diff --git a/src/perl.c b/src/perl.c
index e5dc6c7563437c18134aab5fc4dd1c557a51ae36..78e508ae4d1f1bb7c0b9ae5c9ca340b9685e79e6 100644 (file)
--- a/src/perl.c
+++ b/src/perl.c
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 *) */
static int g_interval_get (pTHX_ SV *var, MAGIC *mg)
{
- cdtime_t *interval = (cdtime_t *)mg->mg_ptr;
- double nv;
-
- nv = CDTIME_T_TO_DOUBLE (*interval);
-
- sv_setnv (var, nv);
+ log_warn ("Accessing $interval_g is deprecated (and might not "
+ "give the desired results) - plugin_get_interval() should "
+ "be used instead.");
+ sv_setnv (var, CDTIME_T_TO_DOUBLE (interval_g));
return 0;
} /* static int g_interval_get (pTHX_ SV *, MAGIC *) */
static int g_interval_set (pTHX_ SV *var, MAGIC *mg)
{
- cdtime_t *interval = (cdtime_t *)mg->mg_ptr;
- double nv;
-
- nv = (double)SvNV (var);
-
- *interval = DOUBLE_TO_CDTIME_T (nv);
+ double nv = (double)SvNV (var);
+ log_warn ("Accessing $interval_g is deprecated (and might not "
+ "give the desired results) - plugin_get_interval() should "
+ "be used instead.");
+ interval_g = DOUBLE_TO_CDTIME_T (nv);
return 0;
} /* static int g_interval_set (pTHX_ SV *, MAGIC *) */
tmp = get_sv ("Collectd::interval_g", /* create = */ 1);
sv_magicext (tmp, NULL, /* how = */ PERL_MAGIC_ext,
/* vtbl = */ &g_interval_vtbl,
- /* name = */ (char *) &interval_g, /* namelen = */ 0);
+ /* name = */ NULL, /* namelen = */ 0);
return;
} /* static void xs_init (pTHX) */