Index: channels/chan_skinny.c =================================================================== --- channels/chan_skinny.c (revision 76979) +++ channels/chan_skinny.c (working copy) @@ -799,7 +799,7 @@ struct ast_hostent ahp; struct hostent *hp; static int skinnysock = -1; -static pthread_t accept_t; +static pthread_t accept_t = AST_PTHREADT_NULL; static char context[AST_MAX_CONTEXT] = "default"; static char language[MAX_LANGUAGE] = ""; static char mohinterpret[MAX_MUSICCLASS] = "default"; @@ -4757,6 +4757,7 @@ ast_verbose(VERBOSE_PREFIX_3 "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr)); for (;;) { + pthread_testcancel(); res = get_input(s); if (res < 0) { break; @@ -4795,6 +4796,7 @@ pthread_t tcp_thread; for (;;) { + pthread_testcancel(); sinlen = sizeof(sin); as = accept(skinnysock, (struct sockaddr *)&sin, &sinlen); if (as < 0) { @@ -4818,13 +4820,18 @@ sessions = s; ast_mutex_unlock(&sessionlock); - if (ast_pthread_create_detached(&tcp_thread, NULL, skinny_session, s)) { - destroy_session(s); + if (accept_t && (accept_t == AST_PTHREADT_STOP)) + break; + + if (ast_pthread_create_detached(&tcp_thread, NULL, skinny_session, s)) { + destroy_session(s); } + s->t = tcp_thread; } if (skinnydebug) ast_verbose("killing accept thread\n"); close(as); + return 0; } @@ -5108,7 +5115,7 @@ if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Skinny listening on %s:%d\n", ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); - ast_pthread_create_background(&accept_t,NULL, accept_thread, NULL); + ast_pthread_create_background(&accept_t, NULL, accept_thread, NULL); } } ast_mutex_unlock(&netlock); @@ -5156,20 +5163,6 @@ ast_mutex_unlock(&devicelock); } -#if 0 -/* - * XXX This never worked properly anyways. - * Let's get rid of it, until we can fix it. - */ -static int reload(void) -{ - delete_devices(); - reload_config(); - restart_monitor(); - return 0; -} -#endif - static int load_module(void) { int res = 0; @@ -5212,6 +5205,16 @@ struct skinny_line *l; struct skinny_subchannel *sub; + + ast_mutex_lock(&netlock); + if (accept_t && (accept_t != AST_PTHREADT_STOP)) { + pthread_cancel(accept_t); + pthread_kill(accept_t, SIGURG); + pthread_join(accept_t, NULL); + } + accept_t = AST_PTHREADT_STOP; + ast_mutex_unlock(&netlock); + ast_mutex_lock(&sessionlock); /* Destroy all the interfaces and free their memory */ s = sessions; @@ -5234,6 +5237,11 @@ } if (slast->fd > -1) close(slast->fd); + if (slast->t){ + pthread_cancel(slast->t); + pthread_kill(slast->t, SIGURG); + pthread_join(slast->t, NULL); + } ast_mutex_destroy(&slast->lock); ast_free(slast); } @@ -5251,27 +5259,35 @@ monitor_thread = AST_PTHREADT_STOP; ast_mutex_unlock(&monlock); - ast_mutex_lock(&netlock); - if (accept_t && (accept_t != AST_PTHREADT_STOP)) { - pthread_cancel(accept_t); - pthread_kill(accept_t, SIGURG); - pthread_join(accept_t, NULL); - } - accept_t = AST_PTHREADT_STOP; - ast_mutex_unlock(&netlock); ast_rtp_proto_unregister(&skinny_rtp); ast_channel_unregister(&skinny_tech); ast_cli_unregister_multiple(cli_skinny, sizeof(cli_skinny) / sizeof(struct ast_cli_entry)); close(skinnysock); + + if (io) + io_context_destroy(io); + if (sched) sched_context_destroy(sched); return 0; } +/* + * XXX This never worked properly anyways. + * Let's get rid of it, until we can fix it. + */ +static int reload_module(void) +{ + unload_module(); + load_module(); + return 0; +} + AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Skinny Client Control Protocol (Skinny)", .load = load_module, .unload = unload_module, + .reload = reload_module, );