LCOV - code coverage report
Current view: top level - lib/tevent - pytevent.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 125 301 41.5 %
Date: 2024-06-13 04:01:37 Functions: 18 54 33.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Python bindings for tevent
       4             : 
       5             :    Copyright (C) Jelmer Vernooij 2010
       6             : 
       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
      10             : 
      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.
      15             : 
      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.
      20             : 
      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/>.
      23             : */
      24             : 
      25             : #include <Python.h>
      26             : #include "replace.h"
      27             : #include <tevent.h>
      28             : 
      29             : #if PY_MAJOR_VERSION >= 3
      30             : #define PyLong_FromLong PyLong_FromLong
      31             : #endif
      32             : 
      33             : /* discard signature of 'func' in favour of 'target_sig' */
      34             : #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
      35             : 
      36             : void init_tevent(void);
      37             : 
      38             : typedef struct {
      39             :         PyObject_HEAD
      40             :         struct tevent_context *ev;
      41             : } TeventContext_Object;
      42             : 
      43             : typedef struct {
      44             :         PyObject_HEAD
      45             :         struct tevent_queue *queue;
      46             : } TeventQueue_Object;
      47             : 
      48             : typedef struct {
      49             :         PyObject_HEAD
      50             :         struct tevent_req *req;
      51             : } TeventReq_Object;
      52             : 
      53             : typedef struct {
      54             :         PyObject_HEAD
      55             :         struct tevent_signal *signal;
      56             : } TeventSignal_Object;
      57             : 
      58             : typedef struct {
      59             :         PyObject_HEAD
      60             :         struct tevent_timer *timer;
      61             :         PyObject *callback;
      62             : } TeventTimer_Object;
      63             : 
      64             : typedef struct {
      65             :         PyObject_HEAD
      66             :         struct tevent_fd *fd;
      67             : } TeventFd_Object;
      68             : 
      69             : static PyTypeObject TeventContext_Type;
      70             : static PyTypeObject TeventReq_Type;
      71             : static PyTypeObject TeventQueue_Type;
      72             : static PyTypeObject TeventSignal_Type;
      73             : static PyTypeObject TeventTimer_Type;
      74             : static PyTypeObject TeventFd_Type;
      75             : 
      76           0 : static int py_context_init(struct tevent_context *ev)
      77             : {
      78             :         /* FIXME */
      79           0 :         return 0;
      80             : }
      81             : 
      82           0 : static struct tevent_fd *py_add_fd(struct tevent_context *ev,
      83             :                                     TALLOC_CTX *mem_ctx,
      84             :                                     int fd, uint16_t flags,
      85             :                                     tevent_fd_handler_t handler,
      86             :                                     void *private_data,
      87             :                                     const char *handler_name,
      88             :                                     const char *location)
      89             : {
      90             :         /* FIXME */
      91           0 :         return NULL;
      92             : }
      93             : 
      94           0 : static void py_set_fd_close_fn(struct tevent_fd *fde,
      95             :                                 tevent_fd_close_fn_t close_fn)
      96             : {
      97             :         /* FIXME */
      98           0 : }
      99             : 
     100           0 : static uint16_t py_get_fd_flags(struct tevent_fd *fde)
     101             : {
     102             :         /* FIXME */
     103           0 :         return 0;
     104             : }
     105             : 
     106           0 : static void py_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
     107             : {
     108             :         /* FIXME */
     109           0 : }
     110             : 
     111             : /* timed_event functions */
     112           0 : static struct tevent_timer *py_add_timer(struct tevent_context *ev,
     113             :                                           TALLOC_CTX *mem_ctx,
     114             :                                           struct timeval next_event,
     115             :                                           tevent_timer_handler_t handler,
     116             :                                           void *private_data,
     117             :                                           const char *handler_name,
     118             :                                           const char *location)
     119             : {
     120             :         /* FIXME */
     121           0 :         return NULL;
     122             : }
     123             : 
     124             : /* immediate event functions */
     125           0 : static void py_schedule_immediate(struct tevent_immediate *im,
     126             :                                    struct tevent_context *ev,
     127             :                                    tevent_immediate_handler_t handler,
     128             :                                    void *private_data,
     129             :                                    const char *handler_name,
     130             :                                    const char *location)
     131             : {
     132             :         /* FIXME */
     133           0 : }
     134             : 
     135             : /* signal functions */
     136           0 : static struct tevent_signal *py_add_signal(struct tevent_context *ev,
     137             :                                             TALLOC_CTX *mem_ctx,
     138             :                                             int signum, int sa_flags,
     139             :                                             tevent_signal_handler_t handler,
     140             :                                             void *private_data,
     141             :                                             const char *handler_name,
     142             :                                             const char *location)
     143             : {
     144             :         /* FIXME */
     145           0 :         return NULL;
     146             : }
     147             : 
     148             : /* loop functions */
     149           0 : static int py_loop_once(struct tevent_context *ev, const char *location)
     150             : {
     151             :         /* FIXME */
     152           0 :         return 0;
     153             : }
     154             : 
     155           0 : static int py_loop_wait(struct tevent_context *ev, const char *location)
     156             : {
     157             :         /* FIXME */
     158           0 :         return 0;
     159             : }
     160             : 
     161             : const static struct tevent_ops py_tevent_ops = {
     162             :         .context_init = py_context_init,
     163             :         .add_fd = py_add_fd,
     164             :         .set_fd_close_fn = py_set_fd_close_fn,
     165             :         .get_fd_flags = py_get_fd_flags,
     166             :         .set_fd_flags = py_set_fd_flags,
     167             :         .add_timer = py_add_timer,
     168             :         .schedule_immediate = py_schedule_immediate,
     169             :         .add_signal = py_add_signal,
     170             :         .loop_wait = py_loop_wait,
     171             :         .loop_once = py_loop_once,
     172             : };
     173             : 
     174           0 : static PyObject *py_register_backend(PyObject *self, PyObject *args)
     175             : {
     176             :         PyObject *name, *py_backend;
     177             : 
     178           0 :         if (!PyArg_ParseTuple(args, "O", &py_backend))
     179           0 :                 return NULL;
     180             : 
     181           0 :         name = PyObject_GetAttrString(py_backend, "name");
     182           0 :         if (name == NULL) {
     183           0 :                 PyErr_SetNone(PyExc_AttributeError);
     184           0 :                 return NULL;
     185             :         }
     186             : 
     187           0 :         if (!PyUnicode_Check(name)) {
     188           0 :                 PyErr_SetNone(PyExc_TypeError);
     189           0 :                 Py_DECREF(name);
     190           0 :                 return NULL;
     191             :         }
     192             : 
     193           0 :         if (!tevent_register_backend(PyUnicode_AsUTF8(name), &py_tevent_ops)) { /* FIXME: What to do with backend */
     194           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     195           0 :                 Py_DECREF(name);
     196           0 :                 return NULL;
     197             :         }
     198             : 
     199           0 :         Py_DECREF(name);
     200             : 
     201           0 :         Py_RETURN_NONE;
     202             : }
     203             : 
     204           1 : static PyObject *py_tevent_context_reinitialise(TeventContext_Object *self,
     205             :                 PyObject *Py_UNUSED(ignored))
     206             : {
     207           1 :         int ret = tevent_re_initialise(self->ev);
     208           1 :         if (ret != 0) {
     209           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     210           0 :                 return NULL;
     211             :         }
     212           1 :         Py_RETURN_NONE;
     213             : }
     214             : 
     215           0 : static PyObject *py_tevent_queue_stop(TeventQueue_Object *self,
     216             :                 PyObject *Py_UNUSED(ignored))
     217             : {
     218           0 :         tevent_queue_stop(self->queue);
     219           0 :         Py_RETURN_NONE;
     220             : }
     221             : 
     222           0 : static PyObject *py_tevent_queue_start(TeventQueue_Object *self,
     223             :                 PyObject *Py_UNUSED(ignored))
     224             : {
     225           0 :         tevent_queue_start(self->queue);
     226           0 :         Py_RETURN_NONE;
     227             : }
     228             : 
     229           0 : static void py_queue_trigger(struct tevent_req *req, void *private_data)
     230             : {
     231           0 :         PyObject *callback = private_data, *ret;
     232             : 
     233           0 :         ret = PyObject_CallFunction(callback, discard_const_p(char, ""));
     234           0 :         Py_XDECREF(ret);
     235           0 : }
     236             : 
     237           0 : static PyObject *py_tevent_queue_add(TeventQueue_Object *self, PyObject *args)
     238             : {
     239             :         TeventContext_Object *py_ev;
     240             :         TeventReq_Object *py_req;
     241             :         PyObject *trigger;
     242             :         bool ret;
     243             : 
     244           0 :         if (!PyArg_ParseTuple(args, "O!O!O", 
     245             :                                                   &TeventContext_Type, &py_ev,
     246             :                                                   &TeventReq_Type, &py_req,
     247             :                                                   &trigger))
     248           0 :                 return NULL;
     249             : 
     250           0 :         Py_INCREF(trigger);
     251             : 
     252           0 :         ret = tevent_queue_add(self->queue, py_ev->ev, py_req->req,
     253             :                                                    py_queue_trigger, trigger);
     254           0 :         if (!ret) {
     255           0 :                 PyErr_SetString(PyExc_RuntimeError, "queue add failed");
     256           0 :                 Py_DECREF(trigger);
     257           0 :                 return NULL;
     258             :         }
     259             : 
     260           0 :         Py_RETURN_NONE;
     261             : }
     262             : 
     263             : static PyMethodDef py_tevent_queue_methods[] = {
     264             :         { "stop", (PyCFunction)py_tevent_queue_stop,
     265             :                 METH_NOARGS,
     266             :                 "S.stop()" },
     267             :         { "start", (PyCFunction)py_tevent_queue_start,
     268             :                 METH_NOARGS,
     269             :                 "S.start()" },
     270             :         { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS,
     271             :                 "S.add(ctx, req, trigger, baton)" },
     272             :         {0},
     273             : };
     274             : 
     275           0 : static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args)
     276             : {
     277             :         /* FIXME */
     278             : 
     279           0 :         Py_RETURN_NONE;
     280             : }
     281             : 
     282           1 : static PyObject *py_tevent_context_loop_wait(TeventContext_Object *self,
     283             :                 PyObject *Py_UNUSED(ignored))
     284             : {
     285           1 :         if (tevent_loop_wait(self->ev) != 0) {
     286           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     287           0 :                 return NULL;
     288             :         }
     289           1 :         Py_RETURN_NONE;
     290             : }
     291             : 
     292           4 : static PyObject *py_tevent_context_loop_once(TeventContext_Object *self,
     293             :                 PyObject *Py_UNUSED(ignored))
     294             : {
     295           4 :         if (tevent_loop_once(self->ev) != 0) {
     296           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     297           0 :                 return NULL;
     298             :         }
     299           4 :         Py_RETURN_NONE;
     300             : }
     301             : 
     302           0 : static void py_tevent_signal_handler(struct tevent_context *ev,
     303             :                                         struct tevent_signal *se,
     304             :                                         int signum,
     305             :                                         int count,
     306             :                                         void *siginfo,
     307             :                                         void *private_data)
     308             : {
     309           0 :         PyObject *callback = (PyObject *)private_data, *ret;
     310             : 
     311           0 :         ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count);
     312           0 :         Py_XDECREF(ret);
     313           0 : }
     314             : 
     315           1 : static void py_tevent_signal_dealloc(TeventSignal_Object *self)
     316             : {
     317           1 :         talloc_free(self->signal);
     318           1 :         PyObject_Del(self);
     319           1 : }
     320             : 
     321             : static PyTypeObject TeventSignal_Type = {
     322             :         .tp_name = "tevent.Signal",
     323             :         .tp_basicsize = sizeof(TeventSignal_Object),
     324             :         .tp_dealloc = (destructor)py_tevent_signal_dealloc,
     325             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     326             : };
     327             : 
     328           1 : static PyObject *py_tevent_context_add_signal(TeventContext_Object *self, PyObject *args)
     329             : {
     330             :         int signum, sa_flags;
     331             :         PyObject *handler;
     332             :         struct tevent_signal *sig;
     333             :         TeventSignal_Object *ret;
     334             : 
     335           1 :         if (!PyArg_ParseTuple(args, "iiO", &signum, &sa_flags, &handler))
     336           0 :                 return NULL;
     337             : 
     338           1 :         Py_INCREF(handler);
     339           1 :         sig = tevent_add_signal(self->ev, NULL, signum, sa_flags,
     340             :                                                         py_tevent_signal_handler, handler);
     341             : 
     342           1 :         ret = PyObject_New(TeventSignal_Object, &TeventSignal_Type);
     343           1 :         if (ret == NULL) {
     344           0 :                 PyErr_NoMemory();
     345           0 :                 talloc_free(sig);
     346           0 :                 return NULL;
     347             :         }
     348             : 
     349           1 :         ret->signal = sig;
     350             : 
     351           1 :         return (PyObject *)ret;
     352             : }
     353             : 
     354           4 : static void py_timer_handler(struct tevent_context *ev,
     355             :                                        struct tevent_timer *te,
     356             :                                        struct timeval current_time,
     357             :                                        void *private_data)
     358             : {
     359           4 :         TeventTimer_Object *self = private_data;
     360             :         PyObject *ret;
     361             : 
     362           4 :         ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te);
     363           4 :         if (ret == NULL) {
     364             :                 /* No Python stack to propagate exception to; just print traceback */
     365           0 :                 PyErr_PrintEx(0);
     366             :         }
     367           4 :         Py_XDECREF(ret);
     368           4 : }
     369             : 
     370           5 : static void py_tevent_timer_dealloc(TeventTimer_Object *self)
     371             : {
     372           5 :         if (self->timer) {
     373           0 :                 talloc_free(self->timer);
     374             :         }
     375           5 :         Py_DECREF(self->callback);
     376           5 :         PyObject_Del(self);
     377           5 : }
     378             : 
     379           0 : static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg)
     380             : {
     381           0 :         Py_VISIT(self->callback);
     382           0 :         return 0;
     383             : }
     384             : 
     385           4 : static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self,
     386             :                         PyObject *Py_UNUSED(ignored))
     387             : {
     388           4 :         return PyBool_FromLong(self->timer != NULL);
     389             : }
     390             : 
     391             : struct PyGetSetDef py_tevent_timer_getset[] = {
     392             :         {
     393             :                 .name = discard_const_p(char, "active"),
     394             :                 .get = (getter)py_tevent_timer_get_active,
     395             :                 .doc = discard_const_p(char, "true if the timer is scheduled to run"),
     396             :         },
     397             :         {0},
     398             : };
     399             : 
     400             : static PyTypeObject TeventTimer_Type = {
     401             :         .tp_name = "tevent.Timer",
     402             :         .tp_basicsize = sizeof(TeventTimer_Object),
     403             :         .tp_dealloc = (destructor)py_tevent_timer_dealloc,
     404             :         .tp_traverse = (traverseproc)py_tevent_timer_traverse,
     405             :         .tp_getset = py_tevent_timer_getset,
     406             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     407             : };
     408             : 
     409             : struct TeventTimer_Object_ref {
     410             :         TeventTimer_Object *obj;
     411             : };
     412             : 
     413           5 : static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref)
     414             : {
     415           5 :         ref->obj->timer = NULL;
     416           5 :         Py_DECREF(ref->obj);
     417           5 :         return 0;
     418             : }
     419             : 
     420           5 : static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self,
     421             :                                                       struct timeval next_event,
     422             :                                                       PyObject *callback)
     423             : {
     424             :         /* Ownership notes:
     425             :          *
     426             :          * There are 5 pieces in play; two tevent contexts and 3 Python objects:
     427             :          * - The tevent timer
     428             :          * - The tevent context
     429             :          * - The Python context -- "self"
     430             :          * - The Python timer (TeventTimer_Object) -- "ret"
     431             :          * - The Python callback function -- "callback"
     432             :          *
     433             :          * We only use the Python context for getting the tevent context,
     434             :          * afterwards it can be destroyed.
     435             :          *
     436             :          * The tevent context owns the tevent timer.
     437             :          *
     438             :          * The tevent timer holds a reference to the Python timer, so the Python
     439             :          * timer must always outlive the tevent timer.
     440             :          * The Python timer has a pointer to the tevent timer; a destructor is
     441             :          * used to set this to NULL when the tevent timer is deallocated.
     442             :          *
     443             :          * The tevent timer can be deallocated in these cases:
     444             :          *  1) when the context is destroyed
     445             :          *  2) after the event fires
     446             :          *  Posssibly, API might be added to cancel (free the tevent timer).
     447             :          *
     448             :          * The Python timer holds a reference to the callback.
     449             :          */
     450             :         TeventTimer_Object *ret;
     451             :         struct TeventTimer_Object_ref *ref;
     452             : 
     453           5 :         ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type);
     454           5 :         if (ret == NULL) {
     455           0 :                 PyErr_NoMemory();
     456           0 :                 return NULL;
     457             :         }
     458           5 :         Py_INCREF(callback);
     459           5 :         ret->callback = callback;
     460           5 :         ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler,
     461             :                                       ret);
     462           5 :         if (ret->timer == NULL) {
     463           0 :                 Py_DECREF(ret);
     464           0 :                 PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer");
     465           0 :                 return NULL;
     466             :         }
     467           5 :         ref = talloc(ret->timer, struct TeventTimer_Object_ref);
     468           5 :         if (ref == NULL) {
     469           0 :                 talloc_free(ret->timer);
     470           0 :                 Py_DECREF(ret);
     471           0 :                 PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer");
     472           0 :                 return NULL;
     473             :         }
     474           5 :         Py_INCREF(ret);
     475           5 :         ref->obj = ret;
     476             : 
     477           5 :         talloc_set_destructor(ref, TeventTimer_Object_ref_destructor);
     478             : 
     479           5 :         return (PyObject *)ret;
     480             : }
     481             : 
     482           3 : static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args)
     483             : {
     484             :         struct timeval next_event;
     485             :         PyObject *callback;
     486             :         double secs, usecs;
     487           3 :         if (!PyArg_ParseTuple(args, "dO", &secs, &callback)){
     488           0 :                 return NULL;
     489             :         }
     490           3 :         next_event.tv_sec = secs;
     491           3 :         usecs = (secs - next_event.tv_sec) * 1000000.0;
     492           3 :         next_event.tv_usec = usecs;
     493           3 :         return py_tevent_context_add_timer_internal(self, next_event, callback);
     494             : }
     495             : 
     496           2 : static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args)
     497             : {
     498             :         struct timeval next_event;
     499             :         double offset;
     500             :         int seconds;
     501             :         PyObject *callback;
     502           2 :         if (!PyArg_ParseTuple(args, "dO", &offset, &callback))
     503           0 :                 return NULL;
     504             : 
     505           2 :         seconds = offset;
     506           2 :         offset -= seconds;
     507           2 :         next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000));
     508           2 :         return py_tevent_context_add_timer_internal(self, next_event, callback);
     509             : }
     510             : 
     511           0 : static void py_fd_handler(struct tevent_context *ev,
     512             :                                     struct tevent_fd *fde,
     513             :                                     uint16_t flags,
     514             :                                     void *private_data)
     515             : {
     516           0 :         PyObject *callback = private_data, *ret;
     517             : 
     518           0 :         ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags);
     519           0 :         Py_XDECREF(ret);
     520           0 : }
     521             : 
     522           0 : static void py_tevent_fp_dealloc(TeventFd_Object *self)
     523             : {
     524           0 :         talloc_free(self->fd);
     525           0 :         PyObject_Del(self);
     526           0 : }
     527             : 
     528             : static PyTypeObject TeventFd_Type = {
     529             :         .tp_name = "tevent.Fd",
     530             :         .tp_basicsize = sizeof(TeventFd_Object),
     531             :         .tp_dealloc = (destructor)py_tevent_fp_dealloc,
     532             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     533             : };
     534             : 
     535           0 : static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args)
     536             : {
     537             :         int fd, flags;
     538             :         PyObject *handler;
     539             :         struct tevent_fd *tfd;
     540             :         TeventFd_Object *ret;
     541             : 
     542           0 :         if (!PyArg_ParseTuple(args, "iiO", &fd, &flags, &handler))
     543           0 :                 return NULL;
     544             : 
     545           0 :         tfd = tevent_add_fd(self->ev, NULL, fd, flags, py_fd_handler, handler);
     546           0 :         if (tfd == NULL) {
     547           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     548           0 :                 return NULL;
     549             :         }
     550             : 
     551           0 :         ret = PyObject_New(TeventFd_Object, &TeventFd_Type);
     552           0 :         if (ret == NULL) {
     553           0 :                 talloc_free(tfd);
     554           0 :                 return NULL;
     555             :         }
     556           0 :         ret->fd = tfd;
     557             : 
     558           0 :         return (PyObject *)ret;
     559             : }
     560             : 
     561             : static PyMethodDef py_tevent_context_methods[] = {
     562             :         { "reinitialise", (PyCFunction)py_tevent_context_reinitialise,
     563             :                 METH_NOARGS,
     564             :                 "S.reinitialise()" },
     565             :         { "wakeup_send", (PyCFunction)py_tevent_context_wakeup_send, 
     566             :                 METH_VARARGS, "S.wakeup_send(wakeup_time) -> req" },
     567             :         { "loop_wait", (PyCFunction)py_tevent_context_loop_wait,
     568             :                 METH_NOARGS, "S.loop_wait()" },
     569             :         { "loop_once", (PyCFunction)py_tevent_context_loop_once,
     570             :                 METH_NOARGS, "S.loop_once()" },
     571             :         { "add_signal", (PyCFunction)py_tevent_context_add_signal,
     572             :                 METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" },
     573             :         { "add_timer", (PyCFunction)py_tevent_context_add_timer,
     574             :                 METH_VARARGS, "S.add_timer(next_event, handler) -> timer" },
     575             :         { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset,
     576             :                 METH_VARARGS, "S.add_timer_offset(offset_seconds, handler) -> timer" },
     577             :         { "add_fd", (PyCFunction)py_tevent_context_add_fd, 
     578             :                 METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" },
     579             :         {0},
     580             : };
     581             : 
     582           0 : static PyObject *py_tevent_req_wakeup_recv(PyObject *self,
     583             :                 PyObject *Py_UNUSED(ignored))
     584             : {
     585             :         /* FIXME */
     586           0 :         Py_RETURN_NONE;
     587             : }
     588             : 
     589           0 : static PyObject *py_tevent_req_received(PyObject *self,
     590             :                 PyObject *Py_UNUSED(ignored))
     591             : {
     592             :         /* FIXME */
     593           0 :         Py_RETURN_NONE;
     594             : }
     595             : 
     596           0 : static PyObject *py_tevent_req_is_error(PyObject *self,
     597             :                 PyObject *Py_UNUSED(ignored))
     598             : {
     599             :         /* FIXME */
     600           0 :         Py_RETURN_NONE;
     601             : }
     602             : 
     603           0 : static PyObject *py_tevent_req_poll(PyObject *self,
     604             :                 PyObject *Py_UNUSED(ignored))
     605             : {
     606             :         /* FIXME */
     607           0 :         Py_RETURN_NONE;
     608             : }
     609             : 
     610           0 : static PyObject *py_tevent_req_is_in_progress(PyObject *self,
     611             :                 PyObject *Py_UNUSED(ignored))
     612             : {
     613             :         /* FIXME */
     614           0 :         Py_RETURN_NONE;
     615             : }
     616             : 
     617             : static PyGetSetDef py_tevent_req_getsetters[] = {
     618             :         {
     619             :                 .name = discard_const_p(char, "in_progress"),
     620             :                 .get = (getter)py_tevent_req_is_in_progress,
     621             :                 .doc = discard_const_p(char, "Whether the request is in progress"),
     622             :         },
     623             :         {0}
     624             : };
     625             : 
     626           0 : static PyObject *py_tevent_req_post(PyObject *self, PyObject *args)
     627             : {
     628             :         /* FIXME */
     629           0 :         Py_RETURN_NONE;
     630             : }
     631             : 
     632           0 : static PyObject *py_tevent_req_set_error(PyObject *self, PyObject *args)
     633             : {
     634             :         /* FIXME */
     635           0 :         Py_RETURN_NONE;
     636             : }
     637             : 
     638           0 : static PyObject *py_tevent_req_done(PyObject *self,
     639             :                 PyObject *Py_UNUSED(ignored))
     640             : {
     641             :         /* FIXME */
     642           0 :         Py_RETURN_NONE;
     643             : }
     644             : 
     645           0 : static PyObject *py_tevent_req_notify_callback(PyObject *self,
     646             :                 PyObject *Py_UNUSED(ignored))
     647             : {
     648             :         /* FIXME */
     649           0 :         Py_RETURN_NONE;
     650             : }
     651             : 
     652           0 : static PyObject *py_tevent_req_set_endtime(PyObject *self, PyObject *args)
     653             : {
     654             :         /* FIXME */
     655           0 :         Py_RETURN_NONE;
     656             : }
     657             : 
     658           0 : static PyObject *py_tevent_req_cancel(TeventReq_Object *self,
     659             :                 PyObject *Py_UNUSED(ignored))
     660             : {
     661           0 :         if (!tevent_req_cancel(self->req)) {
     662           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     663           0 :                 return NULL;
     664             :         }
     665           0 :         Py_RETURN_NONE;
     666             : }
     667             : 
     668             : static PyMethodDef py_tevent_req_methods[] = {
     669             :         { "wakeup_recv", (PyCFunction)py_tevent_req_wakeup_recv,
     670             :                 METH_NOARGS,
     671             :                 "Wakeup received" },
     672             :         { "received", (PyCFunction)py_tevent_req_received,
     673             :                 METH_NOARGS,
     674             :                 "Receive finished" },
     675             :         { "is_error", (PyCFunction)py_tevent_req_is_error, METH_NOARGS,
     676             :                 "is_error() -> (error, state)" },
     677             :         { "poll", (PyCFunction)py_tevent_req_poll, METH_VARARGS,
     678             :                 "poll(ctx)" },
     679             :         { "post", (PyCFunction)py_tevent_req_post, METH_VARARGS,
     680             :                 "post(ctx) -> req" },
     681             :         { "set_error", (PyCFunction)py_tevent_req_set_error, METH_VARARGS,
     682             :                 "set_error(error)" },
     683             :         { "done", (PyCFunction)py_tevent_req_done, METH_NOARGS,
     684             :                 "done()" },
     685             :         { "notify_callback", (PyCFunction)py_tevent_req_notify_callback,
     686             :                 METH_NOARGS, "notify_callback()" },
     687             :         { "set_endtime", (PyCFunction)py_tevent_req_set_endtime,
     688             :                 METH_VARARGS, "set_endtime(ctx, endtime)" },
     689             :         { "cancel", (PyCFunction)py_tevent_req_cancel,
     690             :                 METH_NOARGS, "cancel()" },
     691             :         {0}
     692             : };
     693             : 
     694           0 : static void py_tevent_req_dealloc(TeventReq_Object *self)
     695             : {
     696           0 :         talloc_free(self->req);
     697           0 :         PyObject_DEL(self);
     698           0 : }
     699             : 
     700             : static PyTypeObject TeventReq_Type = {
     701             :         .tp_name = "tevent.Request",
     702             :         .tp_basicsize = sizeof(TeventReq_Object),
     703             :         .tp_methods = py_tevent_req_methods,
     704             :         .tp_dealloc = (destructor)py_tevent_req_dealloc,
     705             :         .tp_getset = py_tevent_req_getsetters,
     706             :         /* FIXME: .tp_new = py_tevent_req_new, */
     707             : };
     708             : 
     709           0 : static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self,
     710             :                         PyObject *Py_UNUSED(ignored))
     711             : {
     712           0 :         return PyLong_FromLong(tevent_queue_length(self->queue));
     713             : }
     714             : 
     715             : static PyGetSetDef py_tevent_queue_getsetters[] = {
     716             :         {
     717             :                 .name = discard_const_p(char, "length"),
     718             :                 .get = (getter)py_tevent_queue_get_length,
     719             :                 .doc = discard_const_p(char, "The number of elements in the queue."),
     720             :         },
     721             :         {0},
     722             : };
     723             : 
     724           0 : static void py_tevent_queue_dealloc(TeventQueue_Object *self)
     725             : {
     726           0 :         talloc_free(self->queue);
     727           0 :         PyObject_Del(self);
     728           0 : }
     729             : 
     730             : static PyTypeObject TeventQueue_Type = {
     731             :         .tp_name = "tevent.Queue",
     732             :         .tp_basicsize = sizeof(TeventQueue_Object),
     733             :         .tp_dealloc = (destructor)py_tevent_queue_dealloc,
     734             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     735             :         .tp_getset = py_tevent_queue_getsetters,
     736             :         .tp_methods = py_tevent_queue_methods,
     737             : };
     738             : 
     739           1 : static PyObject *py_tevent_context_signal_support(PyObject *_self,
     740             :                 PyObject *Py_UNUSED(ignored))
     741             : {
     742           1 :         TeventContext_Object *self = (TeventContext_Object *)_self;
     743           1 :         return PyBool_FromLong(tevent_signal_support(self->ev));
     744             : }
     745             : 
     746             : static PyGetSetDef py_tevent_context_getsetters[] = {
     747             :         {
     748             :                 .name = discard_const_p(char, "signal_support"),
     749             :                 .get = PY_DISCARD_FUNC_SIG(getter,
     750             :                                            py_tevent_context_signal_support),
     751             :                 .doc = discard_const_p(char, "if this platform and tevent context support signal handling"),
     752             :         },
     753             :         {0}
     754             : };
     755             : 
     756          10 : static void py_tevent_context_dealloc(TeventContext_Object *self)
     757             : {
     758          10 :         talloc_free(self->ev);
     759          10 :         PyObject_Del(self);
     760          10 : }
     761             : 
     762          10 : static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     763             : {
     764          10 :         const char * const kwnames[] = { "name", NULL };
     765          10 :         char *name = NULL;
     766             :         struct tevent_context *ev;
     767             :         TeventContext_Object *ret;
     768             : 
     769          10 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name))
     770           0 :                 return NULL;
     771             : 
     772          10 :         if (name == NULL) {
     773           9 :                 ev = tevent_context_init(NULL);
     774             :         } else {
     775           1 :                 ev = tevent_context_init_byname(NULL, name);
     776             :         }
     777             : 
     778          10 :         if (ev == NULL) {
     779           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     780           0 :                 return NULL;
     781             :         }
     782             : 
     783          10 :         ret = PyObject_New(TeventContext_Object, type);
     784          10 :         if (ret == NULL) {
     785           0 :                 PyErr_NoMemory();
     786           0 :                 talloc_free(ev);
     787           0 :                 return NULL;
     788             :         }
     789             : 
     790          10 :         ret->ev = ev;
     791          10 :         return (PyObject *)ret;
     792             : }
     793             : 
     794             : static PyTypeObject TeventContext_Type = {
     795             :         .tp_name = "tevent.Context",
     796             :         .tp_new = py_tevent_context_new,
     797             :         .tp_basicsize = sizeof(TeventContext_Object),
     798             :         .tp_dealloc = (destructor)py_tevent_context_dealloc,
     799             :         .tp_methods = py_tevent_context_methods,
     800             :         .tp_getset = py_tevent_context_getsetters,
     801             :         .tp_flags = Py_TPFLAGS_DEFAULT,
     802             : };
     803             : 
     804           0 : static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
     805             : {
     806             :         char *backend_name;
     807           0 :         if (!PyArg_ParseTuple(args, "s", &backend_name))
     808           0 :                 return NULL;
     809             : 
     810           0 :         tevent_set_default_backend(backend_name);
     811             : 
     812           0 :         Py_RETURN_NONE;
     813             : }
     814             : 
     815           2 : static PyObject *py_backend_list(PyObject *self,
     816             :                 PyObject *Py_UNUSED(ignored))
     817             : {
     818           2 :         PyObject *ret = NULL;
     819           2 :         PyObject *string = NULL;
     820             :         int i, result;
     821           2 :         const char **backends = NULL;
     822             : 
     823           2 :         ret = PyList_New(0);
     824           2 :         if (ret == NULL) {
     825           0 :                 return NULL;
     826             :         }
     827             : 
     828           2 :         backends = tevent_backend_list(NULL);
     829           2 :         if (backends == NULL) {
     830           0 :                 PyErr_SetNone(PyExc_RuntimeError);
     831           0 :                 goto err;
     832             :         }
     833          10 :         for (i = 0; backends[i]; i++) {
     834           8 :                 string = PyUnicode_FromString(backends[i]);
     835           8 :                 if (!string) {
     836           0 :                         goto err;
     837             :                 }
     838           8 :                 result = PyList_Append(ret, string);
     839           8 :                 if (result) {
     840           0 :                         goto err;
     841             :                 }
     842           8 :                 Py_DECREF(string);
     843           8 :                 string = NULL;
     844             :         }
     845             : 
     846           2 :         talloc_free(backends);
     847             : 
     848           2 :         return ret;
     849             : 
     850           0 : err:
     851           0 :         Py_XDECREF(ret);
     852           0 :         Py_XDECREF(string);
     853           0 :         talloc_free(backends);
     854           0 :         return NULL;
     855             : }
     856             : 
     857             : static PyMethodDef tevent_methods[] = {
     858             :         { "register_backend", (PyCFunction)py_register_backend, METH_VARARGS,
     859             :                 "register_backend(backend)" },
     860             :         { "set_default_backend", (PyCFunction)py_set_default_backend, 
     861             :                 METH_VARARGS, "set_default_backend(backend)" },
     862             :         { "backend_list", (PyCFunction)py_backend_list, 
     863             :                 METH_NOARGS, "backend_list() -> list" },
     864             :         {0},
     865             : };
     866             : 
     867             : #define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
     868             : 
     869             : #if PY_MAJOR_VERSION >= 3
     870             : static struct PyModuleDef moduledef = {
     871             :         PyModuleDef_HEAD_INIT,
     872             :         .m_name = "_tevent",
     873             :         .m_doc = MODULE_DOC,
     874             :         .m_size = -1,
     875             :         .m_methods = tevent_methods,
     876             : };
     877             : #endif
     878             : 
     879             : PyObject * module_init(void);
     880           1 : PyObject * module_init(void)
     881             : {
     882             :         PyObject *m;
     883             : 
     884           1 :         if (PyType_Ready(&TeventContext_Type) < 0)
     885           0 :                 return NULL;
     886             : 
     887           1 :         if (PyType_Ready(&TeventQueue_Type) < 0)
     888           0 :                 return NULL;
     889             : 
     890           1 :         if (PyType_Ready(&TeventReq_Type) < 0)
     891           0 :                 return NULL;
     892             : 
     893           1 :         if (PyType_Ready(&TeventSignal_Type) < 0)
     894           0 :                 return NULL;
     895             : 
     896           1 :         if (PyType_Ready(&TeventTimer_Type) < 0)
     897           0 :                 return NULL;
     898             : 
     899           1 :         if (PyType_Ready(&TeventFd_Type) < 0)
     900           0 :                 return NULL;
     901             : 
     902             : #if PY_MAJOR_VERSION >= 3
     903           1 :         m = PyModule_Create(&moduledef);
     904             : #else
     905             :         m = Py_InitModule3("_tevent", tevent_methods, MODULE_DOC);
     906             : #endif
     907           1 :         if (m == NULL)
     908           0 :                 return NULL;
     909             : 
     910           1 :         Py_INCREF(&TeventContext_Type);
     911           1 :         PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type);
     912             : 
     913           1 :         Py_INCREF(&TeventQueue_Type);
     914           1 :         PyModule_AddObject(m, "Queue", (PyObject *)&TeventQueue_Type);
     915             : 
     916           1 :         Py_INCREF(&TeventReq_Type);
     917           1 :         PyModule_AddObject(m, "Request", (PyObject *)&TeventReq_Type);
     918             : 
     919           1 :         Py_INCREF(&TeventSignal_Type);
     920           1 :         PyModule_AddObject(m, "Signal", (PyObject *)&TeventSignal_Type);
     921             : 
     922           1 :         Py_INCREF(&TeventTimer_Type);
     923           1 :         PyModule_AddObject(m, "Timer", (PyObject *)&TeventTimer_Type);
     924             : 
     925           1 :         Py_INCREF(&TeventFd_Type);
     926           1 :         PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type);
     927             : 
     928           1 :         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
     929             : 
     930           1 :         return m;
     931             : }
     932             : 
     933             : #if PY_MAJOR_VERSION >= 3
     934             : PyMODINIT_FUNC PyInit__tevent(void);
     935           1 : PyMODINIT_FUNC PyInit__tevent(void)
     936             : {
     937           1 :         return module_init();
     938             : }
     939             : #else
     940             : void init_tevent(void);
     941             : void init_tevent(void)
     942             : {
     943             :         module_init();
     944             : }
     945             : #endif

Generated by: LCOV version 1.13