From 16baafe97586dd469a9b14a91c2c24762367d6f2 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sat, 21 Feb 2009 18:29:52 +0100 Subject: [PATCH] src/plugin.c: Implement `plugin_register_complex_read' These read callbacks will receive a user pointer. This is nice for the Java plugin, because the plugin infrastructure can now call one specific Java read function. AfaIk, the Perl plugin can make use of this, too. --- src/plugin.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/plugin.h | 15 ++++++++ 2 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/plugin.c b/src/plugin.c index 9f42f2e4..ee39bd3a 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -41,12 +41,20 @@ /* * Private structures */ +#define RF_SIMPLE 0 +#define RF_COMPLEX 1 struct read_func_s { int wait_time; int wait_left; - int (*callback) (void); + int type; + union + { + int (*cb_simple) (void); + plugin_read_cb cb_complex; + } callback; enum { DONE = 0, TODO = 1, ACTIVE = 2 } needs_read; + user_data_t udata; }; typedef struct read_func_s read_func_t; @@ -118,6 +126,16 @@ static int register_callback (llist_t **list, const char *name, void *callback) return (0); } /* int register_callback */ +static void plugin_user_data_destroy (user_data_t *ud) +{ + if ((ud != NULL) && (ud->data != NULL) && (ud->free_func != NULL)) + { + ud->free_func (ud->data); + ud->data = NULL; + ud->free_func = NULL; + } +} /* void plugin_user_data_destroy */ + static int plugin_unregister (llist_t *list, const char *name) { llentry_t *e; @@ -202,7 +220,15 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) (unsigned long int) pthread_self (), le->key); pthread_mutex_unlock (&read_lock); - status = rf->callback (); + if (rf->type == RF_SIMPLE) + { + status = rf->callback.cb_simple (); + } + else + { + assert (rf->type == RF_COMPLEX); + status = rf->callback.cb_complex (&rf->udata); + } done++; if (status != 0) @@ -436,19 +462,76 @@ int plugin_register_read (const char *name, return (-1); } - memset (rf, '\0', sizeof (read_func_t)); + memset (rf, 0, sizeof (read_func_t)); rf->wait_time = interval_g; rf->wait_left = 0; - rf->callback = callback; + rf->type = RF_SIMPLE; + rf->callback.cb_simple = callback; rf->needs_read = DONE; + rf->udata.data = NULL; + rf->udata.free_func = NULL; return (register_callback (&list_read, name, (void *) rf)); } /* int plugin_register_read */ +int plugin_register_complex_read (const char *name, + plugin_read_cb callback, user_data_t *user_data) +{ + read_func_t *rf; + + rf = (read_func_t *) malloc (sizeof (read_func_t)); + if (rf == NULL) + { + ERROR ("plugin_register_complex_read: malloc failed."); + return (-1); + } + + memset (rf, 0, sizeof (read_func_t)); + rf->wait_time = interval_g; + rf->wait_left = 0; + rf->type = RF_COMPLEX; + rf->callback.cb_complex = callback; + rf->needs_read = DONE; + + /* Set user data */ + if (user_data == NULL) + { + rf->udata.data = NULL; + rf->udata.free_func = NULL; + } + else + { + rf->udata = *user_data; + } + + return (register_callback (&list_read, name, (void *) rf)); +} /* int plugin_register_complex_read */ + int plugin_register_write (const char *name, - int (*callback) (const data_set_t *ds, const value_list_t *vl)) + plugin_write_cb callback, user_data_t *user_data) { - return (register_callback (&list_write, name, (void *) callback)); + write_func_t *wr; + + wr = (write_func_t *) malloc (sizeof (*wr)); + if (wr == NULL) + { + ERROR ("plugin_register_write: malloc failed."); + return (-1); + } + memset (wr, 0, sizeof (*wr)); + + wr->callback = callback; + if (user_data == NULL) + { + wr->udata.data = NULL; + wr->udata.free_func = NULL; + } + else + { + wr->udata = *user_data; + } + + return (register_callback (&list_write, name, (void *) wr)); } /* int plugin_register_write */ int plugin_register_flush (const char *name, @@ -532,6 +615,7 @@ int plugin_unregister_init (const char *name) int plugin_unregister_read (const char *name) { llentry_t *e; + read_func_t *rf; e = llist_search (list_read, name); @@ -539,8 +623,12 @@ int plugin_unregister_read (const char *name) return (-1); llist_remove (list_read, e); - free (e->value); + + rf = (read_func_t *) e->value; + plugin_user_data_destroy (&rf->udata); + free (rf); free (e->key); + llentry_destroy (e); return (0); @@ -702,7 +790,17 @@ int plugin_read_all_once (void) le = le->next) { rf = (read_func_t *) le->value; - status = rf->callback (); + + if (rf->type == RF_SIMPLE) + { + status = rf->callback.cb_simple (); + } + else + { + assert (rf->type == RF_COMPLEX); + status = rf->callback.cb_complex (&rf->udata); + } + if (status != 0) { NOTICE ("read-function of plugin `%s' failed.", diff --git a/src/plugin.h b/src/plugin.h index 3088e06e..1eb9feca 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -136,6 +136,18 @@ typedef struct notification_s notification_meta_t *meta; } notification_t; +struct user_data_s +{ + void *data; + void (*free_func) (void *); +}; +typedef struct user_data_s user_data_t; + +/* + * Callback types + */ +typedef int (*plugin_read_cb) (user_data_t *); + /* * NAME * plugin_set_dir @@ -225,6 +237,8 @@ int plugin_register_init (const char *name, int (*callback) (void)); int plugin_register_read (const char *name, int (*callback) (void)); +int plugin_register_complex_read (const char *name, + plugin_read_cb callback, user_data_t *user_data); int plugin_register_write (const char *name, int (*callback) (const data_set_t *ds, const value_list_t *vl)); int plugin_register_flush (const char *name, @@ -241,6 +255,7 @@ int plugin_unregister_config (const char *name); int plugin_unregister_complex_config (const char *name); int plugin_unregister_init (const char *name); int plugin_unregister_read (const char *name); +int plugin_unregister_complex_read (const char *name, void **user_data); int plugin_unregister_write (const char *name); int plugin_unregister_flush (const char *name); int plugin_unregister_shutdown (const char *name); -- 2.11.0