aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2010-12-01 00:20:05 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2010-12-01 00:20:05 +0000
commit4ede17efdd8bf2491247ba04edda4a55853b8e3a (patch)
tree1afc18475958805a26bab6dbd741e7d323746e4c
parent907bff26a0ee5e2a6f6b8937c31138b39beea164 (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.4@296867 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_iax2.c14
-rw-r--r--main/asterisk.c12
2 files changed, 25 insertions, 1 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index d55e8f780..b81a51124 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 1079b215a..6e69aacc5 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);