src/plugin.c: Add a user_data_t pointer to log callbacks.
[collectd.git] / src / plugin.c
index ee39bd3..41a816f 100644 (file)
@@ -58,6 +58,27 @@ struct read_func_s
 };
 typedef struct read_func_s read_func_t;
 
+struct write_func_s
+{
+       plugin_write_cb callback;
+       user_data_t udata;
+};
+typedef struct write_func_s write_func_t;
+
+struct flush_func_s
+{
+       plugin_flush_cb callback;
+       user_data_t udata;
+};
+typedef struct flush_func_s flush_func_t;
+
+struct log_func_s
+{
+       plugin_log_cb callback;
+       user_data_t udata;
+};
+typedef struct log_func_s log_func_t;
+
 /*
  * Private variables
  */
@@ -270,7 +291,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
        return ((void *) 0);
 } /* void *plugin_read_thread */
 
-static void start_threads (int num)
+static void start_read_threads (int num)
 {
        int i;
 
@@ -280,7 +301,7 @@ static void start_threads (int num)
        read_threads = (pthread_t *) calloc (num, sizeof (pthread_t));
        if (read_threads == NULL)
        {
-               ERROR ("plugin: start_threads: calloc failed.");
+               ERROR ("plugin: start_read_threads: calloc failed.");
                return;
        }
 
@@ -294,13 +315,13 @@ static void start_threads (int num)
                }
                else
                {
-                       ERROR ("plugin: start_threads: pthread_create failed.");
+                       ERROR ("plugin: start_read_threads: pthread_create failed.");
                        return;
                }
        } /* for (i) */
-} /* void start_threads */
+} /* void start_read_threads */
 
-static void stop_threads (void)
+static void stop_read_threads (void)
 {
        int i;
 
@@ -309,7 +330,7 @@ static void stop_threads (void)
 
        pthread_mutex_lock (&read_lock);
        read_loop = 0;
-       DEBUG ("plugin: stop_threads: Signalling `read_cond'");
+       DEBUG ("plugin: stop_read_threads: Signalling `read_cond'");
        pthread_cond_broadcast (&read_cond);
        pthread_mutex_unlock (&read_lock);
 
@@ -317,13 +338,43 @@ static void stop_threads (void)
        {
                if (pthread_join (read_threads[i], NULL) != 0)
                {
-                       ERROR ("plugin: stop_threads: pthread_join failed.");
+                       ERROR ("plugin: stop_read_threads: pthread_join failed.");
                }
                read_threads[i] = (pthread_t) 0;
        }
        sfree (read_threads);
        read_threads_num = 0;
-} /* void stop_threads */
+} /* void stop_read_threads */
+
+static int remove_read_functions (void)
+{
+       llentry_t *this;
+
+       if (list_read == NULL)
+               return (0);
+
+       this = llist_head (list_read);
+       while (this != NULL)
+       {
+               llentry_t *next;
+               read_func_t *rf;
+
+               next = this->next;
+               rf = (read_func_t *) this->value;
+
+               free (this->key);
+
+               plugin_user_data_destroy (&rf->udata);
+               free (rf);
+
+               this = next;
+       }
+
+       llist_destroy (list_read);
+       list_read = NULL;
+
+       return (0);
+} /* }}} int remove_read_functions */
 
 /*
  * Public functions
@@ -510,34 +561,55 @@ int plugin_register_complex_read (const char *name,
 int plugin_register_write (const char *name,
                plugin_write_cb callback, user_data_t *user_data)
 {
-       write_func_t *wr;
+       write_func_t *wf;
 
-       wr = (write_func_t *) malloc (sizeof (*wr));
-       if (wr == NULL)
+       wf = (write_func_t *) malloc (sizeof (*wf));
+       if (wf == NULL)
        {
                ERROR ("plugin_register_write: malloc failed.");
                return (-1);
        }
-       memset (wr, 0, sizeof (*wr));
+       memset (wf, 0, sizeof (*wf));
 
-       wr->callback = callback;
+       wf->callback = callback;
        if (user_data == NULL)
        {
-               wr->udata.data = NULL;
-               wr->udata.free_func = NULL;
+               wf->udata.data = NULL;
+               wf->udata.free_func = NULL;
        }
        else
        {
-               wr->udata = *user_data;
+               wf->udata = *user_data;
        }
 
-       return (register_callback (&list_write, name, (void *) wr));
+       return (register_callback (&list_write, name, (void *) wf));
 } /* int plugin_register_write */
 
 int plugin_register_flush (const char *name,
-               int (*callback) (const int timeout, const char *identifier))
+               plugin_flush_cb callback, user_data_t *user_data)
 {
-       return (register_callback (&list_flush, name, (void *) callback));
+       flush_func_t *ff;
+
+       ff = (flush_func_t *) malloc (sizeof (*ff));
+       if (ff == NULL)
+       {
+               ERROR ("plugin_register_flush: malloc failed.");
+               return (-1);
+       }
+       memset (ff, 0, sizeof (*ff));
+
+       ff->callback = callback;
+       if (user_data == NULL)
+       {
+               ff->udata.data = NULL;
+               ff->udata.free_func = NULL;
+       }
+       else
+       {
+               ff->udata = *user_data;
+       }
+
+       return (register_callback (&list_flush, name, (void *) ff));
 } /* int plugin_register_flush */
 
 int plugin_register_shutdown (char *name,
@@ -583,10 +655,31 @@ int plugin_register_data_set (const data_set_t *ds)
        return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy));
 } /* int plugin_register_data_set */
 
