From: Florian Forster Date: Sun, 4 Mar 2012 10:10:20 +0000 (+0100) Subject: perl plugin: Fix a race condition. X-Git-Tag: collectd-4.10.7~10^2 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=2e48eb524ab27e58d402ef2e88b12d84705cd2b3;p=collectd.git perl plugin: Fix a race condition. This hopefully fixes GitHub issue #9. --- diff --git a/src/perl.c b/src/perl.c index a2f5da29..41e763dc 100644 --- a/src/perl.c +++ b/src/perl.c @@ -1923,6 +1923,11 @@ static int perl_read (void) aTHX = t->interp; } + /* Assert that we're not running as the base thread. Otherwise, we might + * run into concurrency issues with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. */ + assert (aTHX != perl_threads->head->interp); + log_debug ("perl_read: c_ithread: interp = %p (active threads: %i)", aTHX, perl_threads->number_of_threads); return pplugin_call_all (aTHX_ PLUGIN_READ); @@ -1931,6 +1936,7 @@ static int perl_read (void) static int perl_write (const data_set_t *ds, const value_list_t *vl, user_data_t __attribute__((unused)) *user_data) { + int status; dTHX; if (NULL == perl_threads) @@ -1946,9 +1952,20 @@ static int perl_write (const data_set_t *ds, const value_list_t *vl, aTHX = t->interp; } + /* Lock the base thread if this is not called from one of the read threads + * to avoid race conditions with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. */ + if (aTHX == perl_threads->head->interp) + pthread_mutex_lock (&perl_threads->mutex); + log_debug ("perl_write: c_ithread: interp = %p (active threads: %i)", aTHX, perl_threads->number_of_threads); - return pplugin_call_all (aTHX_ PLUGIN_WRITE, ds, vl); + status = pplugin_call_all (aTHX_ PLUGIN_WRITE, ds, vl); + + if (aTHX == perl_threads->head->interp) + pthread_mutex_unlock (&perl_threads->mutex); + + return status; } /* static int perl_write (const data_set_t *, const value_list_t *) */ static void perl_log (int level, const char *msg, @@ -1969,7 +1986,17 @@ static void perl_log (int level, const char *msg, aTHX = t->interp; } + /* Lock the base thread if this is not called from one of the read threads + * to avoid race conditions with c_ithread_create(). See + * https://github.com/collectd/collectd/issues/9 for details. */ + if (aTHX == perl_threads->head->interp) + pthread_mutex_lock (&perl_threads->mutex); + pplugin_call_all (aTHX_ PLUGIN_LOG, level, msg); + + if (aTHX == perl_threads->head->interp) + pthread_mutex_unlock (&perl_threads->mutex); + return; } /* static void perl_log (int, const char *) */