tevent: release 0.16.1
[Samba.git] / lib / tevent / pytevent.c
blobbbe29f6c693ba2295e3b3f2ab0e65cd0357e56cf
1 /*
2 Unix SMB/CIFS implementation.
3 Python bindings for tevent
5 Copyright (C) Jelmer Vernooij 2010
7 ** NOTE! The following LGPL license applies to the tevent
8 ** library. This does NOT imply that all of Samba is released
9 ** under the LGPL
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 3 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "lib/replace/system/python.h"
26 #include "replace.h"
27 #include <tevent.h>
30 /* discard signature of 'func' in favour of 'target_sig' */
31 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
33 void init_tevent(void);
35 typedef struct {
36 PyObject_HEAD
37 struct tevent_context *ev;
38 } TeventContext_Object;
40 typedef struct {
41 PyObject_HEAD
42 struct tevent_queue *queue;
43 } TeventQueue_Object;
45 typedef struct {
46 PyObject_HEAD
47 struct tevent_req *req;
48 } TeventReq_Object;
50 typedef struct {
51 PyObject_HEAD
52 struct tevent_signal *signal;
53 } TeventSignal_Object;
55 typedef struct {
56 PyObject_HEAD
57 struct tevent_timer *timer;
58 PyObject *callback;
59 } TeventTimer_Object;
61 typedef struct {
62 PyObject_HEAD
63 struct tevent_fd *fd;
64 } TeventFd_Object;
66 static PyTypeObject TeventContext_Type;
67 static PyTypeObject TeventReq_Type;
68 static PyTypeObject TeventQueue_Type;
69 static PyTypeObject TeventSignal_Type;
70 static PyTypeObject TeventTimer_Type;
71 static PyTypeObject TeventFd_Type;
73 static PyObject *py_tevent_context_reinitialise(TeventContext_Object *self,
74 PyObject *Py_UNUSED(ignored))
76 int ret = tevent_re_initialise(self->ev);
77 if (ret != 0) {
78 PyErr_SetNone(PyExc_RuntimeError);
79 return NULL;
81 Py_RETURN_NONE;
84 static PyObject *py_tevent_queue_stop(TeventQueue_Object *self,
85 PyObject *Py_UNUSED(ignored))
87 tevent_queue_stop(self->queue);
88 Py_RETURN_NONE;
91 static PyObject *py_tevent_queue_start(TeventQueue_Object *self,
92 PyObject *Py_UNUSED(ignored))
94 tevent_queue_start(self->queue);
95 Py_RETURN_NONE;
98 static void py_queue_trigger(struct tevent_req *req, void *private_data)
100 PyObject *callback = private_data, *ret;
102 ret = PyObject_CallFunction(callback, discard_const_p(char, ""));
103 Py_XDECREF(ret);
106 static PyObject *py_tevent_queue_add(TeventQueue_Object *self, PyObject *args)
108 TeventContext_Object *py_ev;
109 TeventReq_Object *py_req;
110 PyObject *trigger;
111 bool ret;
113 if (!PyArg_ParseTuple(args, "O!O!O",
114 &TeventContext_Type, &py_ev,
115 &TeventReq_Type, &py_req,
116 &trigger))
117 return NULL;
119 Py_INCREF(trigger);
121 ret = tevent_queue_add(self->queue, py_ev->ev, py_req->req,
122 py_queue_trigger, trigger);
123 if (!ret) {
124 PyErr_SetString(PyExc_RuntimeError, "queue add failed");
125 Py_DECREF(trigger);
126 return NULL;
129 Py_RETURN_NONE;
132 static PyMethodDef py_tevent_queue_methods[] = {
133 { "stop", (PyCFunction)py_tevent_queue_stop,
134 METH_NOARGS,
135 "S.stop()" },
136 { "start", (PyCFunction)py_tevent_queue_start,
137 METH_NOARGS,
138 "S.start()" },
139 { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS,
140 "S.add(ctx, req, trigger, baton)" },
141 {0},
144 static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args)
146 /* FIXME */
148 Py_RETURN_NONE;
151 static PyObject *py_tevent_context_loop_wait(TeventContext_Object *self,
152 PyObject *Py_UNUSED(ignored))
154 if (tevent_loop_wait(self->ev) != 0) {
155 PyErr_SetNone(PyExc_RuntimeError);
156 return NULL;
158 Py_RETURN_NONE;
161 static PyObject *py_tevent_context_loop_once(TeventContext_Object *self,
162 PyObject *Py_UNUSED(ignored))
164 if (tevent_loop_once(self->ev) != 0) {
165 PyErr_SetNone(PyExc_RuntimeError);
166 return NULL;
168 Py_RETURN_NONE;
171 static void py_tevent_signal_handler(struct tevent_context *ev,
172 struct tevent_signal *se,
173 int signum,
174 int count,
175 void *siginfo,
176 void *private_data)
178 PyObject *callback = (PyObject *)private_data, *ret;
180 ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count);
181 Py_XDECREF(ret);
184 static void py_tevent_signal_dealloc(TeventSignal_Object *self)
186 talloc_free(self->signal);
187 PyObject_Del(self);
190 static PyTypeObject TeventSignal_Type = {
191 .tp_name = "tevent.Signal",
192 .tp_basicsize = sizeof(TeventSignal_Object),
193 .tp_dealloc = (destructor)py_tevent_signal_dealloc,
194 .tp_flags = Py_TPFLAGS_DEFAULT,
197 static PyObject *py_tevent_context_add_signal(TeventContext_Object *self, PyObject *args)
199 int signum, sa_flags;
200 PyObject *handler;
201 struct tevent_signal *sig;
202 TeventSignal_Object *ret;
204 if (!PyArg_ParseTuple(args, "iiO", &signum, &sa_flags, &handler))
205 return NULL;
207 Py_INCREF(handler);
208 sig = tevent_add_signal(self->ev, NULL, signum, sa_flags,
209 py_tevent_signal_handler, handler);
211 ret = PyObject_New(TeventSignal_Object, &TeventSignal_Type);
212 if (ret == NULL) {
213 PyErr_NoMemory();
214 talloc_free(sig);
215 return NULL;
218 ret->signal = sig;
220 return (PyObject *)ret;
223 static void py_timer_handler(struct tevent_context *ev,
224 struct tevent_timer *te,
225 struct timeval current_time,
226 void *private_data)
228 TeventTimer_Object *self = private_data;
229 PyObject *ret;
231 ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te);
232 if (ret == NULL) {
233 /* No Python stack to propagate exception to; just print traceback */
234 PyErr_PrintEx(0);
236 Py_XDECREF(ret);
239 static void py_tevent_timer_dealloc(TeventTimer_Object *self)
241 if (self->timer) {
242 talloc_free(self->timer);
244 Py_CLEAR(self->callback);
245 PyObject_Del(self);
248 static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg)
250 Py_VISIT(self->callback);
251 return 0;
254 static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self,
255 PyObject *Py_UNUSED(ignored))
257 return PyBool_FromLong(self->timer != NULL);
260 struct PyGetSetDef py_tevent_timer_getset[] = {
262 .name = discard_const_p(char, "active"),
263 .get = (getter)py_tevent_timer_get_active,
264 .doc = discard_const_p(char, "true if the timer is scheduled to run"),
266 {0},
269 static PyTypeObject TeventTimer_Type = {
270 .tp_name = "tevent.Timer",
271 .tp_basicsize = sizeof(TeventTimer_Object),
272 .tp_dealloc = (destructor)py_tevent_timer_dealloc,
273 .tp_traverse = (traverseproc)py_tevent_timer_traverse,
274 .tp_getset = py_tevent_timer_getset,
275 .tp_flags = Py_TPFLAGS_DEFAULT,
278 struct TeventTimer_Object_ref {
279 TeventTimer_Object *obj;
282 static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref)
284 ref->obj->timer = NULL;
285 Py_CLEAR(ref->obj);
286 return 0;
289 static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self,
290 struct timeval next_event,
291 PyObject *callback)
293 /* Ownership notes:
295 * There are 5 pieces in play; two tevent contexts and 3 Python objects:
296 * - The tevent timer
297 * - The tevent context
298 * - The Python context -- "self"
299 * - The Python timer (TeventTimer_Object) -- "ret"
300 * - The Python callback function -- "callback"
302 * We only use the Python context for getting the tevent context,
303 * afterwards it can be destroyed.
305 * The tevent context owns the tevent timer.
307 * The tevent timer holds a reference to the Python timer, so the Python
308 * timer must always outlive the tevent timer.
309 * The Python timer has a pointer to the tevent timer; a destructor is
310 * used to set this to NULL when the tevent timer is deallocated.
312 * The tevent timer can be deallocated in these cases:
313 * 1) when the context is destroyed
314 * 2) after the event fires
315 * Posssibly, API might be added to cancel (free the tevent timer).
317 * The Python timer holds a reference to the callback.
319 TeventTimer_Object *ret;
320 struct TeventTimer_Object_ref *ref;
322 ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type);
323 if (ret == NULL) {
324 PyErr_NoMemory();
325 return NULL;
327 Py_INCREF(callback);
328 ret->callback = callback;
329 ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler,
330 ret);
331 if (ret->timer == NULL) {
332 Py_DECREF(ret);
333 PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer");
334 return NULL;
336 ref = talloc(ret->timer, struct TeventTimer_Object_ref);
337 if (ref == NULL) {
338 talloc_free(ret->timer);
339 Py_DECREF(ret);
340 PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer");
341 return NULL;
343 Py_INCREF(ret);
344 ref->obj = ret;
346 talloc_set_destructor(ref, TeventTimer_Object_ref_destructor);
348 return (PyObject *)ret;
351 static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args)
353 struct timeval next_event;
354 PyObject *callback;
355 double secs, usecs;
356 if (!PyArg_ParseTuple(args, "dO", &secs, &callback)){
357 return NULL;
359 next_event.tv_sec = secs;
360 usecs = (secs - next_event.tv_sec) * 1000000.0;
361 next_event.tv_usec = usecs;
362 return py_tevent_context_add_timer_internal(self, next_event, callback);
365 static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args)
367 struct timeval next_event;
368 double offset;
369 int seconds;
370 PyObject *callback;
371 if (!PyArg_ParseTuple(args, "dO", &offset, &callback))
372 return NULL;
374 seconds = offset;
375 offset -= seconds;
376 next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000));
377 return py_tevent_context_add_timer_internal(self, next_event, callback);
380 static void py_fd_handler(struct tevent_context *ev,
381 struct tevent_fd *fde,
382 uint16_t flags,
383 void *private_data)
385 PyObject *callback = private_data, *ret;
387 ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags);
388 Py_XDECREF(ret);
391 static void py_tevent_fp_dealloc(TeventFd_Object *self)
393 talloc_free(self->fd);
394 PyObject_Del(self);
397 static PyTypeObject TeventFd_Type = {
398 .tp_name = "tevent.Fd",
399 .tp_basicsize = sizeof(TeventFd_Object),
400 .tp_dealloc = (destructor)py_tevent_fp_dealloc,
401 .tp_flags = Py_TPFLAGS_DEFAULT,
404 static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args)
406 int fd, flags;
407 PyObject *handler;
408 struct tevent_fd *tfd;
409 TeventFd_Object *ret;
411 if (!PyArg_ParseTuple(args, "iiO", &fd, &flags, &handler))
412 return NULL;
414 tfd = tevent_add_fd(self->ev, NULL, fd, flags, py_fd_handler, handler);
415 if (tfd == NULL) {
416 PyErr_SetNone(PyExc_RuntimeError);
417 return NULL;
420 ret = PyObject_New(TeventFd_Object, &TeventFd_Type);
421 if (ret == NULL) {
422 talloc_free(tfd);
423 return NULL;
425 ret->fd = tfd;
427 return (PyObject *)ret;
430 static PyMethodDef py_tevent_context_methods[] = {
431 { "reinitialise", (PyCFunction)py_tevent_context_reinitialise,
432 METH_NOARGS,
433 "S.reinitialise()" },
434 { "wakeup_send", (PyCFunction)py_tevent_context_wakeup_send,
435 METH_VARARGS, "S.wakeup_send(wakeup_time) -> req" },
436 { "loop_wait", (PyCFunction)py_tevent_context_loop_wait,
437 METH_NOARGS, "S.loop_wait()" },
438 { "loop_once", (PyCFunction)py_tevent_context_loop_once,
439 METH_NOARGS, "S.loop_once()" },
440 { "add_signal", (PyCFunction)py_tevent_context_add_signal,
441 METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" },
442 { "add_timer", (PyCFunction)py_tevent_context_add_timer,
443 METH_VARARGS, "S.add_timer(next_event, handler) -> timer" },
444 { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset,
445 METH_VARARGS, "S.add_timer_offset(offset_seconds, handler) -> timer" },
446 { "add_fd", (PyCFunction)py_tevent_context_add_fd,
447 METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" },
448 {0},
451 static PyObject *py_tevent_req_wakeup_recv(PyObject *self,
452 PyObject *Py_UNUSED(ignored))
454 /* FIXME */
455 Py_RETURN_NONE;
458 static PyObject *py_tevent_req_received(PyObject *self,
459 PyObject *Py_UNUSED(ignored))
461 /* FIXME */
462 Py_RETURN_NONE;
465 static PyObject *py_tevent_req_is_error(PyObject *self,
466 PyObject *Py_UNUSED(ignored))
468 /* FIXME */
469 Py_RETURN_NONE;
472 static PyObject *py_tevent_req_poll(PyObject *self,
473 PyObject *Py_UNUSED(ignored))
475 /* FIXME */
476 Py_RETURN_NONE;
479 static PyObject *py_tevent_req_is_in_progress(PyObject *self,
480 PyObject *Py_UNUSED(ignored))
482 /* FIXME */
483 Py_RETURN_NONE;
486 static PyGetSetDef py_tevent_req_getsetters[] = {
488 .name = discard_const_p(char, "in_progress"),
489 .get = (getter)py_tevent_req_is_in_progress,
490 .doc = discard_const_p(char, "Whether the request is in progress"),
495 static PyObject *py_tevent_req_post(PyObject *self, PyObject *args)
497 /* FIXME */
498 Py_RETURN_NONE;
501 static PyObject *py_tevent_req_set_error(PyObject *self, PyObject *args)
503 /* FIXME */
504 Py_RETURN_NONE;
507 static PyObject *py_tevent_req_done(PyObject *self,
508 PyObject *Py_UNUSED(ignored))
510 /* FIXME */
511 Py_RETURN_NONE;
514 static PyObject *py_tevent_req_notify_callback(PyObject *self,
515 PyObject *Py_UNUSED(ignored))
517 /* FIXME */
518 Py_RETURN_NONE;
521 static PyObject *py_tevent_req_set_endtime(PyObject *self, PyObject *args)
523 /* FIXME */
524 Py_RETURN_NONE;
527 static PyObject *py_tevent_req_cancel(TeventReq_Object *self,
528 PyObject *Py_UNUSED(ignored))
530 if (!tevent_req_cancel(self->req)) {
531 PyErr_SetNone(PyExc_RuntimeError);
532 return NULL;
534 Py_RETURN_NONE;
537 static PyMethodDef py_tevent_req_methods[] = {
538 { "wakeup_recv", (PyCFunction)py_tevent_req_wakeup_recv,
539 METH_NOARGS,
540 "Wakeup received" },
541 { "received", (PyCFunction)py_tevent_req_received,
542 METH_NOARGS,
543 "Receive finished" },
544 { "is_error", (PyCFunction)py_tevent_req_is_error, METH_NOARGS,
545 "is_error() -> (error, state)" },
546 { "poll", (PyCFunction)py_tevent_req_poll, METH_VARARGS,
547 "poll(ctx)" },
548 { "post", (PyCFunction)py_tevent_req_post, METH_VARARGS,
549 "post(ctx) -> req" },
550 { "set_error", (PyCFunction)py_tevent_req_set_error, METH_VARARGS,
551 "set_error(error)" },
552 { "done", (PyCFunction)py_tevent_req_done, METH_NOARGS,
553 "done()" },
554 { "notify_callback", (PyCFunction)py_tevent_req_notify_callback,
555 METH_NOARGS, "notify_callback()" },
556 { "set_endtime", (PyCFunction)py_tevent_req_set_endtime,
557 METH_VARARGS, "set_endtime(ctx, endtime)" },
558 { "cancel", (PyCFunction)py_tevent_req_cancel,
559 METH_NOARGS, "cancel()" },
563 static void py_tevent_req_dealloc(TeventReq_Object *self)
565 talloc_free(self->req);
566 PyObject_DEL(self);
569 static PyTypeObject TeventReq_Type = {
570 .tp_name = "tevent.Request",
571 .tp_basicsize = sizeof(TeventReq_Object),
572 .tp_methods = py_tevent_req_methods,
573 .tp_dealloc = (destructor)py_tevent_req_dealloc,
574 .tp_getset = py_tevent_req_getsetters,
575 /* FIXME: .tp_new = py_tevent_req_new, */
578 static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self,
579 PyObject *Py_UNUSED(ignored))
581 return PyLong_FromLong(tevent_queue_length(self->queue));
584 static PyGetSetDef py_tevent_queue_getsetters[] = {
586 .name = discard_const_p(char, "length"),
587 .get = (getter)py_tevent_queue_get_length,
588 .doc = discard_const_p(char, "The number of elements in the queue."),
590 {0},
593 static void py_tevent_queue_dealloc(TeventQueue_Object *self)
595 talloc_free(self->queue);
596 PyObject_Del(self);
599 static PyTypeObject TeventQueue_Type = {
600 .tp_name = "tevent.Queue",
601 .tp_basicsize = sizeof(TeventQueue_Object),
602 .tp_dealloc = (destructor)py_tevent_queue_dealloc,
603 .tp_flags = Py_TPFLAGS_DEFAULT,
604 .tp_getset = py_tevent_queue_getsetters,
605 .tp_methods = py_tevent_queue_methods,
608 static PyObject *py_tevent_context_signal_support(PyObject *_self,
609 PyObject *Py_UNUSED(ignored))
611 TeventContext_Object *self = (TeventContext_Object *)_self;
612 return PyBool_FromLong(tevent_signal_support(self->ev));
615 static PyGetSetDef py_tevent_context_getsetters[] = {
617 .name = discard_const_p(char, "signal_support"),
618 .get = PY_DISCARD_FUNC_SIG(getter,
619 py_tevent_context_signal_support),
620 .doc = discard_const_p(char, "if this platform and tevent context support signal handling"),
625 static void py_tevent_context_dealloc(TeventContext_Object *self)
627 talloc_free(self->ev);
628 PyObject_Del(self);
631 static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
633 const char * const kwnames[] = { "name", NULL };
634 char *name = NULL;
635 struct tevent_context *ev;
636 TeventContext_Object *ret;
638 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name))
639 return NULL;
641 if (name == NULL) {
642 ev = tevent_context_init(NULL);
643 } else {
644 ev = tevent_context_init_byname(NULL, name);
647 if (ev == NULL) {
648 PyErr_SetNone(PyExc_RuntimeError);
649 return NULL;
652 ret = PyObject_New(TeventContext_Object, type);
653 if (ret == NULL) {
654 PyErr_NoMemory();
655 talloc_free(ev);
656 return NULL;
659 ret->ev = ev;
660 return (PyObject *)ret;
663 static PyTypeObject TeventContext_Type = {
664 .tp_name = "tevent.Context",
665 .tp_new = py_tevent_context_new,
666 .tp_basicsize = sizeof(TeventContext_Object),
667 .tp_dealloc = (destructor)py_tevent_context_dealloc,
668 .tp_methods = py_tevent_context_methods,
669 .tp_getset = py_tevent_context_getsetters,
670 .tp_flags = Py_TPFLAGS_DEFAULT,
673 static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
675 char *backend_name;
676 if (!PyArg_ParseTuple(args, "s", &backend_name))
677 return NULL;
679 tevent_set_default_backend(backend_name);
681 Py_RETURN_NONE;
684 static PyObject *py_backend_list(PyObject *self,
685 PyObject *Py_UNUSED(ignored))
687 PyObject *ret = NULL;
688 PyObject *string = NULL;
689 int i, result;
690 const char **backends = NULL;
692 ret = PyList_New(0);
693 if (ret == NULL) {
694 return NULL;
697 backends = tevent_backend_list(NULL);
698 if (backends == NULL) {
699 PyErr_SetNone(PyExc_RuntimeError);
700 goto err;
702 for (i = 0; backends[i]; i++) {
703 string = PyUnicode_FromString(backends[i]);
704 if (!string) {
705 goto err;
707 result = PyList_Append(ret, string);
708 if (result) {
709 goto err;
711 Py_DECREF(string);
712 string = NULL;
715 talloc_free(backends);
717 return ret;
719 err:
720 Py_XDECREF(ret);
721 Py_XDECREF(string);
722 talloc_free(backends);
723 return NULL;
726 static PyMethodDef tevent_methods[] = {
727 { "set_default_backend", (PyCFunction)py_set_default_backend,
728 METH_VARARGS, "set_default_backend(backend)" },
729 { "backend_list", (PyCFunction)py_backend_list,
730 METH_NOARGS, "backend_list() -> list" },
731 {0},
734 #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
736 static struct PyModuleDef moduledef = {
737 PyModuleDef_HEAD_INIT,
738 .m_name = "_tevent",
739 .m_doc = MODULE_DOC,
740 .m_size = -1,
741 .m_methods = tevent_methods,
744 PyObject * module_init(void);
745 PyObject * module_init(void)
747 PyObject *m;
749 if (PyType_Ready(&TeventContext_Type) < 0)
750 return NULL;
752 if (PyType_Ready(&TeventQueue_Type) < 0)
753 return NULL;
755 if (PyType_Ready(&TeventReq_Type) < 0)
756 return NULL;
758 if (PyType_Ready(&TeventSignal_Type) < 0)
759 return NULL;
761 if (PyType_Ready(&TeventTimer_Type) < 0)
762 return NULL;
764 if (PyType_Ready(&TeventFd_Type) < 0)
765 return NULL;
767 m = PyModule_Create(&moduledef);
768 if (m == NULL)
769 return NULL;
771 Py_INCREF(&TeventContext_Type);
772 PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type);
774 Py_INCREF(&TeventQueue_Type);
775 PyModule_AddObject(m, "Queue", (PyObject *)&TeventQueue_Type);
777 Py_INCREF(&TeventReq_Type);
778 PyModule_AddObject(m, "Request", (PyObject *)&TeventReq_Type);
780 Py_INCREF(&TeventSignal_Type);
781 PyModule_AddObject(m, "Signal", (PyObject *)&TeventSignal_Type);
783 Py_INCREF(&TeventTimer_Type);
784 PyModule_AddObject(m, "Timer", (PyObject *)&TeventTimer_Type);
786 Py_INCREF(&TeventFd_Type);
787 PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type);
789 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
791 return m;
794 PyMODINIT_FUNC PyInit__tevent(void);
795 PyMODINIT_FUNC PyInit__tevent(void)
797 return module_init();