Added unregister functions for all callbacks.
authorSven Trenkel <collectd@semidefinite.de>
Mon, 16 Nov 2009 00:57:20 +0000 (01:57 +0100)
committerSven Trenkel <collectd@semidefinite.de>
Mon, 16 Nov 2009 00:57:20 +0000 (01:57 +0100)
Also removed useless plugin_unregister_complex_read declaration.

src/plugin.h
src/python.c

index e576141..868f44a 100644 (file)
@@ -284,7 +284,6 @@ 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);
index a9fc0c6..4082296 100644 (file)
@@ -411,6 +411,89 @@ static PyObject *cpy_debug(PyObject *self, PyObject *args) {
        Py_RETURN_NONE;
 }
 
+static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *arg, const char *desc, int short_name) {
+       char buf[512];
+       const char *name;
+       cpy_callback_t *prev = NULL, *tmp;
+
+       if (PyString_Check(arg)) {
+               name = PyString_AsString(arg);
+       } else {
+               if (!PyCallable_Check(arg)) {
+                       PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
+                       return NULL;
+               }
+               cpy_build_name(buf, sizeof(buf), arg, NULL, short_name);
+               name = buf;
+       }
+       for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next)
+               if (strcmp(name, tmp->name) == 0)
+                       break;
+       
+       if (tmp == NULL) {
+               PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
+               return NULL;
+       }
+       /* Yes, this is actually save. To call this function the calles has to
+        * hold the GIL. Well, save as long as there is only one GIL anyway ... */
+       if (prev == NULL)
+               *list_head = tmp->next;
+       else
+               prev->next = tmp->next;
+       cpy_destroy_user_data(tmp);
+       Py_RETURN_NONE;
+}
+
+typedef int cpy_unregister_function_t(const char *name);
+
+static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc, int short_name) {
+       char buf[512];
+       const char *name;
+
+       if (PyString_Check(arg)) {
+               name = PyString_AsString(arg);
+       } else {
+               if (!PyCallable_Check(arg)) {
+                       PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
+                       return NULL;
+               }
+               cpy_build_name(buf, sizeof(buf), arg, NULL, short_name);
+               name = buf;
+       }
+       if (unreg(name) == 0)
+               Py_RETURN_NONE;
+       PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
+       return NULL;
+}
+
+static PyObject *cpy_unregister_log(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic_userdata(plugin_unregister_log, arg, "log", 0);
+}
+
+static PyObject *cpy_unregister_init(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic(&cpy_init_callbacks, arg, "init", 0);
+}
+
+static PyObject *cpy_unregister_config(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic(&cpy_config_callbacks, arg, "config", 1);
+}
+
+static PyObject *cpy_unregister_read(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic_userdata(plugin_unregister_read, arg, "read", 0);
+}
+
+static PyObject *cpy_unregister_write(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic_userdata(plugin_unregister_write, arg, "write", 0);
+}
+
+static PyObject *cpy_unregister_flush(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic_userdata(plugin_unregister_flush, arg, "flush", 1);
+}
+
+static PyObject *cpy_unregister_shutdown(PyObject *self, PyObject *arg) {
+       return cpy_unregister_generic(&cpy_shutdown_callbacks, arg, "shutdown", 0);
+}
+
 static PyMethodDef cpy_methods[] = {
        {"debug", cpy_debug, METH_VARARGS, "This is an unhelpful text."},
        {"info", cpy_info, METH_VARARGS, "This is an unhelpful text."},
@@ -425,6 +508,13 @@ static PyMethodDef cpy_methods[] = {
        {"register_write", (PyCFunction) cpy_register_write, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
        {"register_flush", (PyCFunction) cpy_register_flush, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
        {"register_shutdown", (PyCFunction) cpy_register_shutdown, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
+       {"unregister_log", cpy_unregister_log, METH_O, "This is an unhelpful text."},
+       {"unregister_init", cpy_unregister_init, METH_O, "This is an unhelpful text."},
+       {"unregister_config", cpy_unregister_config, METH_O, "This is an unhelpful text."},
+       {"unregister_read", cpy_unregister_read, METH_O, "This is an unhelpful text."},
+       {"unregister_write", cpy_unregister_write, METH_O, "This is an unhelpful text."},
+       {"unregister_flush", cpy_unregister_flush, METH_O, "This is an unhelpful text."},
+       {"unregister_shutdown", cpy_unregister_shutdown, METH_O, "This is an unhelpful text."},
        {0, 0, 0, 0}
 };