[asterisk-commits] tilghman: branch 1.4 r273981 - in /branches/1.4/channels: chan_iax2.c chan_oss.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jul 5 14:48:45 CDT 2010


Author: tilghman
Date: Mon Jul  5 14:48:42 2010
New Revision: 273981

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=273981
Log:
Command 'stop gracefully' doesn't.

Modified:
    branches/1.4/channels/chan_iax2.c
    branches/1.4/channels/chan_oss.c

Modified: branches/1.4/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/channels/chan_iax2.c?view=diff&rev=273981&r1=273980&r2=273981
==============================================================================
--- branches/1.4/channels/chan_iax2.c (original)
+++ branches/1.4/channels/chan_iax2.c Mon Jul  5 14:48:42 2010
@@ -172,6 +172,7 @@
 static struct ast_netsock_list *netsock;
 static struct ast_netsock_list *outsock;		/*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
 static int defaultsockfd = -1;
+static int unloading;
 
 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
 
@@ -2324,6 +2325,12 @@
 	};
 
 	if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
+		if (unloading) {
+			peercnt_remove_cb(peercnt);
+			replace_callno(callno_entry);
+			return;
+		}
+
 		/* refcount is incremented with ao2_find.  keep that ref for the scheduler */
 		if (option_debug) {
 			ast_log(LOG_DEBUG, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
@@ -9976,12 +9983,14 @@
 	ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
 	pthread_cleanup_push(iax2_process_thread_cleanup, data);
 	for(;;) {
+		pthread_testcancel();
+
 		/* Wait for something to signal us to be awake */
 		ast_mutex_lock(&thread->lock);
 
 		/* Flag that we're ready to accept signals */
 		thread->ready_for_signal = 1;
-		
+
 		/* Put into idle list if applicable */
 		if (put_into_idle)
 			insert_idle_thread(thread);
@@ -12491,8 +12500,10 @@
 	struct iax2_thread *thread = NULL;
 	int x;
 
+	unloading = 1;
+
 	/* Make sure threads do not hold shared resources when they are canceled */
-	
+
 	/* Grab the sched lock resource to keep it away from threads about to die */
 	/* Cancel the network thread, close the net socket */
 	if (netthreadid != AST_PTHREADT_NULL) {
@@ -12505,13 +12516,13 @@
 		pthread_join(netthreadid, NULL);
 	}
 	if (schedthreadid != AST_PTHREADT_NULL) {
-		ast_mutex_lock(&sched_lock);	
+		ast_mutex_lock(&sched_lock);
 		pthread_cancel(schedthreadid);
 		ast_cond_signal(&sched_cond);
-		ast_mutex_unlock(&sched_lock);	
+		ast_mutex_unlock(&sched_lock);
 		pthread_join(schedthreadid, NULL);
 	}
-	
+
 	/* Call for all threads to halt */
 	AST_LIST_LOCK(&idle_list);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
@@ -12530,19 +12541,20 @@
 	AST_LIST_UNLOCK(&active_list);
 
 	AST_LIST_LOCK(&dynamic_list);
-        AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
 		AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
 		pthread_cancel(thread->threadid);
-        }
+	}
 	AST_LIST_TRAVERSE_SAFE_END
-        AST_LIST_UNLOCK(&dynamic_list);
+	AST_LIST_UNLOCK(&dynamic_list);
 
 	AST_LIST_HEAD_DESTROY(&iaxq.queue);
 
 	/* Wait for threads to exit */
-	while(0 < iaxactivethreadcount)
+	while (0 < iaxactivethreadcount) {
 		usleep(10000);
-	
+	}
+
 	ast_netsock_release(netsock);
 	ast_netsock_release(outsock);
 	for (x = 0; x < ARRAY_LEN(iaxs); x++) {

Modified: branches/1.4/channels/chan_oss.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/channels/chan_oss.c?view=diff&rev=273981&r1=273980&r2=273981
==============================================================================
--- branches/1.4/channels/chan_oss.c (original)
+++ branches/1.4/channels/chan_oss.c Mon Jul  5 14:48:42 2010
@@ -50,6 +50,7 @@
 #include <sys/time.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <signal.h>      /* for pthread_kill(3) */
 
 #ifdef __linux
 #include <linux/soundcard.h>
@@ -606,6 +607,8 @@
 		fd_set rfds, wfds;
 		int maxfd, res;
 
+		pthread_testcancel();
+
 		FD_ZERO(&rfds);
 		FD_ZERO(&wfds);
 		FD_SET(o->sndcmd[0], &rfds);
@@ -626,6 +629,7 @@
 		}
 		/* ast_select emulates linux behaviour in terms of timeout handling */
 		res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
+		pthread_testcancel();
 		if (res < 1) {
 			ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
 			sleep(1);
@@ -636,6 +640,7 @@
 			int i, what = -1;
 
 			if (read(o->sndcmd[0], &what, sizeof(what)) != sizeof(what)) {
+				pthread_testcancel();
 				ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
 				continue;
 			}
@@ -1880,17 +1885,28 @@
 	ast_cli_unregister_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
 
 	for (o = oss_default.next; o; o = o->next) {
+		if (o->owner) {
+			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
+			/* Give the channel a chance to go away */
+			sched_yield();
+		}
+		if (o->owner) {
+			return -1;
+		}
+		oss_default.next = o->next;
+		if (o->sthread > 0) {
+			pthread_cancel(o->sthread);
+			pthread_kill(o->sthread, SIGURG);
+			pthread_join(o->sthread, NULL);
+		}
 		close(o->sounddev);
 		if (o->sndcmd[0] > 0) {
 			close(o->sndcmd[0]);
 			close(o->sndcmd[1]);
 		}
-		if (o->owner)
-			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
-		if (o->owner)
-			return -1;
-		/* XXX what about the thread ? */
-		/* XXX what about the memory allocated ? */
+		if (o->sthread > 0) {
+			free(o);
+		}
 	}
 	return 0;
 }




More information about the asterisk-commits mailing list