Merge branch 'ff/highres'
[collectd.git] / src / python.c
index 00516fb..eed0591 100644 (file)
@@ -335,7 +335,7 @@ static int cpy_read_callback(user_data_t *data) {
 static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
        int i;
        cpy_callback_t *c = data->data;
-       PyObject *ret, *list, *temp, *dict = NULL;
+       PyObject *ret, *list, *temp, *dict = NULL, *val;
        Values *v;
 
        CPY_LOCK_THREADS
@@ -371,6 +371,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        }
                        if (PyErr_Occurred() != NULL) {
                                cpy_log_exception("value building for write callback");
+                               Py_DECREF(list);
                                CPY_RETURN_FROM_THREADS 0;
                        }
                }
@@ -427,17 +428,21 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        }
                        free(table);
                }
-               v = PyObject_New(Values, (void *) &ValuesType);
+               val = Values_New(); /* New reference. */
+               v = (Values *) val; 
                sstrncpy(v->data.host, value_list->host, sizeof(v->data.host));
                sstrncpy(v->data.type, value_list->type, sizeof(v->data.type));
                sstrncpy(v->data.type_instance, value_list->type_instance, sizeof(v->data.type_instance));
                sstrncpy(v->data.plugin, value_list->plugin, sizeof(v->data.plugin));
                sstrncpy(v->data.plugin_instance, value_list->plugin_instance, sizeof(v->data.plugin_instance));
-               v->data.time = value_list->time;
-               v->interval = value_list->interval;
+               v->data.time = CDTIME_T_TO_DOUBLE(value_list->time);
+               v->interval = CDTIME_T_TO_DOUBLE(value_list->interval);
+               Py_CLEAR(v->values);
                v->values = list;
+               Py_CLEAR(v->meta);
                v->meta = dict;
                ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */
+               Py_XDECREF(val);
                if (ret == NULL) {
                        cpy_log_exception("write callback");
                } else {
@@ -449,20 +454,22 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
 
 static int cpy_notification_callback(const notification_t *notification, user_data_t *data) {
        cpy_callback_t *c = data->data;
-       PyObject *ret;
+       PyObject *ret, *notify;
        Notification *n;
 
        CPY_LOCK_THREADS
-               n = PyObject_New(Notification, (void *) &NotificationType);
+               notify = Notification_New(); /* New reference. */
+               n = (Notification *) notify;
                sstrncpy(n->data.host, notification->host, sizeof(n->data.host));
                sstrncpy(n->data.type, notification->type, sizeof(n->data.type));
                sstrncpy(n->data.type_instance, notification->type_instance, sizeof(n->data.type_instance));
                sstrncpy(n->data.plugin, notification->plugin, sizeof(n->data.plugin));
                sstrncpy(n->data.plugin_instance, notification->plugin_instance, sizeof(n->data.plugin_instance));
-               n->data.time = notification->time;
+               n->data.time = CDTIME_T_TO_DOUBLE(notification->time);
                sstrncpy(n->message, notification->message, sizeof(n->message));
                n->severity = notification->severity;
                ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
+               Py_XDECREF(notify);
                if (ret == NULL) {
                        cpy_log_exception("notification callback");
                } else {
@@ -896,6 +903,11 @@ static int cpy_init(void) {
        static pthread_t thread;
        sigset_t sigset;
        
+       if (!Py_IsInitialized()) {
+               WARNING("python: Plugin loaded but not configured.");
+               plugin_unregister_shutdown("python");
+               return 0;
+       }
        PyEval_InitThreads();
        /* Now it's finally OK to use python threads. */
        for (c = cpy_init_callbacks; c; c = c->next) {
@@ -966,6 +978,7 @@ PyMODINIT_FUNC PyInit_collectd(void) {
 
 static int cpy_config(oconfig_item_t *ci) {
        int i;
+       char *argv = "";
        PyObject *sys, *tb;
        PyObject *sys_path;
        PyObject *module;
@@ -1005,6 +1018,9 @@ static int cpy_config(oconfig_item_t *ci) {
                cpy_log_exception("python initialization");
                return 1;
        }
+       PySys_SetArgv(1, &argv);
+       PyList_SetSlice(sys_path, 0, 1, NULL);
+
 #ifdef IS_PY3K
        module = PyImport_ImportModule("collectd");
 #else