-int plugin_register_log (char *name,
-               void (*callback) (int priority, const char *msg))
+int plugin_register_log (const char *name,
+               plugin_log_cb callback, user_data_t *user_data)
 {
-       return (register_callback (&list_log, name, (void *) callback));
+       log_func_t *lf;
+
+       lf = (log_func_t *) malloc (sizeof (*lf));
+       if (lf == NULL)
+       {
+               ERROR ("plugin_register_log: malloc failed.");
+               return (-1);
+       }
+       memset (lf, 0, sizeof (*lf));
+
+       lf->callback = callback;
+       if (user_data == NULL)
+       {
+               lf->udata.data = NULL;
+               lf->udata.free_func = NULL;
+       }
+       else
+       {
+               lf->udata = *user_data;
+       }
+
+       return (register_callback (&list_log, name, (void *) lf));
 } /* int plugin_register_log */
 
 int plugin_register_notification (const char *name,
@@ -636,12 +729,46 @@ int plugin_unregister_read (const char *name)
 
 int plugin_unregister_write (const char *name)
 {
-       return (plugin_unregister (list_write, name));
+       llentry_t *e;
+       write_func_t *wf;
+
+       e = llist_search (list_write, name);
+
+       if (e == NULL)
+               return (-1);
+
+       llist_remove (list_write, e);
+
+       wf = (write_func_t *) e->value;
+       plugin_user_data_destroy (&wf->udata);
+       free (wf);
+       free (e->key);
+
+       llentry_destroy (e);
+
+       return (0);
 }
 
 int plugin_unregister_flush (const char *name)
 {
-       return (plugin_unregister (list_flush, name));
+       llentry_t *e;
+       flush_func_t *ff;
+
+       e = llist_search (list_flush, name);
+
+       if (e == NULL)
+               return (-1);
+
+       llist_remove (list_flush, e);
+
+       ff = (flush_func_t *) e->value;
+       plugin_user_data_destroy (&ff->udata);
+       free (ff);
+       free (e->key);
+
+       llentry_destroy (e);
+
+       return (0);
 }
 
 int plugin_unregister_shutdown (const char *name)
@@ -667,7 +794,24 @@ int plugin_unregister_data_set (const char *name)
 
 int plugin_unregister_log (const char *name)
 {
-       return (plugin_unregister (list_log, name));
+       llentry_t *e;
+       log_func_t *lf;
+
+       e = llist_search (list_log, name);
+
+       if (e == NULL)
+               return (-1);
+
+       llist_remove (list_log, e);
+
+       lf = (log_func_t *) e->value;
+       plugin_user_data_destroy (&lf->udata);
+       free (lf);
+       free (e->key);
+
+       llentry_destroy (e);
+
+       return (0);
 }
 
 int plugin_unregister_notification (const char *name)
@@ -728,7 +872,7 @@ void plugin_init_all (void)
                rt = global_option_get ("ReadThreads");
                num = atoi (rt);
                if (num != -1)
-                       start_threads ((num > 0) ? num : 5);
+                       start_read_threads ((num > 0) ? num : 5);
        }
 } /* void plugin_init_all */
 
