if (NULL == (tmp = hv_fetch (hash, "value", 5, 0))) {
log_warn ("av2notification_meta: Skipping invalid "
"meta information.");
- free ((*m)->name);
free (*m);
continue;
}
/* the ithread no longer exists */
if (NULL == t)
+ {
+ pthread_mutex_unlock (&perl_threads->mutex);
return;
+ }
c_ithread_destroy (ithread);
values = ST (/* stack index = */ 0);
+ if (NULL == values)
+ XSRETURN_EMPTY;
+
/* Make sure the argument is a hash reference. */
if (! (SvROK (values) && (SVt_PVHV == SvTYPE (SvRV (values))))) {
log_err ("Collectd::plugin_dispatch_values: Invalid values.");
XSRETURN_EMPTY;
}
- if (NULL == values)
- XSRETURN_EMPTY;
-
ret = pplugin_dispatch_values (aTHX_ (HV *)SvRV (values));
if (0 == ret)
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);
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)
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,
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 *) */
return 0;
if (NULL == aTHX) {
- c_ithread_t *t = NULL;
+ t = NULL;
pthread_mutex_lock (&perl_threads->mutex);
t = c_ithread_create (perl_threads->head->interp);
int current_status = 0;
if (NULL != perl_threads)
- aTHX = PERL_GET_CONTEXT;
+ {
+ if ((aTHX = PERL_GET_CONTEXT) == NULL)
+ return -1;
+ }
if (0 == strcasecmp (c->key, "LoadPlugin"))
current_status = perl_config_loadplugin (aTHX_ c);