summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8e1ace0)
raw | patch | inline | side by side (parent: 8e1ace0)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 25 Sep 2013 08:53:06 +0000 (10:53 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 25 Sep 2013 08:53:06 +0000 (10:53 +0200) |
Store the new dynamic context in callbacks. The daemon may no longer set the
context before loading a plugin. Instead, sdb_plugin_load now accepts a second
parameter specifying the public context attributes.
context before loading a plugin. Instead, sdb_plugin_load now accepts a second
parameter specifying the public context attributes.
src/core/plugin.c | patch | blob | history | |
src/daemon/config.c | patch | blob | history | |
src/include/core/plugin.h | patch | blob | history |
diff --git a/src/core/plugin.c b/src/core/plugin.c
index fa00c0510b944dea05af3752c01769828b11cf28..a31ede30f2ed4104f104d9780bb6104ed484ed17 100644 (file)
--- a/src/core/plugin.c
+++ b/src/core/plugin.c
#define INFO_GET(i, attr) \
((i)->attr ? (i)->attr : #attr" not set")
+typedef struct {
+ sdb_object_t super;
+ sdb_plugin_ctx_t public;
+} ctx_t;
+#define CTX_INIT { SDB_OBJECT_INIT, \
+ SDB_PLUGIN_CTX_INIT }
+
+#define CTX(obj) ((ctx_t *)(obj))
+
typedef struct {
sdb_object_t super;
void *cb_callback;
sdb_object_t *cb_user_data;
- sdb_plugin_ctx_t cb_ctx;
+ ctx_t *cb_ctx;
} sdb_plugin_cb_t;
#define SDB_PLUGIN_CB_INIT { SDB_OBJECT_INIT, \
/* callback = */ NULL, /* user_data = */ NULL, \
#define SDB_PLUGIN_CB(obj) ((sdb_plugin_cb_t *)(obj))
#define SDB_PLUGIN_CCB(obj) ((sdb_plugin_collector_cb_t *)(obj))
-typedef struct {
- sdb_object_t super;
- sdb_plugin_ctx_t public;
-} ctx_t;
-#define CTX_INIT { SDB_OBJECT_INIT, \
- SDB_PLUGIN_CTX_INIT }
-
-#define CTX(obj) ((ctx_t *)(obj))
-
/*
* private variables
*/
*info = empty_info;
} /* sdb_plugin_info_clear */
-static void
-ctx_destructor(void *c)
-{
- sdb_object_deref(SDB_OBJ(c));
-} /* ctx_destructor */
-
static void
ctx_key_init(void)
{
if (plugin_ctx_key_initialized)
return;
- pthread_key_create(&plugin_ctx_key, ctx_destructor);
+ pthread_key_create(&plugin_ctx_key, /* destructor */ NULL);
plugin_ctx_key_initialized = 1;
} /* ctx_key_init */
return ctx;
} /* ctx_create */
+static ctx_t *
+ctx_get(void)
+{
+ if (! plugin_ctx_key_initialized)
+ ctx_key_init();
+ return pthread_getspecific(plugin_ctx_key);
+} /* ctx_get */
+
+static ctx_t *
+ctx_set(ctx_t *new)
+{
+ ctx_t *old;
+
+ if (! plugin_ctx_key_initialized)
+ ctx_key_init();
+
+ old = pthread_getspecific(plugin_ctx_key);
+ pthread_setspecific(plugin_ctx_key, new);
+ return old;
+} /* ctx_set */
+
static int
sdb_plugin_cb_init(sdb_object_t *obj, va_list ap)
{
}
SDB_PLUGIN_CB(obj)->cb_callback = callback;
- SDB_PLUGIN_CB(obj)->cb_ctx = sdb_plugin_get_ctx();
+ SDB_PLUGIN_CB(obj)->cb_ctx = ctx_get();
+ sdb_object_ref(SDB_OBJ(SDB_PLUGIN_CB(obj)->cb_ctx));
sdb_object_ref(ud);
SDB_PLUGIN_CB(obj)->cb_user_data = ud;
{
assert(obj);
sdb_object_deref(SDB_PLUGIN_CB(obj)->cb_user_data);
+ sdb_object_deref(SDB_OBJ(SDB_PLUGIN_CB(obj)->cb_ctx));
} /* sdb_plugin_cb_destroy */
static sdb_type_t sdb_plugin_cb_type = {
*/
int
-sdb_plugin_load(const char *name)
+sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx)
{
char real_name[strlen(name) > 0 ? strlen(name) : 1];
const char *name_ptr;
char *tmp;
char filename[1024];
+ ctx_t *ctx;
lt_dlhandle lh;
return -1;
}
+ if (ctx_get())
+ sdb_log(SDB_LOG_WARNING, "plugin: Discarding old plugin context");
+
+ ctx = ctx_create();
+ if (! ctx) {
+ sdb_log(SDB_LOG_ERR, "plugin: Failed to initialize plugin context");
+ return -1;
+ }
+
+ if (plugin_ctx)
+ ctx->public = *plugin_ctx;
+
mod_init = (int (*)(sdb_plugin_info_t *))lt_dlsym(lh, "sdb_module_init");
if (! mod_init) {
sdb_log(SDB_LOG_ERR, "plugin: Failed to load plugin '%s': "
"could not find symbol 'sdb_module_init'", name);
+ sdb_object_deref(SDB_OBJ(ctx));
return -1;
}
sdb_log(SDB_LOG_ERR, "plugin: Failed to initialize "
"plugin '%s'", name);
sdb_plugin_info_clear(&info);
+ sdb_object_deref(SDB_OBJ(ctx));
return -1;
}
INFO_GET(&info, description),
INFO_GET(&info, copyright),
INFO_GET(&info, license));
+
sdb_plugin_info_clear(&info);
+ /* any registered callbacks took ownership of the context */
+ sdb_object_deref(SDB_OBJ(ctx));
+
+ /* reset */
+ ctx_set(NULL);
return 0;
} /* sdb_plugin_load */
@@ -539,37 +577,33 @@ sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback
sdb_plugin_ctx_t
sdb_plugin_get_ctx(void)
{
- ctx_t *ctx;
+ ctx_t *c;
- if (! plugin_ctx_key_initialized)
- ctx_key_init();
- ctx = pthread_getspecific(plugin_ctx_key);
-
- if (! ctx)
- ctx = ctx_create();
- if (! ctx)
+ c = ctx_get();
+ if (! c) {
+ sdb_plugin_log(SDB_LOG_ERR, "plugin: Invalid read access to plugin "
+ "context outside a plugin");
return plugin_default_ctx;
- return ctx->public;
+ }
+ return c->public;
} /* sdb_plugin_get_ctx */
-sdb_plugin_ctx_t
-sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx)
+int
+sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx, sdb_plugin_ctx_t *old)
{
- ctx_t *tmp;
- sdb_plugin_ctx_t old;
-
- if (! plugin_ctx_key_initialized)
- ctx_key_init();
- tmp = pthread_getspecific(plugin_ctx_key);
+ ctx_t *c;
- if (! tmp)
- tmp = ctx_create();
- if (! tmp)
- return plugin_default_ctx;
+ c = ctx_get();
+ if (! c) {
+ sdb_plugin_log(SDB_LOG_ERR, "plugin: Invalid write access to plugin "
+ "context outside a plugin");
+ return -1;
+ }
- old = tmp->public;
- tmp->public = ctx;
- return old;
+ if (old)
+ *old = c->public;
+ c->public = ctx;
+ return 0;
} /* sdb_plugin_set_ctx */
int
sdb_plugin_cb_t *plugin;
sdb_plugin_config_cb callback;
- sdb_plugin_ctx_t old_ctx;
+ ctx_t *old_ctx;
int status;
return -1;
}
- old_ctx = sdb_plugin_set_ctx(plugin->cb_ctx);
+ old_ctx = ctx_set(plugin->cb_ctx);
callback = plugin->cb_callback;
status = callback(ci);
- sdb_plugin_set_ctx(old_ctx);
+ ctx_set(old_ctx);
return status;
} /* sdb_plugin_configure */
iter = sdb_llist_get_iter(init_list);
while (sdb_llist_iter_has_next(iter)) {
sdb_plugin_init_cb callback;
- sdb_plugin_ctx_t old_ctx;
+ ctx_t *old_ctx;
sdb_object_t *obj = sdb_llist_iter_get_next(iter);
assert(obj);
callback = SDB_PLUGIN_CB(obj)->cb_callback;
- old_ctx = sdb_plugin_set_ctx(SDB_PLUGIN_CB(obj)->cb_ctx);
+ old_ctx = ctx_set(SDB_PLUGIN_CB(obj)->cb_ctx);
if (callback(SDB_PLUGIN_CB(obj)->cb_user_data)) {
/* XXX: unload plugin */
}
- sdb_plugin_set_ctx(old_ctx);
+ ctx_set(old_ctx);
}
sdb_llist_iter_destroy(iter);
return 0;
while (loop->do_loop) {
sdb_plugin_collector_cb callback;
- sdb_plugin_ctx_t old_ctx;
+ ctx_t *old_ctx;
sdb_time_t interval, now;
return 0;
}
- old_ctx = sdb_plugin_set_ctx(SDB_PLUGIN_CCB(obj)->ccb_ctx);
+ old_ctx = ctx_set(SDB_PLUGIN_CCB(obj)->ccb_ctx);
if (callback(SDB_PLUGIN_CCB(obj)->ccb_user_data)) {
/* XXX */
}
- sdb_plugin_set_ctx(old_ctx);
+ ctx_set(old_ctx);
interval = SDB_PLUGIN_CCB(obj)->ccb_interval;
if (! interval)
diff --git a/src/daemon/config.c b/src/daemon/config.c
index 76955050837b2714011252e74e6dda78e7b660bc..d15081f469446ee1f3b3214b6dbe8efcdf6e7253 100644 (file)
--- a/src/daemon/config.c
+++ b/src/daemon/config.c
daemon_load_plugin(oconfig_item_t *ci)
{
char *name;
-
- sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
- sdb_plugin_ctx_t old_ctx;
-
- int status, i;
+ int i;
if (oconfig_get_string(ci, &name)) {
sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single "
continue;
}
- old_ctx = sdb_plugin_set_ctx(ctx);
- status = sdb_plugin_load(name);
- sdb_plugin_set_ctx(old_ctx);
- return status;
+ return sdb_plugin_load(name, NULL);
} /* daemon_load_plugin */
static int
daemon_load_backend(oconfig_item_t *ci)
{
+ sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
+
char plugin_name[1024];
char *name;
- sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT;
- sdb_plugin_ctx_t old_ctx;
-
- int status, i;
+ int i;
ctx.interval = default_interval;
}
}
- old_ctx = sdb_plugin_set_ctx(ctx);
- status = sdb_plugin_load(plugin_name);
- sdb_plugin_set_ctx(old_ctx);
- return status;
+ return sdb_plugin_load(plugin_name, &ctx);
} /* daemon_load_backend */
static int
index 446c8672ff890edd7a3180047ba7897677410b03..6a679ce8a17baa5900573ee38cf0deb3e22882cb 100644 (file)
/*
* sdb_plugin_load:
* Load (any type of) plugin by loading the shared object file and calling the
- * sdb_module_init function.
+ * sdb_module_init function. If specified, 'plugin_ctx' fine-tunes the
+ * behavior of the plugin.
*/
int
-sdb_plugin_load(const char *name);
+sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx);
/*
* sdb_plugin_set_info:
* plugin has been called. It may be used to pass around various information
* between the different component of the library without having each and
* every plugin care about it.
+ *
+ * If non-NULL, sdb_plugin_set_ctx stores the previous context in the location
+ * pointed to be 'old'.
*/
sdb_plugin_ctx_t
sdb_plugin_get_ctx(void);
-sdb_plugin_ctx_t
-sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx);
+int
+sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx, sdb_plugin_ctx_t *old);
/*
* sdb_plugin_configure: