callbacks.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* Copyright (c) 2011-2012 Denis Bilenko. See LICENSE for details. */
  2. #ifdef Py_PYTHON_H
  3. /* the name changes depending on our file layout and --module-name option */
  4. #define _GEVENTLOOP struct __pyx_vtabstruct_6gevent_5libev_8corecext_loop
  5. static void gevent_handle_error(struct PyGeventLoopObject* loop, PyObject* context) {
  6. PyThreadState *tstate;
  7. PyObject *type, *value, *traceback, *result;
  8. tstate = PyThreadState_GET();
  9. type = tstate->curexc_type;
  10. if (!type)
  11. return;
  12. value = tstate->curexc_value;
  13. traceback = tstate->curexc_traceback;
  14. if (!value) value = Py_None;
  15. if (!traceback) traceback = Py_None;
  16. Py_INCREF(type);
  17. Py_INCREF(value);
  18. Py_INCREF(traceback);
  19. PyErr_Clear();
  20. result = ((_GEVENTLOOP *)loop->__pyx_vtab)->handle_error(loop, context, type, value, traceback, 0);
  21. if (result) {
  22. Py_DECREF(result);
  23. }
  24. else {
  25. PyErr_Print();
  26. PyErr_Clear();
  27. }
  28. Py_DECREF(type);
  29. Py_DECREF(value);
  30. Py_DECREF(traceback);
  31. }
  32. static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) {
  33. if (!ev_is_default_loop(loop->_ptr)) {
  34. /* only reporting signals on the default loop */
  35. return;
  36. }
  37. PyErr_CheckSignals();
  38. if (PyErr_Occurred()) gevent_handle_error(loop, Py_None);
  39. }
  40. #define GET_OBJECT(PY_TYPE, EV_PTR, MEMBER) \
  41. ((struct PY_TYPE *)(((char *)EV_PTR) - offsetof(struct PY_TYPE, MEMBER)))
  42. #ifdef WITH_THREAD
  43. #define GIL_DECLARE PyGILState_STATE ___save
  44. #define GIL_ENSURE ___save = PyGILState_Ensure();
  45. #define GIL_RELEASE PyGILState_Release(___save);
  46. #else
  47. #define GIL_DECLARE
  48. #define GIL_ENSURE
  49. #define GIL_RELEASE
  50. #endif
  51. static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) {
  52. PyObject *result, *method;
  53. int error;
  54. error = 1;
  55. method = PyObject_GetAttrString(watcher, "stop");
  56. if (method) {
  57. result = PyObject_Call(method, __pyx_empty_tuple, NULL);
  58. if (result) {
  59. Py_DECREF(result);
  60. error = 0;
  61. }
  62. Py_DECREF(method);
  63. }
  64. if (error) {
  65. gevent_handle_error(loop, watcher);
  66. }
  67. }
  68. static void gevent_callback(struct PyGeventLoopObject* loop, PyObject* callback, PyObject* args, PyObject* watcher, void *c_watcher, int revents) {
  69. GIL_DECLARE;
  70. PyObject *result, *py_events;
  71. long length;
  72. py_events = 0;
  73. GIL_ENSURE;
  74. Py_INCREF(loop);
  75. Py_INCREF(callback);
  76. Py_INCREF(args);
  77. Py_INCREF(watcher);
  78. gevent_check_signals(loop);
  79. if (args == Py_None) {
  80. args = __pyx_empty_tuple;
  81. }
  82. length = PyTuple_Size(args);
  83. if (length < 0) {
  84. gevent_handle_error(loop, watcher);
  85. goto end;
  86. }
  87. if (length > 0 && PyTuple_GET_ITEM(args, 0) == GEVENT_CORE_EVENTS) {
  88. py_events = PyInt_FromLong(revents);
  89. if (!py_events) {
  90. gevent_handle_error(loop, watcher);
  91. goto end;
  92. }
  93. PyTuple_SET_ITEM(args, 0, py_events);
  94. }
  95. else {
  96. py_events = NULL;
  97. }
  98. result = PyObject_Call(callback, args, NULL);
  99. if (result) {
  100. Py_DECREF(result);
  101. }
  102. else {
  103. gevent_handle_error(loop, watcher);
  104. if (revents & (EV_READ|EV_WRITE)) {
  105. /* io watcher: not stopping it may cause the failing callback to be called repeatedly */
  106. gevent_stop(watcher, loop);
  107. goto end;
  108. }
  109. }
  110. if (!ev_is_active(c_watcher)) {
  111. /* Watcher was stopped, maybe by libev. Let's call stop() to clean up
  112. * 'callback' and 'args' properties, do Py_DECREF() and ev_ref() if necessary.
  113. * BTW, we don't need to check for EV_ERROR, because libev stops the watcher in that case. */
  114. gevent_stop(watcher, loop);
  115. }
  116. end:
  117. if (py_events) {
  118. Py_DECREF(py_events);
  119. PyTuple_SET_ITEM(args, 0, GEVENT_CORE_EVENTS);
  120. }
  121. Py_DECREF(watcher);
  122. Py_DECREF(args);
  123. Py_DECREF(callback);
  124. Py_DECREF(loop);
  125. GIL_RELEASE;
  126. }
  127. static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb) {
  128. /* no need for GIL here because it is only called from run_callbacks which already has GIL */
  129. PyObject *result, *callback, *args;
  130. if (!loop || !cb)
  131. return;
  132. callback = cb->callback;
  133. args = cb->args;
  134. if (!callback || !args)
  135. return;
  136. if (callback == Py_None || args == Py_None)
  137. return;
  138. Py_INCREF(loop);
  139. Py_INCREF(callback);
  140. Py_INCREF(args);
  141. Py_INCREF(Py_None);
  142. Py_DECREF(cb->callback);
  143. cb->callback = Py_None;
  144. result = PyObject_Call(callback, args, NULL);
  145. if (result) {
  146. Py_DECREF(result);
  147. }
  148. else {
  149. gevent_handle_error(loop, (PyObject*)cb);
  150. }
  151. Py_INCREF(Py_None);
  152. Py_DECREF(cb->args);
  153. cb->args = Py_None;
  154. Py_DECREF(callback);
  155. Py_DECREF(args);
  156. Py_DECREF(loop);
  157. }
  158. #undef DEFINE_CALLBACK
  159. #define DEFINE_CALLBACK(WATCHER_LC, WATCHER_TYPE) \
  160. static void gevent_callback_##WATCHER_LC(struct ev_loop *_loop, void *c_watcher, int revents) { \
  161. struct PyGevent##WATCHER_TYPE##Object* watcher = GET_OBJECT(PyGevent##WATCHER_TYPE##Object, c_watcher, _watcher); \
  162. gevent_callback(watcher->loop, watcher->_callback, watcher->args, (PyObject*)watcher, c_watcher, revents); \
  163. }
  164. DEFINE_CALLBACKS
  165. static void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) {
  166. struct PyGeventLoopObject* loop;
  167. PyObject *result;
  168. GIL_DECLARE;
  169. GIL_ENSURE;
  170. loop = GET_OBJECT(PyGeventLoopObject, watcher, _prepare);
  171. Py_INCREF(loop);
  172. gevent_check_signals(loop);
  173. result = ((_GEVENTLOOP *)loop->__pyx_vtab)->_run_callbacks(loop);
  174. if (result) {
  175. Py_DECREF(result);
  176. }
  177. else {
  178. PyErr_Print();
  179. PyErr_Clear();
  180. }
  181. Py_DECREF(loop);
  182. GIL_RELEASE;
  183. }
  184. #if defined(_WIN32)
  185. static void gevent_periodic_signal_check(struct ev_loop *_loop, void *watcher, int revents) {
  186. GIL_DECLARE;
  187. GIL_ENSURE;
  188. gevent_check_signals(GET_OBJECT(PyGeventLoopObject, watcher, _periodic_signal_checker));
  189. GIL_RELEASE;
  190. }
  191. #endif /* _WIN32 */
  192. #endif /* Py_PYTHON_H */