python plugin: Properly deal with identifier being NULL in a log callback.
[collectd.git] / src / python.c
index 24046de..a555734 100644 (file)
@@ -197,7 +197,7 @@ static char reg_flush_doc[] = "register_flush(callback[, data][, name]) -> ident
                "The callback function will be called with two or three parameters:\n"
                "timeout: Indicates that only data older than 'timeout' seconds is to\n"
                "    be flushed.\n"
-               "id: Specifies which values are to be flushed.\n"
+               "id: Specifies which values are to be flushed. Might be None.\n"
                "data: The optional data parameter passed to the register function.\n"
                "    If the parameter was omitted it will be omitted here, too.";
 
@@ -239,8 +239,10 @@ static cpy_callback_t *cpy_shutdown_callbacks;
 static void cpy_destroy_user_data(void *data) {
        cpy_callback_t *c = data;
        free(c->name);
+       CPY_LOCK_THREADS
        Py_DECREF(c->callback);
        Py_XDECREF(c->data);
+       CPY_RELEASE_THREADS
        free(c);
 }
 
@@ -389,12 +391,11 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                }
                dict = PyDict_New();  /* New reference. */
                if (value_list->meta) {
-                       int num;
                        char **table;
                        meta_data_t *meta = value_list->meta;
 
-                       num = meta_data_toc(meta, &table);
-                       for (size_t i = 0; i < num; ++i) {
+                       int num = meta_data_toc(meta, &table);
+                       for (int i = 0; i < num; ++i) {
                                int type;
                                char *string;
                                int64_t si;
@@ -519,7 +520,12 @@ static void cpy_flush_callback(int timeout, const char *id, user_data_t *data) {
        PyObject *ret, *text;
 
        CPY_LOCK_THREADS
-       text = cpy_string_to_unicode_or_bytes(id);
+       if (id) {
+               text = cpy_string_to_unicode_or_bytes(id);
+       } else {
+               text = Py_None;
+               Py_INCREF(text);
+       }
        if (c->data == NULL)
                ret = PyObject_CallFunction(c->callback, "iN", timeout, text); /* New reference. */
        else
@@ -624,7 +630,6 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
        char buf[512];
        reg_function_t *register_function = (reg_function_t *) reg;
        cpy_callback_t *c = NULL;
-       user_data_t user_data = { 0 };
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
        static char *kwlist[] = {"callback", "data", "name", NULL};
@@ -650,8 +655,10 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
        c->data = data;
        c->next = NULL;
 
-       user_data.free_func = cpy_destroy_user_data;
-       user_data.data = c;
+       user_data_t user_data = {
+               .data = c,
+               .free_func = cpy_destroy_user_data
+       };
 
        register_function(buf, handler, &user_data);
        return cpy_string_to_unicode_or_bytes(buf);
@@ -660,7 +667,6 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
 static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
        char buf[512];
        cpy_callback_t *c = NULL;
-       user_data_t user_data = { 0 };
        double interval = 0;
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
@@ -687,8 +693,10 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd
        c->data = data;
        c->next = NULL;
 
-       user_data.free_func = cpy_destroy_user_data;
-       user_data.data = c;
+       user_data_t user_data = {
+               .data = c,
+               .free_func = cpy_destroy_user_data
+       };
 
        plugin_register_complex_read(/* group = */ "python", buf,
                        cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), &user_data);