summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a1a8bdc)
raw | patch | inline | side by side (parent: a1a8bdc)
author | Sven Trenkel <collectd@semidefinite.de> | |
Tue, 3 Nov 2009 00:32:36 +0000 (01:32 +0100) | ||
committer | Sven Trenkel <collectd@semidefinite.de> | |
Tue, 3 Nov 2009 00:32:36 +0000 (01:32 +0100) |
src/cpython.h | patch | blob | history | |
src/python.c | patch | blob | history |
diff --git a/src/cpython.h b/src/cpython.h
index bec6cde9866b044cf2a8dc4185d877ca6d075d7c..4cac6c59f3d74c94bca8abaea35f73bf53f40906 100644 (file)
--- a/src/cpython.h
+++ b/src/cpython.h
PyGILState_STATE gil_state;\
gil_state = PyGILState_Ensure();
+#define CPY_RETURN_FROM_THREADS \
+ PyGILState_Release(gil_state);\
+ return
+
#define CPY_RELEASE_THREADS \
PyGILState_Release(gil_state);\
}
diff --git a/src/python.c b/src/python.c
index c15b0d55234fb606e67f10748d31bf6463c9f6d9..56061ff53369293881eef8437552aa119835d1e2 100644 (file)
--- a/src/python.c
+++ b/src/python.c
free(c);
}
+static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) {
+ const char *module;
+ PyObject *mod = NULL, *n = NULL;
+
+ if (name != NULL && strchr(name, '.') != NULL) {
+ snprintf(buf, size, "python.%s", name);
+ return;
+ }
+
+ mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
+ if (mod != NULL)
+ module = PyString_AsString(mod);
+ else
+ module = "collectd";
+ if (name != NULL) {
+ snprintf(buf, size, "python.%s.%s", module, name);
+ Py_XDECREF(mod);
+ return;
+ }
+
+ n = PyObject_GetAttrString(callback, "__name__"); /* New reference. */
+ if (n != NULL)
+ name = PyString_AsString(n);
+
+ if (name != NULL)
+ snprintf(buf, size, "python.%s.%s", module, name);
+ else
+ snprintf(buf, size, "python.%s.%p", module, callback);
+ Py_XDECREF(mod);
+ Py_XDECREF(n);
+}
+
+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, *v, *list;
+
+ CPY_LOCK_THREADS
+ list = PyList_New(value_list->values_len); /* New reference. */
+ if (list == NULL) {
+ PyErr_Print();
+ CPY_RETURN_FROM_THREADS 0;
+ }
+ for (i = 0; i < value_list->values_len; ++i) {
+ if (ds->ds->type == DS_TYPE_COUNTER) {
+ if ((long) value_list->values[i].counter == value_list->values[i].counter)
+ PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].counter));
+ else
+ PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
+ } else if (ds->ds->type == DS_TYPE_GAUGE) {
+ PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge));
+ } else if (ds->ds->type == DS_TYPE_DERIVE) {
+ if ((long) value_list->values[i].derive == value_list->values[i].derive)
+ PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].derive));
+ else
+ PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
+ } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+ if ((long) value_list->values[i].absolute == value_list->values[i].absolute)
+ PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].absolute));
+ else
+ PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
+ } else {
+ ERROR("cpy_write_callback: Unknown value type %d.", ds->ds->type);
+ Py_DECREF(list);
+ CPY_RETURN_FROM_THREADS 0;
+ }
+ if (PyErr_Occurred() != NULL) {
+ PyErr_Print();
+ CPY_RETURN_FROM_THREADS 0;
+ }
+ }
+ v = PyObject_CallFunction((PyObject *) &ValuesType, "sOssssdi", value_list->type, list,
+ value_list->plugin_instance, value_list->type_instance, value_list->plugin,
+ value_list->host, (double) value_list->time, value_list->interval);
+ Py_DECREF(list);
+ ret = PyObject_CallFunctionObjArgs(c->callback, v, (void *) 0);
+ if (ret == NULL) {
+ /* FIXME */
+ PyErr_Print();
+ } else {
+ Py_DECREF(ret);
+ }
+ CPY_RELEASE_THREADS
+ return 0;
+}
+
static void cpy_log_callback(int severity, const char *message, user_data_t *data) {
cpy_callback_t * c = data->data;
PyObject *ret;
static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) {
cpy_callback_t *c;
const char *name = NULL;
- PyObject *callback = NULL, *data = NULL;
+ PyObject *callback = NULL, *data = NULL, *mod = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oz", kwlist, &callback, &data, &name) == 0) return NULL;
@@ -63,11 +149,10 @@ static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args
return NULL;
}
if (name == NULL) {
- PyObject *mod;
-
- mod = PyObject_GetAttrString(callback, "__module__");
+ mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
if (mod != NULL) name = PyString_AsString(mod);
if (name == NULL) {
+ Py_XDECREF(mod);
PyErr_SetString(PyExc_ValueError, "No module name specified and "
"callback function does not have a \"__module__\" attribute.");
return NULL;
c->data = data;
c->next = *list_head;
*list_head = c;
+ Py_XDECREF(mod);
Py_RETURN_NONE;
}
@@ -92,7 +178,11 @@ static PyObject *cpy_register_init(PyObject *self, PyObject *args, PyObject *kwd
return cpy_register_generic(&cpy_init_callbacks, args, kwds);
}
-static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) {
+typedef int reg_function_t(const char *name, void *callback, void *data);
+
+static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObject *args, PyObject *kwds) {
+ char buf[512];
+ reg_function_t *register_function = (reg_function_t *) reg;
cpy_callback_t *c = NULL;
user_data_t *user_data = NULL;
const char *name = NULL;
@@ -104,29 +194,28 @@ static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds
PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
return NULL;
}
- if (name == NULL) {
- PyObject *mod;
-
- mod = PyObject_GetAttrString(callback, "__module__");
- if (mod != NULL) name = PyString_AsString(mod);
- if (name == NULL) {
- PyErr_SetString(PyExc_ValueError, "No module name specified and "
- "callback function does not have a \"__module__\" attribute.");
- return NULL;
- }
- }
+ cpy_build_name(buf, sizeof(buf), callback, name);
+
Py_INCREF(callback);
Py_XINCREF(data);
c = malloc(sizeof(*c));
- c->name = strdup(name);
+ c->name = strdup(buf);
c->callback = callback;
c->data = data;
c->next = NULL;
user_data = malloc(sizeof(*user_data));
user_data->free_func = cpy_destroy_user_data;
user_data->data = c;
- plugin_register_log(name, cpy_log_callback, user_data);
- Py_RETURN_NONE;
+ register_function(buf, handler, user_data);
+ return PyString_FromString(buf);
+}
+
+static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) {
+ return cpy_register_generic_userdata(plugin_register_log, cpy_log_callback, args, kwds);
+}
+
+static PyObject *cpy_register_write(PyObject *self, PyObject *args, PyObject *kwds) {
+ return cpy_register_generic_userdata(plugin_register_write, cpy_write_callback, args, kwds);
}
static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, PyObject *kwds) {
{"register_log", (PyCFunction) cpy_register_log, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
{"register_init", (PyCFunction) cpy_register_init, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
{"register_config", (PyCFunction) cpy_register_config, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
+ {"register_write", (PyCFunction) cpy_register_write, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
{"register_shutdown", (PyCFunction) cpy_register_shutdown, METH_VARARGS | METH_KEYWORDS, "This is an unhelpful text."},
{0, 0, 0, 0}
};