[asterisk-commits] tilghman: branch 1.4 r296867 - in /branches/1.4: channels/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Nov 30 18:20:10 CST 2010


Author: tilghman
Date: Tue Nov 30 18:20:05 2010
New Revision: 296867

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=296867
Log:
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.

Modified:
    branches/1.4/channels/chan_iax2.c
    branches/1.4/main/asterisk.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=296867&r1=296866&r2=296867
==============================================================================
--- branches/1.4/channels/chan_iax2.c (original)
+++ branches/1.4/channels/chan_iax2.c Tue Nov 30 18:20:05 2010
@@ -227,7 +227,11 @@
 
 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)
 {
+	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 @@
 	}
 
 	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();

Modified: branches/1.4/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/main/asterisk.c?view=diff&rev=296867&r1=296866&r2=296867
==============================================================================
--- branches/1.4/main/asterisk.c (original)
+++ branches/1.4/main/asterisk.c Tue Nov 30 18:20:05 2010
@@ -262,7 +262,16 @@
 	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 @@
 	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);




More information about the asterisk-commits mailing list