]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Command 'stop gracefully' doesn't.
authorTilghman Lesher <tilghman@meg.abyt.es>
Mon, 5 Jul 2010 19:48:42 +0000 (19:48 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Mon, 5 Jul 2010 19:48:42 +0000 (19:48 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@273981 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c
channels/chan_oss.c

index 70adaa48076bebee9b96dbc70365e828d141b1c6..0fc3f70e98917a1be660e570ac5b0e7ca180e8f6 100644 (file)
@@ -172,6 +172,7 @@ static int timingfd = -1;                           /* Timing file descriptor */
 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 @@ static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *cal
        };
 
        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 @@ static void *iax2_process_thread(void *data)
        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 @@ static int __unload_module(void)
        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 @@ static int __unload_module(void)
                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 @@ static int __unload_module(void)
        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++) {
index 27f4eea1290de99bab61a0bdb9eed21e78c1267b..8f55daa5563666ef39f7ffe9b2e7b34a6003dd72 100644 (file)
@@ -50,6 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #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 @@ static void *sound_thread(void *arg)
                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 @@ static void *sound_thread(void *arg)
                }
                /* 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 @@ static void *sound_thread(void *arg)
                        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 @@ static int unload_module(void)
        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;
 }