X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fperl.c;h=a2568da2621fb8f7ea79445f199f7171822f6abb;hb=92999cbffb2f3aff8421938216864ccd901d908a;hp=116c34f363d535b2d644ee73add242804be3465d;hpb=edd0e2639a241167e213ec301bfc71c7d291ee61;p=collectd.git diff --git a/src/perl.c b/src/perl.c index 116c34f3..a2568da2 100644 --- a/src/perl.c +++ b/src/perl.c @@ -235,15 +235,6 @@ struct { { "", NULL } }; -struct { - char name[64]; - int *var; -} g_integers[] = -{ - { "Collectd::interval_g", &interval_g }, - { "", NULL } -}; - /* * Helper functions for data type conversion. */ @@ -403,7 +394,10 @@ static int hv2value_list (pTHX_ HV *hash, value_list_t *vl) } if (NULL != (tmp = hv_fetch (hash, "interval", 8, 0))) - vl->interval = SvIV (*tmp); + { + double t = SvNV (*tmp); + vl->interval = DOUBLE_TO_CDTIME_T (t); + } if (NULL != (tmp = hv_fetch (hash, "host", 4, 0))) sstrncpy (vl->host, SvPV_nolen (*tmp), sizeof (vl->host)); @@ -684,8 +678,11 @@ static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash) return -1; } - if (NULL == hv_store (hash, "interval", 8, newSViv (vl->interval), 0)) - return -1; + { + double t = CDTIME_T_TO_DOUBLE (vl->interval); + if (NULL == hv_store (hash, "interval", 8, newSVnv (t), 0)) + return -1; + } if ('\0' != vl->host[0]) if (NULL == hv_store (hash, "host", 4, newSVpv (vl->host, 0), 0)) @@ -1932,6 +1929,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); @@ -1940,6 +1942,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) @@ -1955,9 +1958,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, @@ -1978,7 +1992,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 *) */ @@ -2104,19 +2128,27 @@ static int g_pv_set (pTHX_ SV *var, MAGIC *mg) return 0; } /* static int g_pv_set (pTHX_ SV *, MAGIC *) */ -static int g_iv_get (pTHX_ SV *var, MAGIC *mg) +static int g_interval_get (pTHX_ SV *var, MAGIC *mg) { - int *iv = (int *)mg->mg_ptr; - sv_setiv (var, *iv); + cdtime_t *interval = (cdtime_t *)mg->mg_ptr; + double nv; + + nv = CDTIME_T_TO_DOUBLE (*interval); + + sv_setnv (var, nv); return 0; -} /* static int g_iv_get (pTHX_ SV *, MAGIC *) */ +} /* static int g_interval_get (pTHX_ SV *, MAGIC *) */ -static int g_iv_set (pTHX_ SV *var, MAGIC *mg) +static int g_interval_set (pTHX_ SV *var, MAGIC *mg) { - int *iv = (int *)mg->mg_ptr; - *iv = (int)SvIV (var); + cdtime_t *interval = (cdtime_t *)mg->mg_ptr; + double nv; + + nv = (double)SvNV (var); + + *interval = DOUBLE_TO_CDTIME_T (nv); return 0; -} /* static int g_iv_set (pTHX_ SV *, MAGIC *) */ +} /* static int g_interval_set (pTHX_ SV *, MAGIC *) */ static MGVTBL g_pv_vtbl = { g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL @@ -2124,8 +2156,8 @@ static MGVTBL g_pv_vtbl = { , NULL #endif }; -static MGVTBL g_iv_vtbl = { - g_iv_get, g_iv_set, NULL, NULL, NULL, NULL, NULL +static MGVTBL g_interval_vtbl = { + g_interval_get, g_interval_set, NULL, NULL, NULL, NULL, NULL #if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL , NULL #endif @@ -2167,12 +2199,11 @@ static void xs_init (pTHX) g_strings[i].var, 0); } - /* global integers */ - for (i = 0; '\0' != g_integers[i].name[0]; ++i) { - tmp = get_sv (g_integers[i].name, 1); - sv_magicext (tmp, NULL, PERL_MAGIC_ext, &g_iv_vtbl, - (char *)g_integers[i].var, 0); - } + 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); + return; } /* static void xs_init (pTHX) */