@@ -815,7 +959,6 @@ int plugin_read_all_once (void)
 int plugin_write (const char *plugin, /* {{{ */
                const data_set_t *ds, const value_list_t *vl)
 {
-  int (*callback) (const data_set_t *ds, const value_list_t *vl);
   llentry_t *le;
   int status;
 
@@ -843,8 +986,10 @@ int plugin_write (const char *plugin, /* {{{ */
     le = llist_head (list_write);
     while (le != NULL)
     {
-      callback = le->value;
-      status = (*callback) (ds, vl);
+      write_func_t *wf = le->value;
+
+      DEBUG ("plugin: plugin_write: Writing values via %s.", le->key);
+      status = wf->callback (ds, vl, &wf->udata);
       if (status != 0)
         failure++;
       else
@@ -860,6 +1005,7 @@ int plugin_write (const char *plugin, /* {{{ */
   }
   else /* plugin != NULL */
   {
+    write_func_t *wf;
     le = llist_head (list_write);
     while (le != NULL)
     {
@@ -872,8 +1018,10 @@ int plugin_write (const char *plugin, /* {{{ */
     if (le == NULL)
       return (ENOENT);
 
-    callback = le->value;
-    status = (*callback) (ds, vl);
+    wf = le->value;
+
+    DEBUG ("plugin: plugin_write: Writing values via %s.", le->key);
+    status = wf->callback (ds, vl, &wf->udata);
   }
 
   return (status);
@@ -881,7 +1029,6 @@ int plugin_write (const char *plugin, /* {{{ */
 
 int plugin_flush (const char *plugin, int timeout, const char *identifier)
 {
-  int (*callback) (int timeout, const char *identifier);
   llentry_t *le;
 
   if (list_flush == NULL)
@@ -890,6 +1037,8 @@ int plugin_flush (const char *plugin, int timeout, const char *identifier)
   le = llist_head (list_flush);
   while (le != NULL)
   {
+    flush_func_t *ff;
+
     if ((plugin != NULL)
         && (strcmp (plugin, le->key) != 0))
     {
@@ -897,8 +1046,9 @@ int plugin_flush (const char *plugin, int timeout, const char *identifier)
       continue;
     }
 
-    callback = (int (*) (int, const char *)) le->value;
-    (*callback) (timeout, identifier);
+    ff = (flush_func_t *) le->value;
+
+    ff->callback (timeout, identifier, &ff->udata);
 
     le = le->next;
   }
@@ -910,7 +1060,8 @@ void plugin_shutdown_all (void)
        int (*callback) (void);
        llentry_t *le;
 
-       stop_threads ();
+       stop_read_threads ();
+       remove_read_functions ();
 
        if (list_shutdown == NULL)
                return;
@@ -1066,8 +1217,6 @@ void plugin_log (int level, const char *format, ...)
 {
        char msg[1024];
        va_list ap;
-
-       void (*callback) (int, const char *);
        llentry_t *le;
 
        if (list_log == NULL)
@@ -1086,8 +1235,11 @@ void plugin_log (int level, const char *format, ...)
        le = llist_head (list_log);
        while (le != NULL)
        {
-               callback = (void (*) (int, const char *)) le->value;
-               (*callback) (level, msg);
+               log_func_t *lf;
+
+               lf = (log_func_t *) le->value;
+
+               lf->callback (level, msg, &lf->udata);
 
                le = le->next;
        }