Merge pull request #2618 from ajssmith/amqp1_dev1_branch
[collectd.git] / src / perl.c
index ea53fbf..306d413 100644 (file)
@@ -38,9 +38,7 @@
 
 #undef DONT_POISON_SPRINTF_YET
 
-#if HAVE_STDBOOL_H
 #include <stdbool.h>
-#endif
 
 #include <EXTERN.h>
 #include <perl.h>
@@ -140,8 +138,8 @@ static int perl_flush(cdtime_t timeout, const char *identifier,
 typedef struct c_ithread_s {
   /* the thread's Perl interpreter */
   PerlInterpreter *interp;
-  _Bool running; /* thread is inside Perl interpreter */
-  _Bool shutdown;
+  bool running; /* thread is inside Perl interpreter */
+  bool shutdown;
   pthread_t pthread;
 
   /* double linked list of threads */
@@ -185,17 +183,17 @@ extern char **environ;
  * private variables
  */
 
-static _Bool register_legacy_flush = 1;
+static bool register_legacy_flush = true;
 
 /* if perl_threads != NULL perl_threads->head must
  * point to the "base" thread */
-static c_ithread_list_t *perl_threads = NULL;
+static c_ithread_list_t *perl_threads;
 
 /* the key used to store each pthread's ithread */
 static pthread_key_t perl_thr_key;
 
-static int perl_argc = 0;
-static char **perl_argv = NULL;
+static int perl_argc;
+static char **perl_argv;
 
 static char base_name[DATA_MAX_NAME_LEN] = "";
 
@@ -263,12 +261,6 @@ struct {
                  {"Collectd::NOTIF_WARNING", NOTIF_WARNING},
                  {"Collectd::NOTIF_OKAY", NOTIF_OKAY},
                  {"", 0}};
-
-struct {
-  char name[64];
-  char *var;
-} g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
-
 /*
  * Helper functions for data type conversion.
  */
@@ -339,12 +331,12 @@ static size_t av2value(pTHX_ char *name, AV *array, value_t *value,
 
   if (array_len < ds->ds_num) {
     log_warn("av2value: array does not contain enough elements for type "
-             "\"%s\": got %zu, want %zu",
+             "\"%s\": got %" PRIsz ", want %" PRIsz,
              name, array_len, ds->ds_num);
     return 0;
   } else if (array_len > ds->ds_num) {
     log_warn("av2value: array contains excess elements for type \"%s\": got "
-             "%zu, want %zu",
+             "%" PRIsz ", want %" PRIsz,
              name, array_len, ds->ds_num);
   }
 
@@ -426,8 +418,6 @@ static int hv2value_list(pTHX_ HV *hash, value_list_t *vl) {
 
   if (NULL != (tmp = hv_fetch(hash, "host", 4, 0)))
     sstrncpy(vl->host, SvPV_nolen(*tmp), sizeof(vl->host));
-  else
-    sstrncpy(vl->host, hostname_g, sizeof(vl->host));
 
   if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0)))
     sstrncpy(vl->plugin, SvPV_nolen(*tmp), sizeof(vl->plugin));
@@ -496,7 +486,8 @@ static int av2data_set(pTHX_ AV *array, char *name, data_set_t *ds) {
  *   meta     => [ { name => <name>, value => <value> }, ... ]
  * }
  */
-static int av2notification_meta(pTHX_ AV *array, notification_meta_t **ret_meta) {
+static int av2notification_meta(pTHX_ AV *array,
+                                notification_meta_t **ret_meta) {
   notification_meta_t *tail = NULL;
 
   int len = av_len(array);
@@ -715,10 +706,8 @@ static int value_list2hv(pTHX_ value_list_t *vl, data_set_t *ds, HV *hash) {
 
 static int notification_meta2av(pTHX_ notification_meta_t *meta, AV *array) {
   int meta_num = 0;
-
-  while (meta) {
+  for (notification_meta_t *m = meta; m != NULL; m = m->next) {
     ++meta_num;
-    meta = meta->next;
   }
 
   av_extend(array, meta_num);
@@ -883,12 +872,12 @@ static int oconfig_item2hv(pTHX_ oconfig_item_t *ci, HV *hash) {
 static char *get_module_name(char *buf, size_t buf_len, const char *module) {
   int status = 0;
   if (base_name[0] == '\0')
-    status = ssnprintf(buf, buf_len, "%s", module);
+    status = snprintf(buf, buf_len, "%s", module);
   else
-    status = ssnprintf(buf, buf_len, "%s::%s", base_name, module);
+    status = snprintf(buf, buf_len, "%s::%s", base_name, module);
   if ((status < 0) || ((unsigned int)status >= buf_len))
-    return (NULL);
-  return (buf);
+    return NULL;
+  return buf;
 } /* char *get_module_name */
 
 /*
@@ -992,7 +981,7 @@ static int pplugin_dispatch_notification(pTHX_ HV *notif) {
  * Call perl sub with thread locking flags handled.
  */
 static int call_pv_locked(pTHX_ const char *sub_name) {
-  _Bool old_running;
+  bool old_running;
   int ret;
 
   c_ithread_t *t = (c_ithread_t *)pthread_getspecific(perl_thr_key);
@@ -1000,7 +989,7 @@ static int call_pv_locked(pTHX_ const char *sub_name) {
     return 0;
 
   old_running = t->running;
-  t->running = 1;
+  t->running = true;
 
   if (t->shutdown) {
     t->running = old_running;
@@ -1200,7 +1189,7 @@ static void c_ithread_destroy(c_ithread_t *ithread) {
   /* Mark as running to avoid deadlock:
      c_ithread_destroy -> log_debug -> perl_log()
   */
-  ithread->running = 1;
+  ithread->running = true;
   log_debug("Shutting down Perl interpreter %p...", aTHX);
 
 #if COLLECT_DEBUG
@@ -1286,8 +1275,8 @@ static c_ithread_t *c_ithread_create(PerlInterpreter *base) {
   }
 
   t->pthread = pthread_self();
-  t->running = 0;
-  t->shutdown = 0;
+  t->running = false;
+  t->shutdown = false;
   perl_threads->tail = t;
 
   pthread_setspecific(perl_thr_key, (const void *)t);
@@ -1627,18 +1616,19 @@ static void _plugin_register_generic_userdata(pTHX, int type,
       ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
     }
 
-    if (0 == ret)
+    if (0 == ret) {
       ret = plugin_register_flush(pluginname, perl_flush, &userdata);
+    } else {
+      free(userdata.data);
+    }
   } else {
     ret = -1;
   }
 
   if (0 == ret)
     XSRETURN_YES;
-  else {
-    free(userdata.data);
+  else
     XSRETURN_EMPTY;
-  }
 } /* static void _plugin_register_generic_userdata ( ... ) */
 
 /*
@@ -1652,23 +1642,23 @@ static void _plugin_register_generic_userdata(pTHX, int type,
  */
 
 static XS(Collectd_plugin_register_read) {
-  return _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read");
+  _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read");
 }
 
 static XS(Collectd_plugin_register_write) {
-  return _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write");
+  _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write");
 }
 
 static XS(Collectd_plugin_register_log) {
-  return _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log");
+  _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log");
 }
 
 static XS(Collectd_plugin_register_notification) {
-  return _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification");
+  _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification");
 }
 
 static XS(Collectd_plugin_register_flush) {
-  return _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush");
+  _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush");
 }
 
 typedef int perl_unregister_function_t(const char *name);
@@ -1695,8 +1685,6 @@ static void _plugin_unregister_generic(pTHX, perl_unregister_function_t *unreg,
   unreg(SvPV_nolen(ST(0)));
 
   XSRETURN_EMPTY;
-
-  return;
 } /* static void _plugin_unregister_generic ( ... ) */
 
 /*
@@ -1710,24 +1698,24 @@ static void _plugin_unregister_generic(pTHX, perl_unregister_function_t *unreg,
  */
 
 static XS(Collectd_plugin_unregister_read) {
-  return _plugin_unregister_generic(aTHX, plugin_unregister_read, "read");
+  _plugin_unregister_generic(aTHX, plugin_unregister_read, "read");
 }
 
 static XS(Collectd_plugin_unregister_write) {
-  return _plugin_unregister_generic(aTHX, plugin_unregister_write, "write");
+  _plugin_unregister_generic(aTHX, plugin_unregister_write, "write");
 }
 
 static XS(Collectd_plugin_unregister_log) {
-  return _plugin_unregister_generic(aTHX, plugin_unregister_log, "log");
+  _plugin_unregister_generic(aTHX, plugin_unregister_log, "log");
 }
 
 static XS(Collectd_plugin_unregister_notification) {
-  return _plugin_unregister_generic(aTHX, plugin_unregister_notification,
-                                    "notification");
+  _plugin_unregister_generic(aTHX, plugin_unregister_notification,
+                             "notification");
 }
 
 static XS(Collectd_plugin_unregister_flush) {
-  return _plugin_unregister_generic(aTHX, plugin_unregister_flush, "flush");
+  _plugin_unregister_generic(aTHX, plugin_unregister_flush, "flush");
 }
 
 /*
@@ -2101,7 +2089,7 @@ 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.
-  */
+   */
   assert(aTHX == perl_threads->head->interp);
   pthread_mutex_lock(&perl_threads->mutex);
 
@@ -2192,7 +2180,7 @@ static void perl_log(int level, const char *msg, user_data_t *user_data) {
   /* 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);
@@ -2286,7 +2274,7 @@ static int perl_shutdown(void) {
      * the thread as this will free the memory */
     t = t->prev;
 
-    thr->shutdown = 1;
+    thr->shutdown = true;
     if (thr->running) {
       /* Give some time to thread to exit from Perl interpreter */
       WARNING("perl shutdown: Thread is running inside Perl. Waiting.");
@@ -2351,14 +2339,25 @@ static int g_interval_set(pTHX_ SV *var, MAGIC *mg) {
   return 0;
 } /* static int g_interval_set (pTHX_ SV *, MAGIC *) */
 
-static MGVTBL g_pv_vtbl = {g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL
+static MGVTBL g_pv_vtbl = {g_pv_get,
+                           g_pv_set,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL
 #if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
                            ,
                            NULL
 #endif
 };
-static MGVTBL g_interval_vtbl = {g_interval_get, g_interval_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
@@ -2392,6 +2391,11 @@ static void xs_init(pTHX) {
    * accessing any such variable (this is basically the same as using
    * tie() in Perl) */
   /* global strings */
+  struct {
+    char name[64];
+    char *var;
+  } g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
+
   for (int i = 0; '\0' != g_strings[i].name[0]; ++i) {
     tmp = get_sv(g_strings[i].name, 1);
     sv_magicext(tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl, g_strings[i].var, 0);
@@ -2499,7 +2503,7 @@ static int perl_config_loadplugin(pTHX_ oconfig_item_t *ci) {
 
   if (NULL == get_module_name(module_name, sizeof(module_name), value)) {
     log_err("Invalid module name %s", value);
-    return (1);
+    return 1;
   }
 
   if (0 != init_pi(perl_argc, perl_argv))
@@ -2618,6 +2622,12 @@ static int perl_config_plugin(pTHX_ oconfig_item_t *ci) {
   char *plugin;
   HV *config;
 
+  if (NULL == perl_threads) {
+    log_err("A `Plugin' block was encountered but no plugin was loaded yet. "
+            "Put the appropriate `LoadPlugin' option in front of it.");
+    return -1;
+  }
+
   dSP;
 
   if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
@@ -2719,5 +2729,3 @@ void module_register(void) {
   plugin_register_complex_config("perl", perl_config);
   return;
 } /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */