summaryrefslogtreecommitdiffstats
path: root/pysource.c
diff options
context:
space:
mode:
Diffstat (limited to 'pysource.c')
-rw-r--r--pysource.c166
1 files changed, 70 insertions, 96 deletions
diff --git a/pysource.c b/pysource.c
index f3a0663..413ab2c 100644
--- a/pysource.c
+++ b/pysource.c
@@ -4,153 +4,127 @@
typedef struct _PY_SOURCE_REC
{
- int once;
int tag;
+ GSList **tag_list;
int fd;
- GSList **container; /* "container" points to a list owned by a Script object */
- PyObject *handler;
+ PyObject *func;
PyObject *data;
} PY_SOURCE_REC;
-static PY_SOURCE_REC *py_source_new(GSList **list, int once, PyObject *handler, PyObject *data)
+static PY_SOURCE_REC *py_source_rec_new(GSList **tag_list, int fd, PyObject *func, PyObject *data)
{
PY_SOURCE_REC *rec;
rec = g_new0(PY_SOURCE_REC, 1);
- rec->once = once;
- rec->fd = -1;
- rec->handler = handler;
+ rec->tag_list = tag_list;
+ rec->fd = fd;
+ rec->func = func;
rec->data = data;
- rec->container = list;
- Py_INCREF(handler);
- Py_XINCREF(data);
+ Py_INCREF(func);
+ Py_XINCREF(data);
return rec;
}
+static int py_remove_tag(GSList **list, int handle)
+{
+ GSList *node;
+
+ node = g_slist_find(*list, GINT_TO_POINTER(handle));
+ if (!node)
+ return 0;
+
+ *list = g_slist_delete_link(*list, node);
+
+ return 1;
+}
+
static void py_source_destroy(PY_SOURCE_REC *rec)
{
- g_source_remove(rec->tag);
- Py_DECREF(rec->handler);
+ g_return_if_fail(py_remove_tag(rec->tag_list, rec->tag) == 1);
+ Py_DECREF(rec->func);
Py_XDECREF(rec->data);
g_free(rec);
}
-static int py_source_proxy(PY_SOURCE_REC *rec)
+static int py_handle_ret(PyObject *ret)
{
- char args[3] = {0,0,0};
- int fd;
- PyObject *ret;
- PyObject *handler, *data;
-
- /* Copy data out of the rec (there's not much). The rec may be deleted in
- the if block below or by the Python code executed. Protect handler & data
- with INCREF.
- */
+ int res;
- fd = rec->fd;
- handler = rec->handler;
- data = rec->data;
- Py_INCREF(handler);
- Py_XINCREF(data);
-
- if (rec->once)
+ if (!ret)
{
- *rec->container = g_slist_remove(*rec->container, rec);
- py_source_destroy(rec);
+ PyErr_Print();
+ res = FALSE;
+ }
+ else
+ {
+ res = PyObject_IsTrue(ret);
+ Py_DECREF(ret);
}
- /* call python function with fd and/or data if available.
- IO handler will be called with either "iO" or "i".
- Timeout with "O" or "".
- */
+ return res;
+}
- if (fd >= 0)
- {
- /* IO handler */
- args[0] = 'i';
- if (data)
- args[1] = 'O';
+static int py_timeout_proxy(PY_SOURCE_REC *rec)
+{
+ PyObject *ret;
- ret = PyObject_CallFunction(handler, args, fd, data);
- }
+ g_return_val_if_fail(rec != NULL, FALSE);
+
+ if (rec->data)
+ ret = PyObject_CallFunction(rec->func, "O", rec->data);
else
- {
- /* Timeout handler */
- if (data)
- args[0] = 'O';
+ ret = PyObject_CallFunction(rec->func, "");
- ret = PyObject_CallFunction(handler, args, data);
- }
+ return py_handle_ret(ret);
+}
- if (!ret)
- PyErr_Print();
+static int py_io_proxy(GIOChannel *src, GIOCondition condition, PY_SOURCE_REC *rec)
+{
+ PyObject *ret;
+
+ g_return_val_if_fail(rec != NULL, FALSE);
+
+ if (rec->data)
+ ret = PyObject_CallFunction(rec->func, "iiO", rec->fd, condition, rec->data);
else
- Py_DECREF(ret);
+ ret = PyObject_CallFunction(rec->func, "ii", rec->fd, condition);
- Py_DECREF(handler);
- Py_XDECREF(data);
-
- return 1;
+ return py_handle_ret(ret);
}
-int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data, int once)
+int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data)
{
PY_SOURCE_REC *rec;
g_return_val_if_fail(func != NULL, -1);
- rec = py_source_new(list, once, func, data);
- rec->tag = g_timeout_add(msecs, (GSourceFunc)py_source_proxy, rec);
-
- *list = g_slist_append(*list, rec);
-
+ rec = py_source_rec_new(list, -1, func, data);
+ rec->tag = g_timeout_add_full(G_PRIORITY_DEFAULT, msecs,
+ (GSourceFunc)py_timeout_proxy, rec,
+ (GDestroyNotify)py_source_destroy);
+
+ *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag));
+
return rec->tag;
}
-int pysource_input_add_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data, int once)
+int pysource_io_add_watch_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data)
{
PY_SOURCE_REC *rec;
GIOChannel *channel;
g_return_val_if_fail(func != NULL, 1);
- rec = py_source_new(list, once, func, data);
- rec->fd = fd;
+
+ rec = py_source_rec_new(list, fd, func, data);
channel = g_io_channel_unix_new(fd);
- rec->tag = g_input_add(channel, cond, (GInputFunction)py_source_proxy, rec);
+ rec->tag = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
+ (GIOFunc)py_io_proxy, rec,
+ (GDestroyNotify)py_source_destroy);
g_io_channel_unref(channel);
- *list = g_slist_append(*list, rec);
+ *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag));
return rec->tag;
}
-
-int pysource_remove_tag(GSList **list, int handle)
-{
- GSList *node;
-
- for (node = *list; node != NULL; node = node->next)
- {
- PY_SOURCE_REC *rec = node->data;
-
- if (rec->tag == handle)
- {
- py_source_destroy(rec);
- *list = g_slist_delete_link(*list, node);
-
- return 1;
- }
- }
-
- return 0;
-}
-
-void pysource_remove_list(GSList *list)
-{
- GSList *node;
-
- for (node = list; node != NULL; node = node->next)
- py_source_destroy(node->data);
-}
-