[svn-commits] mjordan: branch mjordan/1.8_instrumented r369697 - in /team/mjordan/1.8_instr...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jul 6 08:22:43 CDT 2012


Author: mjordan
Date: Fri Jul  6 08:22:41 2012
New Revision: 369697

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=369697
Log:
Update with latest asterisk.c/channel.c updates

Modified:
    team/mjordan/1.8_instrumented/include/asterisk/channel.h
    team/mjordan/1.8_instrumented/main/asterisk.c
    team/mjordan/1.8_instrumented/main/channel.c

Modified: team/mjordan/1.8_instrumented/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/1.8_instrumented/include/asterisk/channel.h?view=diff&rev=369697&r1=369696&r2=369697
==============================================================================
--- team/mjordan/1.8_instrumented/include/asterisk/channel.h (original)
+++ team/mjordan/1.8_instrumented/include/asterisk/channel.h Fri Jul  6 08:22:41 2012
@@ -360,7 +360,7 @@
  * PSTN gateway).
  *
  * \todo Implement settings for transliteration between UTF8 Caller ID names in
- *       to ASCII Caller ID's (DAHDI). Östen Åsklund might be transliterated into
+ *       to ASCII Caller ID's (DAHDI). �sten �sklund might be transliterated into
  *       Osten Asklund or Oesten Aasklund depending upon language and person...
  *       We need automatic routines for incoming calls and static settings for
  *       our own accounts.
@@ -2127,6 +2127,9 @@
 /*! \return number of active/allocated channels */
 int ast_active_channels(void);
 
+/*! \return the number of channels not yet destroyed */
+int ast_undestroyed_channels(void);
+
 /*! \return non-zero if Asterisk is being shut down */
 int ast_shutting_down(void);
 

Modified: team/mjordan/1.8_instrumented/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/1.8_instrumented/main/asterisk.c?view=diff&rev=369697&r1=369696&r2=369697
==============================================================================
--- team/mjordan/1.8_instrumented/main/asterisk.c (original)
+++ team/mjordan/1.8_instrumented/main/asterisk.c Fri Jul  6 08:22:41 2012
@@ -190,7 +190,6 @@
 /* XXX tmpdir is a subdir of the spool directory, and no way to remap it */
 char record_cache_dir[AST_CACHE_DIR_LEN] = DEFAULT_TMP_DIR;
 
-AST_MUTEX_DEFINE_STATIC(listener_lock);
 static int ast_socket = -1;		/*!< UNIX Socket for allowing remote control */
 static int ast_consock = -1;		/*!< UNIX Socket for controlling another asterisk */
 pid_t ast_mainpid;
