From: Tilghman Lesher Date: Wed, 1 Dec 2010 00:20:05 +0000 (+0000) Subject: Get rid of the annoying startup and shutdown errors on OS X. X-Git-Tag: 1.4.39-rc1~3^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=196032208f53bf18cbd751e6ba276ec0f08d6394;p=thirdparty%2Fasterisk.git Get rid of the annoying startup and shutdown errors on OS X. This mainly deals with the problem of constructors on platforms where an explicit constructor order cannot be specified (any system with gcc 4.2 or less). However, this is only a problem on those systems where we need to initialize mutexes with a constructor, because we have other code that also relies upon constructors, and we cannot specify that mutexes are initialized first (and destroyed last). There are two approaches to dealing with this issue, related to whether the code exists in the core Asterisk binary or in a separate code module. In the core case, constructors are run immediately upon load, and the file_versions list mutex needs to be already initialized, as it is referenced in the first constructor within each core source file. In this case, we use pthread_once to ensure that the mutex is initialized immediately before it is used for the first time. The only caveat is that the mutex is not ever destroyed, but because this is the core, it makes no real difference; the only time when destruction is safe would be just prior to process destruction, which takes care of that anyway. And due to using pthread_once, the mutex will never be reinitialized, which means only one structure has leaked at the end of the process. Hence, it is not a problematic leak. The second approach is to use the load_module and unload_module routines, which, for obvious reasons, exist only in loadable modules. In this second case, we don't have a problem with the constructors, but only with destructor order, because mutexes can be destroyed before their final usage is employed. However, we need the mutexes to still be destroyed, in certain scenarios: if the module is unloaded prior to the process ending, it should be clean, with no allocations by the module hanging around after that point in time. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@296867 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index d55e8f7800..b81a511240 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -227,7 +227,11 @@ static struct ast_flags globalflags = { 0 }; static pthread_t netthreadid = AST_PTHREADT_NULL; static pthread_t schedthreadid = AST_PTHREADT_NULL; +#ifndef AST_MUTEX_INIT_W_CONSTRUCTORS AST_MUTEX_DEFINE_STATIC(sched_lock); +#else +static ast_mutex_t sched_lock; +#endif static ast_cond_t sched_cond; enum { @@ -12634,8 +12638,13 @@ static int __unload_module(void) static int unload_module(void) { + int res; ast_custom_function_unregister(&iaxpeer_function); - return __unload_module(); + res = __unload_module(); +#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS + ast_mutex_destroy(&sched_lock); +#endif + return res; } static int peer_set_sock_cb(void *obj, void *arg, int flags) @@ -12770,6 +12779,9 @@ static int load_module(void) } ast_cond_init(&sched_cond, NULL); +#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS + ast_mutex_init(&sched_lock); +#endif io = io_context_create(); sched = sched_context_create(); diff --git a/main/asterisk.c b/main/asterisk.c index 1079b215a0..6e69aacc5f 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -262,7 +262,16 @@ struct file_version { char *version; }; +#ifndef AST_MUTEX_INIT_W_CONSTRUCTORS static AST_LIST_HEAD_STATIC(file_versions, file_version); +#else +static AST_LIST_HEAD(file_versions, file_version) file_versions; +static pthread_once_t file_versions_once = PTHREAD_ONCE_INIT; +static void file_versions_init(void) +{ + AST_LIST_HEAD_INIT(&file_versions); +} +#endif void ast_register_file_version(const char *file, const char *version) { @@ -280,6 +289,9 @@ void ast_register_file_version(const char *file, const char *version) new->file = file; new->version = (char *) new + sizeof(*new); memcpy(new->version, work, version_length); +#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS + pthread_once(&file_versions_once, file_versions_init); +#endif AST_LIST_LOCK(&file_versions); AST_LIST_INSERT_HEAD(&file_versions, new, list); AST_LIST_UNLOCK(&file_versions);