Code

perl plugin: Switched to PTHREAD_MUTEX_RECURSIVE locking
authorPavel Rochnyack <pavel2000@ngs.ru>
Mon, 30 May 2016 05:31:44 +0000 (11:31 +0600)
committerSebastian Harl <sh@tokkee.org>
Mon, 30 May 2016 19:51:36 +0000 (21:51 +0200)
src/perl.c

index 7ab45d8d758dd7841554ff22fe3d2cd3fe563b7e..d253d09d0815fafc21ad77b5565d921d5b6214fc 100644 (file)
@@ -131,6 +131,7 @@ typedef struct {
 #endif /* COLLECT_DEBUG */
 
        pthread_mutex_t mutex;
+       pthread_mutexattr_t mutexattr;
 } c_ithread_list_t;
 
 /* name / user_data for Perl matches / targets */
@@ -1942,7 +1943,6 @@ static int perl_init (void)
        /* Lock the base thread to avoid race conditions with c_ithread_create().
         * See https://github.com/collectd/collectd/issues/9 and
         *     https://github.com/collectd/collectd/issues/1706 for details.
-        * Locking here requires additional check in perl_log() to avoid deadlock.
        */
        assert (aTHX == perl_threads->head->interp);
        pthread_mutex_lock (&perl_threads->mutex);
@@ -2020,7 +2020,6 @@ static void perl_log (int level, const char *msg,
                user_data_t __attribute__((unused)) *user_data)
 {
        dTHX;
-       int locked = 0;
 
        if (NULL == perl_threads)
                return;
@@ -2038,18 +2037,14 @@ static void perl_log (int level, const char *msg,
        /* 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.
-        * Additionally check, if we are called from perl interpreter.
-        * Maybe PTHREAD_MUTEX_RECURSIVE mutex type will be more appropriate?
        */
 
-       if (aTHX == perl_threads->head->interp && !perl_threads->head->running) {
+       if (aTHX == perl_threads->head->interp)
                pthread_mutex_lock (&perl_threads->mutex);
-               locked = 1;
-       }
 
        pplugin_call_all (aTHX_ PLUGIN_LOG, level, msg);
 
-       if (locked)
+       if (aTHX == perl_threads->head->interp)
                pthread_mutex_unlock (&perl_threads->mutex);
 
        return;
@@ -2163,6 +2158,7 @@ static int perl_shutdown (void)
 
        pthread_mutex_unlock (&perl_threads->mutex);
        pthread_mutex_destroy (&perl_threads->mutex);
+       pthread_mutexattr_destroy (&perl_threads->mutexattr);
 
        sfree (perl_threads);
 
@@ -2302,7 +2298,9 @@ static int init_pi (int argc, char **argv)
        perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
        memset (perl_threads, 0, sizeof (c_ithread_list_t));
 
-       pthread_mutex_init (&perl_threads->mutex, NULL);
+       pthread_mutexattr_init(&perl_threads->mutexattr);
+       pthread_mutexattr_settype(&perl_threads->mutexattr, PTHREAD_MUTEX_RECURSIVE);
+       pthread_mutex_init (&perl_threads->mutex, &perl_threads->mutexattr);
        /* locking the mutex should not be necessary at this point
         * but let's just do it for the sake of completeness */
        pthread_mutex_lock (&perl_threads->mutex);