@@ -1103,6 +1102,11 @@
 void ast_console_toggle_loglevel(int fd, int level, int state)
 {
 	int x;
+
+	if (level >= NUMLOGLEVELS) {
+		level = NUMLOGLEVELS - 1;
+	}
+
 	for (x = 0;x < AST_MAX_CONNECTS; x++) {
 		if (fd == consoles[x].fd) {
 			/*
@@ -1258,14 +1262,17 @@
 {
 	struct console *con = vconsole;
 	char hostname[MAXHOSTNAMELEN] = "";
-	char tmp[512];
+	char inbuf[512];
+	char outbuf[512];
+	const char * const end_buf = inbuf + sizeof(inbuf);
+	char *start_read = inbuf;
 	int res;
 	struct pollfd fds[2];
-	
+
 	if (gethostname(hostname, sizeof(hostname)-1))
 		ast_copy_string(hostname, "<Unknown>", sizeof(hostname));
-	snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
-	fdprint(con->fd, tmp);
+	snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version());
+	fdprint(con->fd, outbuf);
 	for (;;) {
 		fds[0].fd = con->fd;
 		fds[0].events = POLLIN;
@@ -1281,24 +1288,49 @@
 			continue;
 		}
 		if (fds[0].revents) {
-			res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con);
-			if (res < 1) {
+			int cmds_read, bytes_read;
+			if ((bytes_read = read_credentials(con->fd, start_read, end_buf - start_read, con)) < 1) {
 				break;
 			}
-			tmp[res] = 0;
-			if (strncmp(tmp, "cli quit after ", 15) == 0) {
-				ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15);
+			/* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
+			if (strncmp(inbuf, "cli quit after ", 15) == 0) {
+				ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read - 15, inbuf + 15);
 				break;
 			}
-			ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp);
+			/* ast_cli_command_multiple_full will only process individual commands terminated by a
+			 * NULL and not trailing partial commands. */
+			if (!(cmds_read = ast_cli_command_multiple_full(con->uid, con->gid, con->fd, bytes_read + start_read - inbuf, inbuf))) {
+				/* No commands were read. We either have a short read on the first command
+				 * with space left, or a command that is too long */
+				if (start_read + bytes_read < end_buf) {
+					start_read += bytes_read;
+				} else {
+					ast_log(LOG_ERROR, "Command too long! Skipping\n");
+					start_read = inbuf;
+				}
+				continue;
+			}
+			if (start_read[bytes_read - 1] == '\0') {
+				/* The read ended on a command boundary, start reading again at the head of inbuf */
+				start_read = inbuf;
+				continue;
+			}
+			/* If we get this far, we have left over characters that have not been processed.
+			 * Advance to the character after the last command read by ast_cli_command_multiple_full.
+			 * We are guaranteed to have at least cmds_read NULLs */
+			while (cmds_read-- && (start_read = strchr(start_read, '\0'))) {
+				start_read++;
+			}
+			memmove(inbuf, start_read, end_buf - start_read);
+			start_read = end_buf - start_read + inbuf;
 		}
 		if (fds[1].revents) {
-			res = read_credentials(con->p[0], tmp, sizeof(tmp), con);
+			res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con);
 			if (res < 1) {
 				ast_log(LOG_ERROR, "read returned %d\n", res);
 				break;
 			}
-			res = write(con->fd, tmp, res);
+			res = write(con->fd, outbuf, res);
 			if (res < 1)
 				break;
 		}
@@ -1323,14 +1355,10 @@
 	int flags;
 	struct pollfd fds[1];
 	for (;;) {
-		ast_mutex_lock(&listener_lock);
-		if (ast_socket < 0) {
-			ast_mutex_unlock(&listener_lock);
+		if (ast_socket < 0)
 			return NULL;
-		}
 		fds[0].fd = ast_socket;
 		fds[0].events = POLLIN;
-		ast_mutex_unlock(&listener_lock);
 		s = ast_poll(fds, 1, -1);
 		pthread_testcancel();
 		if (s < 0) {
@@ -1341,7 +1369,6 @@
 		}
 		len = sizeof(sunaddr);
 		s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len);
-		ast_mutex_unlock(&listener_lock);
 		if (s < 0) {
 			if (errno != EINTR)
 				ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno));
@@ -1434,7 +1461,11 @@
 		ast_log(LOG_WARNING, "Unable to register network verboser?\n");
 	}
 
