static void gevent_callback(struct PyGeventLoopObject* loop, PyObject* callback, PyObject* args, PyObject* watcher, void *c_watcher, int revents) { GIL_DECLARE; PyObject *result, *py_events; long length; py_events = 0; GIL_ENSURE; Py_INCREF(loop); Py_INCREF(callback); Py_INCREF(args); Py_INCREF(watcher); gevent_check_signals(loop); if (args == Py_None) { args = __pyx_empty_tuple; } length = PyTuple_Size(args); if (length < 0) { gevent_handle_error(loop, watcher); goto end; } if (length > 0 && PyTuple_GET_ITEM(args, 0) == GEVENT_CORE_EVENTS) { py_events = PyInt_FromLong(revents); if (!py_events) { gevent_handle_error(loop, watcher); goto end; } PyTuple_SET_ITEM(args, 0, py_events); } else { py_events = NULL; } result = PyObject_Call(callback, args, NULL); if (result) { Py_DECREF(result); } else { gevent_handle_error(loop, watcher); if (revents & (EV_READ|EV_WRITE)) { /* io watcher: not stopping it may cause the failing callback to be called repeatedly */ gevent_stop(watcher, loop); goto end; } } if (!ev_is_active(c_watcher)) { /* Watcher was stopped, maybe by libev. Let's call stop() to clean up * 'callback' and 'args' properties, do Py_DECREF() and ev_ref() if necessary. * BTW, we don't need to check for EV_ERROR, because libev stops the watcher in that case. */ gevent_stop(watcher, loop); } end: if (py_events) { Py_DECREF(py_events); PyTuple_SET_ITEM(args, 0, GEVENT_CORE_EVENTS); } Py_DECREF(watcher); Py_DECREF(args); Py_DECREF(callback); Py_DECREF(loop); GIL_RELEASE; }
static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb) { /* no need for GIL here because it is only called from run_callbacks which already has GIL */ PyObject *result, *callback, *args; if (!loop || !cb) return; callback = cb->callback; args = cb->args; if (!callback || !args) return; if (callback == Py_None || args == Py_None) return; Py_INCREF(loop); Py_INCREF(callback); Py_INCREF(args); Py_INCREF(Py_None); Py_DECREF(cb->callback); cb->callback = Py_None; result = PyObject_Call(callback, args, NULL); if (result) { Py_DECREF(result); } else { gevent_handle_error(loop, (PyObject*)cb); } Py_INCREF(Py_None); Py_DECREF(cb->args); cb->args = Py_None; Py_DECREF(callback); Py_DECREF(args); Py_DECREF(loop); }
static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) { if (!ev_is_default_loop(loop->_ptr)) { /* only reporting signals on the default loop */ return; } PyErr_CheckSignals(); if (PyErr_Occurred()) gevent_handle_error(loop, Py_None); }
static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) { PyObject *result, *method; int error; error = 1; method = PyObject_GetAttrString(watcher, "stop"); if (method) { result = PyObject_Call(method, __pyx_empty_tuple, NULL); if (result) { Py_DECREF(result); error = 0; } Py_DECREF(method); } if (error) { gevent_handle_error(loop, watcher); } }
static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb) { GIL_DECLARE; PyObject *result, *callback, *args; GIL_ENSURE; if (!loop || !cb) return; callback = cb->callback; args = cb->args; if (!callback || !args) return; if (callback == Py_None || args == Py_None) return; Py_INCREF(loop); Py_INCREF(callback); Py_INCREF(args); Py_INCREF(Py_None); Py_DECREF(cb->callback); cb->callback = Py_None; result = PyObject_Call(callback, args, NULL); if (result) { Py_DECREF(result); } else { gevent_handle_error(loop, cb); } Py_INCREF(Py_None); Py_DECREF(cb->args); cb->args = Py_None; Py_DECREF(callback); Py_DECREF(args); Py_DECREF(loop); GIL_RELEASE; }
static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) { PyErr_CheckSignals(); if (PyErr_Occurred()) gevent_handle_error(loop, Py_None); }