-	ast_pthread_create_background(&lthread, NULL, listener, NULL);
+	if (ast_pthread_create_background(&lthread, NULL, listener, NULL)) {
+		ast_log(LOG_WARNING, "Unable to create listener thread.\n");
+		close(ast_socket);
+		return -1;
+	}
 
 	if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) {
 		struct passwd *pw;
@@ -1473,6 +1504,7 @@
 	int res;
 	ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0);
 	if (ast_consock < 0) {
+		ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
 		printf("Unable to create socket: %s\n", strerror(errno));
 		printf("%s[%d]\n", __FILE__, __LINE__);
 		return 0;
@@ -1673,7 +1705,7 @@
 		for (;;) {
 			time(&e);
 			/* Wait up to 15 seconds for all channels to go away */
-			if ((e - s) > 15 || !ast_active_channels() || shuttingdown != niceness) {
+			if ((e - s) > 15 || !ast_undestroyed_channels() || shuttingdown != niceness) {
 				break;
 			}
 			/* Sleep 1/10 of a second */
@@ -1687,7 +1719,7 @@
 			ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt");
 		}
 		for (;;) {
-			if (!ast_active_channels() || shuttingdown != niceness) {
+			if (!ast_undestroyed_channels() || shuttingdown != niceness) {
 				break;
 			}
 			sleep(1);
@@ -1748,12 +1780,10 @@
 	ast_debug(1, "Asterisk ending (%d).\n", num);
 	manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False");
 	if (ast_socket > -1) {
-		ast_mutex_lock(&listener_lock);
+		pthread_cancel(lthread);
 		close(ast_socket);
 		ast_socket = -1;
 		unlink(ast_config_AST_SOCKET);
-		ast_mutex_unlock(&listener_lock);
-		pthread_cancel(lthread);
 	}
 	if (ast_consock > -1)
 		close(ast_consock);
@@ -2298,6 +2328,7 @@
 						quit_handler(0, SHUTDOWN_FAST, 0);
 					}
 				}
+				continue;
 			}
 
 			buf[res] = '\0';
@@ -2593,7 +2624,9 @@
 	if (ast_opt_remote) {
 		snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
 		fdsend(ast_consock, buf);
-		res = read(ast_consock, buf, sizeof(buf) - 1);
+		if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
+			return (char*)(CC_ERROR);
+		}
 		buf[res] = '\0';
 		nummatches = atoi(buf);
 
@@ -3238,9 +3271,8 @@
 	sleep(120);
 
 	for (;;) {
-		stat(canary_filename, &canary_stat);
 		now = ast_tvnow();
-		if (now.tv_sec > canary_stat.st_mtime + 60) {
+		if (stat(canary_filename, &canary_stat) || now.tv_sec > canary_stat.st_mtime + 60) {
 			ast_log(LOG_WARNING,
 				"The canary is no more.  He has ceased to be!  "
 				"He's expired and gone to meet his maker!  "
@@ -3583,6 +3615,7 @@
 		if (errno == EEXIST) {
 			rundir_exists = 1;
 		} else {
+			ast_log(LOG_WARNING, "Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
 			printf("%s[%d]\n", __FILE__, __LINE__);
 			printf("Unable to create socket file directory.  Remote consoles will not be able to connect! (%s)\n", strerror(x));
 		}
@@ -3750,12 +3783,14 @@
 			quit_handler(0, SHUTDOWN_FAST, 0);
 			exit(0);
 		} else {
+			ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
 			printf("Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET);
 			printf("%s", term_quit());
 			printf("%s[%d]\n", __FILE__, __LINE__);
 			exit(1);
 		}
 	} else if (ast_opt_remote || ast_opt_exec) {
+		ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
 		printf("Unable to connect to remote asterisk (does %s exist?)\n", ast_config_AST_SOCKET);
 		printf("%s", term_quit());
 		printf("%s[%d]\n", __FILE__, __LINE__);

Modified: team/mjordan/1.8_instrumented/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/1.8_instrumented/main/channel.c?view=diff&rev=369697&r1=369696&r2=369697
==============================================================================
--- team/mjordan/1.8_instrumented/main/channel.c (original)
+++ team/mjordan/1.8_instrumented/main/channel.c Fri Jul  6 08:22:41 2012
@@ -93,6 +93,7 @@
 static int shutting_down;
 
 static int uniqueint;
+static int chancount;
 
 unsigned long global_fin, global_fout;
 
@@ -980,6 +981,12 @@
 	return -1;
 }
 
+int ast_undestroyed_channels(void)
+{
+	return ast_atomic_fetchadd_int(&chancount, 0);
+}
+
+
 /*! \brief Gives the string form of a given channel state.
 	\note This function is not reentrant.
  */
@@ -1295,6 +1302,7 @@
 	ast_cdr_init(tmp->cdr, tmp);
 	ast_cdr_start(tmp->cdr);
 
+	ast_atomic_fetchadd_int(&chancount, +1);
 	ast_cel_report_event(tmp, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
 
 	headp = &tmp->varshead;
@@ -2479,6 +2487,7 @@
 		 */
 		ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
 	}
+	ast_atomic_fetchadd_int(&chancount, -1);
 }
 
 /*! \brief Free a dummy channel structure */




More information about the svn-commits mailing list