| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1 | #include "Python.h" | 
 | 2 | #include "structmember.h" | 
 | 3 |  | 
 | 4 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 5 | /*[clinic input] | 
 | 6 | module _asyncio | 
 | 7 | [clinic start generated code]*/ | 
 | 8 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/ | 
 | 9 |  | 
 | 10 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 11 | /* identifiers used from some functions */ | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 12 | _Py_IDENTIFIER(add_done_callback); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 13 | _Py_IDENTIFIER(call_soon); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 14 | _Py_IDENTIFIER(cancel); | 
 | 15 | _Py_IDENTIFIER(send); | 
 | 16 | _Py_IDENTIFIER(throw); | 
 | 17 | _Py_IDENTIFIER(_step); | 
 | 18 | _Py_IDENTIFIER(_schedule_callbacks); | 
 | 19 | _Py_IDENTIFIER(_wakeup); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 20 |  | 
 | 21 |  | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 22 | /* State of the _asyncio module */ | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 23 | static PyObject *all_tasks; | 
| Yury Selivanov | 684ef2c | 2016-10-28 19:01:21 -0400 | [diff] [blame] | 24 | static PyObject *current_tasks; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 25 | static PyObject *traceback_extract_stack; | 
 | 26 | static PyObject *asyncio_get_event_loop; | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 27 | static PyObject *asyncio_future_repr_info_func; | 
 | 28 | static PyObject *asyncio_task_repr_info_func; | 
 | 29 | static PyObject *asyncio_task_get_stack_func; | 
 | 30 | static PyObject *asyncio_task_print_stack_func; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 31 | static PyObject *asyncio_InvalidStateError; | 
 | 32 | static PyObject *asyncio_CancelledError; | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 33 | static PyObject *inspect_isgenerator; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 34 |  | 
 | 35 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 36 | typedef enum { | 
 | 37 |     STATE_PENDING, | 
 | 38 |     STATE_CANCELLED, | 
 | 39 |     STATE_FINISHED | 
 | 40 | } fut_state; | 
 | 41 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 42 | #define FutureObj_HEAD(prefix)                                              \ | 
 | 43 |     PyObject_HEAD                                                           \ | 
 | 44 |     PyObject *prefix##_loop;                                                \ | 
 | 45 |     PyObject *prefix##_callbacks;                                           \ | 
 | 46 |     PyObject *prefix##_exception;                                           \ | 
 | 47 |     PyObject *prefix##_result;                                              \ | 
 | 48 |     PyObject *prefix##_source_tb;                                           \ | 
 | 49 |     fut_state prefix##_state;                                               \ | 
 | 50 |     int prefix##_log_tb;                                                    \ | 
 | 51 |     int prefix##_blocking;                                                  \ | 
 | 52 |     PyObject *dict;                                                         \ | 
 | 53 |     PyObject *prefix##_weakreflist; | 
 | 54 |  | 
 | 55 | typedef struct { | 
 | 56 |     FutureObj_HEAD(fut) | 
 | 57 | } FutureObj; | 
 | 58 |  | 
 | 59 | typedef struct { | 
 | 60 |     FutureObj_HEAD(task) | 
 | 61 |     PyObject *task_fut_waiter; | 
 | 62 |     PyObject *task_coro; | 
 | 63 |     int task_must_cancel; | 
 | 64 |     int task_log_destroy_pending; | 
 | 65 | } TaskObj; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 66 |  | 
 | 67 | typedef struct { | 
 | 68 |     PyObject_HEAD | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 69 |     TaskObj *sw_task; | 
 | 70 |     PyObject *sw_arg; | 
 | 71 | } TaskSendMethWrapper; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 72 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 73 | typedef struct { | 
 | 74 |     PyObject_HEAD | 
 | 75 |     TaskObj *ww_task; | 
 | 76 | } TaskWakeupMethWrapper; | 
 | 77 |  | 
 | 78 |  | 
 | 79 | #include "clinic/_asynciomodule.c.h" | 
 | 80 |  | 
 | 81 |  | 
 | 82 | /*[clinic input] | 
 | 83 | class _asyncio.Future "FutureObj *" "&Future_Type" | 
 | 84 | [clinic start generated code]*/ | 
 | 85 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/ | 
 | 86 |  | 
 | 87 | /* Get FutureIter from Future */ | 
 | 88 | static PyObject* future_new_iter(PyObject *); | 
 | 89 | static inline int future_call_schedule_callbacks(FutureObj *); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 90 |  | 
 | 91 | static int | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 92 | future_schedule_callbacks(FutureObj *fut) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 93 | { | 
 | 94 |     Py_ssize_t len; | 
 | 95 |     PyObject* iters; | 
 | 96 |     int i; | 
 | 97 |  | 
 | 98 |     if (fut->fut_callbacks == NULL) { | 
 | 99 |         PyErr_SetString(PyExc_RuntimeError, "NULL callbacks"); | 
 | 100 |         return -1; | 
 | 101 |     } | 
 | 102 |  | 
 | 103 |     len = PyList_GET_SIZE(fut->fut_callbacks); | 
 | 104 |     if (len == 0) { | 
 | 105 |         return 0; | 
 | 106 |     } | 
 | 107 |  | 
 | 108 |     iters = PyList_GetSlice(fut->fut_callbacks, 0, len); | 
 | 109 |     if (iters == NULL) { | 
 | 110 |         return -1; | 
 | 111 |     } | 
 | 112 |     if (PyList_SetSlice(fut->fut_callbacks, 0, len, NULL) < 0) { | 
 | 113 |         Py_DECREF(iters); | 
 | 114 |         return -1; | 
 | 115 |     } | 
 | 116 |  | 
 | 117 |     for (i = 0; i < len; i++) { | 
 | 118 |         PyObject *handle = NULL; | 
 | 119 |         PyObject *cb = PyList_GET_ITEM(iters, i); | 
 | 120 |  | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 121 |         handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, &PyId_call_soon, | 
 | 122 |                                                cb, fut, NULL); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 123 |  | 
 | 124 |         if (handle == NULL) { | 
 | 125 |             Py_DECREF(iters); | 
 | 126 |             return -1; | 
 | 127 |         } | 
 | 128 |         else { | 
 | 129 |             Py_DECREF(handle); | 
 | 130 |         } | 
 | 131 |     } | 
 | 132 |  | 
 | 133 |     Py_DECREF(iters); | 
 | 134 |     return 0; | 
 | 135 | } | 
 | 136 |  | 
 | 137 | static int | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 138 | future_init(FutureObj *fut, PyObject *loop) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 139 | { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 140 |     PyObject *res = NULL; | 
 | 141 |     _Py_IDENTIFIER(get_debug); | 
 | 142 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 143 |     if (loop == NULL || loop == Py_None) { | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 144 |         loop = _PyObject_CallNoArg(asyncio_get_event_loop); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 145 |         if (loop == NULL) { | 
 | 146 |             return -1; | 
 | 147 |         } | 
 | 148 |     } | 
 | 149 |     else { | 
 | 150 |         Py_INCREF(loop); | 
 | 151 |     } | 
 | 152 |     Py_CLEAR(fut->fut_loop); | 
 | 153 |     fut->fut_loop = loop; | 
 | 154 |  | 
| Victor Stinner | f94d1ee | 2016-10-29 09:05:39 +0200 | [diff] [blame] | 155 |     res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 156 |     if (res == NULL) { | 
 | 157 |         return -1; | 
 | 158 |     } | 
 | 159 |     if (PyObject_IsTrue(res)) { | 
 | 160 |         Py_CLEAR(res); | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 161 |         fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 162 |         if (fut->fut_source_tb == NULL) { | 
 | 163 |             return -1; | 
 | 164 |         } | 
 | 165 |     } | 
 | 166 |     else { | 
 | 167 |         Py_CLEAR(res); | 
 | 168 |     } | 
 | 169 |  | 
 | 170 |     fut->fut_callbacks = PyList_New(0); | 
 | 171 |     if (fut->fut_callbacks == NULL) { | 
 | 172 |         return -1; | 
 | 173 |     } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 174 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 175 |     return 0; | 
 | 176 | } | 
 | 177 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 178 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 179 | future_set_result(FutureObj *fut, PyObject *res) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 180 | { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 181 |     if (fut->fut_state != STATE_PENDING) { | 
 | 182 |         PyErr_SetString(asyncio_InvalidStateError, "invalid state"); | 
 | 183 |         return NULL; | 
 | 184 |     } | 
 | 185 |  | 
 | 186 |     Py_INCREF(res); | 
 | 187 |     fut->fut_result = res; | 
 | 188 |     fut->fut_state = STATE_FINISHED; | 
 | 189 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 190 |     if (future_call_schedule_callbacks(fut) == -1) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 191 |         return NULL; | 
 | 192 |     } | 
 | 193 |     Py_RETURN_NONE; | 
 | 194 | } | 
 | 195 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 196 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 197 | future_set_exception(FutureObj *fut, PyObject *exc) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 198 | { | 
 | 199 |     PyObject *exc_val = NULL; | 
 | 200 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 201 |     if (fut->fut_state != STATE_PENDING) { | 
 | 202 |         PyErr_SetString(asyncio_InvalidStateError, "invalid state"); | 
 | 203 |         return NULL; | 
 | 204 |     } | 
 | 205 |  | 
 | 206 |     if (PyExceptionClass_Check(exc)) { | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 207 |         exc_val = _PyObject_CallNoArg(exc); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 208 |         if (exc_val == NULL) { | 
 | 209 |             return NULL; | 
 | 210 |         } | 
 | 211 |     } | 
 | 212 |     else { | 
 | 213 |         exc_val = exc; | 
 | 214 |         Py_INCREF(exc_val); | 
 | 215 |     } | 
 | 216 |     if (!PyExceptionInstance_Check(exc_val)) { | 
 | 217 |         Py_DECREF(exc_val); | 
 | 218 |         PyErr_SetString(PyExc_TypeError, "invalid exception object"); | 
 | 219 |         return NULL; | 
 | 220 |     } | 
 | 221 |     if ((PyObject*)Py_TYPE(exc_val) == PyExc_StopIteration) { | 
 | 222 |         Py_DECREF(exc_val); | 
 | 223 |         PyErr_SetString(PyExc_TypeError, | 
 | 224 |                         "StopIteration interacts badly with generators " | 
 | 225 |                         "and cannot be raised into a Future"); | 
 | 226 |         return NULL; | 
 | 227 |     } | 
 | 228 |  | 
 | 229 |     fut->fut_exception = exc_val; | 
 | 230 |     fut->fut_state = STATE_FINISHED; | 
 | 231 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 232 |     if (future_call_schedule_callbacks(fut) == -1) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 233 |         return NULL; | 
 | 234 |     } | 
 | 235 |  | 
 | 236 |     fut->fut_log_tb = 1; | 
 | 237 |     Py_RETURN_NONE; | 
 | 238 | } | 
 | 239 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 240 | static int | 
 | 241 | future_get_result(FutureObj *fut, PyObject **result) | 
 | 242 | { | 
 | 243 |     PyObject *exc; | 
 | 244 |  | 
 | 245 |     if (fut->fut_state == STATE_CANCELLED) { | 
 | 246 |         exc = _PyObject_CallNoArg(asyncio_CancelledError); | 
 | 247 |         if (exc == NULL) { | 
 | 248 |             return -1; | 
 | 249 |         } | 
 | 250 |         *result = exc; | 
 | 251 |         return 1; | 
 | 252 |     } | 
 | 253 |  | 
 | 254 |     if (fut->fut_state != STATE_FINISHED) { | 
 | 255 |         PyObject *msg = PyUnicode_FromString("Result is not ready."); | 
 | 256 |         if (msg == NULL) { | 
 | 257 |             return -1; | 
 | 258 |         } | 
 | 259 |  | 
| Victor Stinner | 7bfb42d | 2016-12-05 17:04:32 +0100 | [diff] [blame] | 260 |         exc = PyObject_CallFunctionObjArgs(asyncio_InvalidStateError, msg, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 261 |         Py_DECREF(msg); | 
 | 262 |         if (exc == NULL) { | 
 | 263 |             return -1; | 
 | 264 |         } | 
 | 265 |  | 
 | 266 |         *result = exc; | 
 | 267 |         return 1; | 
 | 268 |     } | 
 | 269 |  | 
 | 270 |     fut->fut_log_tb = 0; | 
 | 271 |     if (fut->fut_exception != NULL) { | 
 | 272 |         Py_INCREF(fut->fut_exception); | 
 | 273 |         *result = fut->fut_exception; | 
 | 274 |         return 1; | 
 | 275 |     } | 
 | 276 |  | 
 | 277 |     Py_INCREF(fut->fut_result); | 
 | 278 |     *result = fut->fut_result; | 
 | 279 |     return 0; | 
 | 280 | } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 281 |  | 
 | 282 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 283 | future_add_done_callback(FutureObj *fut, PyObject *arg) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 284 | { | 
 | 285 |     if (fut->fut_state != STATE_PENDING) { | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 286 |         PyObject *handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, | 
 | 287 |                                                          &PyId_call_soon, | 
 | 288 |                                                          arg, fut, NULL); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 289 |  | 
 | 290 |         if (handle == NULL) { | 
 | 291 |             return NULL; | 
 | 292 |         } | 
 | 293 |         else { | 
 | 294 |             Py_DECREF(handle); | 
 | 295 |         } | 
 | 296 |     } | 
 | 297 |     else { | 
 | 298 |         int err = PyList_Append(fut->fut_callbacks, arg); | 
 | 299 |         if (err != 0) { | 
 | 300 |             return NULL; | 
 | 301 |         } | 
 | 302 |     } | 
 | 303 |     Py_RETURN_NONE; | 
 | 304 | } | 
 | 305 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 306 | static PyObject * | 
 | 307 | future_cancel(FutureObj *fut) | 
 | 308 | { | 
 | 309 |     if (fut->fut_state != STATE_PENDING) { | 
 | 310 |         Py_RETURN_FALSE; | 
 | 311 |     } | 
 | 312 |     fut->fut_state = STATE_CANCELLED; | 
 | 313 |  | 
 | 314 |     if (future_call_schedule_callbacks(fut) == -1) { | 
 | 315 |         return NULL; | 
 | 316 |     } | 
 | 317 |  | 
 | 318 |     Py_RETURN_TRUE; | 
 | 319 | } | 
 | 320 |  | 
 | 321 | /*[clinic input] | 
 | 322 | _asyncio.Future.__init__ | 
 | 323 |  | 
 | 324 |     * | 
 | 325 |     loop: 'O' = NULL | 
 | 326 |  | 
 | 327 | This class is *almost* compatible with concurrent.futures.Future. | 
 | 328 |  | 
 | 329 |     Differences: | 
 | 330 |  | 
 | 331 |     - result() and exception() do not take a timeout argument and | 
 | 332 |       raise an exception when the future isn't done yet. | 
 | 333 |  | 
 | 334 |     - Callbacks registered with add_done_callback() are always called | 
 | 335 |       via the event loop's call_soon_threadsafe(). | 
 | 336 |  | 
 | 337 |     - This class is not compatible with the wait() and as_completed() | 
 | 338 |       methods in the concurrent.futures package. | 
 | 339 | [clinic start generated code]*/ | 
 | 340 |  | 
 | 341 | static int | 
 | 342 | _asyncio_Future___init___impl(FutureObj *self, PyObject *loop) | 
 | 343 | /*[clinic end generated code: output=9ed75799eaccb5d6 input=8e1681f23605be2d]*/ | 
 | 344 |  | 
 | 345 | { | 
 | 346 |     return future_init(self, loop); | 
 | 347 | } | 
 | 348 |  | 
 | 349 | static int | 
 | 350 | FutureObj_clear(FutureObj *fut) | 
 | 351 | { | 
 | 352 |     Py_CLEAR(fut->fut_loop); | 
 | 353 |     Py_CLEAR(fut->fut_callbacks); | 
 | 354 |     Py_CLEAR(fut->fut_result); | 
 | 355 |     Py_CLEAR(fut->fut_exception); | 
 | 356 |     Py_CLEAR(fut->fut_source_tb); | 
 | 357 |     Py_CLEAR(fut->dict); | 
 | 358 |     return 0; | 
 | 359 | } | 
 | 360 |  | 
 | 361 | static int | 
 | 362 | FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) | 
 | 363 | { | 
 | 364 |     Py_VISIT(fut->fut_loop); | 
 | 365 |     Py_VISIT(fut->fut_callbacks); | 
 | 366 |     Py_VISIT(fut->fut_result); | 
 | 367 |     Py_VISIT(fut->fut_exception); | 
 | 368 |     Py_VISIT(fut->fut_source_tb); | 
 | 369 |     Py_VISIT(fut->dict); | 
 | 370 |     return 0; | 
 | 371 | } | 
 | 372 |  | 
 | 373 | /*[clinic input] | 
 | 374 | _asyncio.Future.result | 
 | 375 |  | 
 | 376 | Return the result this future represents. | 
 | 377 |  | 
 | 378 | If the future has been cancelled, raises CancelledError.  If the | 
 | 379 | future's result isn't yet available, raises InvalidStateError.  If | 
 | 380 | the future is done and has an exception set, this exception is raised. | 
 | 381 | [clinic start generated code]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 382 |  | 
 | 383 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 384 | _asyncio_Future_result_impl(FutureObj *self) | 
 | 385 | /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/ | 
 | 386 | { | 
 | 387 |     PyObject *result; | 
 | 388 |     int res = future_get_result(self, &result); | 
 | 389 |  | 
 | 390 |     if (res == -1) { | 
 | 391 |         return NULL; | 
 | 392 |     } | 
 | 393 |  | 
 | 394 |     if (res == 0) { | 
 | 395 |         return result; | 
 | 396 |     } | 
 | 397 |  | 
 | 398 |     assert(res == 1); | 
 | 399 |  | 
 | 400 |     PyErr_SetObject(PyExceptionInstance_Class(result), result); | 
 | 401 |     Py_DECREF(result); | 
 | 402 |     return NULL; | 
 | 403 | } | 
 | 404 |  | 
 | 405 | /*[clinic input] | 
 | 406 | _asyncio.Future.exception | 
 | 407 |  | 
 | 408 | Return the exception that was set on this future. | 
 | 409 |  | 
 | 410 | The exception (or None if no exception was set) is returned only if | 
 | 411 | the future is done.  If the future has been cancelled, raises | 
 | 412 | CancelledError.  If the future isn't done yet, raises | 
 | 413 | InvalidStateError. | 
 | 414 | [clinic start generated code]*/ | 
 | 415 |  | 
 | 416 | static PyObject * | 
 | 417 | _asyncio_Future_exception_impl(FutureObj *self) | 
 | 418 | /*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ | 
 | 419 | { | 
 | 420 |     if (self->fut_state == STATE_CANCELLED) { | 
 | 421 |         PyErr_SetString(asyncio_CancelledError, ""); | 
 | 422 |         return NULL; | 
 | 423 |     } | 
 | 424 |  | 
 | 425 |     if (self->fut_state != STATE_FINISHED) { | 
 | 426 |         PyErr_SetString(asyncio_InvalidStateError, "Result is not ready."); | 
 | 427 |         return NULL; | 
 | 428 |     } | 
 | 429 |  | 
 | 430 |     if (self->fut_exception != NULL) { | 
 | 431 |         self->fut_log_tb = 0; | 
 | 432 |         Py_INCREF(self->fut_exception); | 
 | 433 |         return self->fut_exception; | 
 | 434 |     } | 
 | 435 |  | 
 | 436 |     Py_RETURN_NONE; | 
 | 437 | } | 
 | 438 |  | 
 | 439 | /*[clinic input] | 
 | 440 | _asyncio.Future.set_result | 
 | 441 |  | 
 | 442 |     res: 'O' | 
 | 443 |     / | 
 | 444 |  | 
 | 445 | Mark the future done and set its result. | 
 | 446 |  | 
 | 447 | If the future is already done when this method is called, raises | 
 | 448 | InvalidStateError. | 
 | 449 | [clinic start generated code]*/ | 
 | 450 |  | 
 | 451 | static PyObject * | 
 | 452 | _asyncio_Future_set_result(FutureObj *self, PyObject *res) | 
 | 453 | /*[clinic end generated code: output=a620abfc2796bfb6 input=8619565e0503357e]*/ | 
 | 454 | { | 
 | 455 |     return future_set_result(self, res); | 
 | 456 | } | 
 | 457 |  | 
 | 458 | /*[clinic input] | 
 | 459 | _asyncio.Future.set_exception | 
 | 460 |  | 
 | 461 |     exception: 'O' | 
 | 462 |     / | 
 | 463 |  | 
 | 464 | Mark the future done and set an exception. | 
 | 465 |  | 
 | 466 | If the future is already done when this method is called, raises | 
 | 467 | InvalidStateError. | 
 | 468 | [clinic start generated code]*/ | 
 | 469 |  | 
 | 470 | static PyObject * | 
 | 471 | _asyncio_Future_set_exception(FutureObj *self, PyObject *exception) | 
 | 472 | /*[clinic end generated code: output=f1c1b0cd321be360 input=1377dbe15e6ea186]*/ | 
 | 473 | { | 
 | 474 |     return future_set_exception(self, exception); | 
 | 475 | } | 
 | 476 |  | 
 | 477 | /*[clinic input] | 
 | 478 | _asyncio.Future.add_done_callback | 
 | 479 |  | 
 | 480 |     fn: 'O' | 
 | 481 |     / | 
 | 482 |  | 
 | 483 | Add a callback to be run when the future becomes done. | 
 | 484 |  | 
 | 485 | The callback is called with a single argument - the future object. If | 
 | 486 | the future is already done when this is called, the callback is | 
 | 487 | scheduled with call_soon. | 
 | 488 | [clinic start generated code]*/ | 
 | 489 |  | 
 | 490 | static PyObject * | 
 | 491 | _asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn) | 
 | 492 | /*[clinic end generated code: output=819e09629b2ec2b5 input=8cce187e32cec6a8]*/ | 
 | 493 | { | 
 | 494 |     return future_add_done_callback(self, fn); | 
 | 495 | } | 
 | 496 |  | 
 | 497 | /*[clinic input] | 
 | 498 | _asyncio.Future.remove_done_callback | 
 | 499 |  | 
 | 500 |     fn: 'O' | 
 | 501 |     / | 
 | 502 |  | 
 | 503 | Remove all instances of a callback from the "call when done" list. | 
 | 504 |  | 
 | 505 | Returns the number of callbacks removed. | 
 | 506 | [clinic start generated code]*/ | 
 | 507 |  | 
 | 508 | static PyObject * | 
 | 509 | _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) | 
 | 510 | /*[clinic end generated code: output=5ab1fb52b24ef31f input=3fedb73e1409c31c]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 511 | { | 
 | 512 |     PyObject *newlist; | 
 | 513 |     Py_ssize_t len, i, j=0; | 
 | 514 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 515 |     len = PyList_GET_SIZE(self->fut_callbacks); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 516 |     if (len == 0) { | 
 | 517 |         return PyLong_FromSsize_t(0); | 
 | 518 |     } | 
 | 519 |  | 
 | 520 |     newlist = PyList_New(len); | 
 | 521 |     if (newlist == NULL) { | 
 | 522 |         return NULL; | 
 | 523 |     } | 
 | 524 |  | 
| Yury Selivanov | 84af903 | 2017-03-02 23:46:56 -0500 | [diff] [blame] | 525 |     for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 526 |         int ret; | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 527 |         PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 528 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 529 |         if ((ret = PyObject_RichCompareBool(fn, item, Py_EQ)) < 0) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 530 |             goto fail; | 
 | 531 |         } | 
 | 532 |         if (ret == 0) { | 
 | 533 |             Py_INCREF(item); | 
 | 534 |             PyList_SET_ITEM(newlist, j, item); | 
 | 535 |             j++; | 
 | 536 |         } | 
 | 537 |     } | 
 | 538 |  | 
 | 539 |     if (PyList_SetSlice(newlist, j, len, NULL) < 0) { | 
 | 540 |         goto fail; | 
 | 541 |     } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 542 |     if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 543 |         goto fail; | 
 | 544 |     } | 
 | 545 |     Py_DECREF(newlist); | 
 | 546 |     return PyLong_FromSsize_t(len - j); | 
 | 547 |  | 
 | 548 | fail: | 
 | 549 |     Py_DECREF(newlist); | 
 | 550 |     return NULL; | 
 | 551 | } | 
 | 552 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 553 | /*[clinic input] | 
 | 554 | _asyncio.Future.cancel | 
 | 555 |  | 
 | 556 | Cancel the future and schedule callbacks. | 
 | 557 |  | 
 | 558 | If the future is already done or cancelled, return False.  Otherwise, | 
 | 559 | change the future's state to cancelled, schedule the callbacks and | 
 | 560 | return True. | 
 | 561 | [clinic start generated code]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 562 |  | 
 | 563 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 564 | _asyncio_Future_cancel_impl(FutureObj *self) | 
 | 565 | /*[clinic end generated code: output=e45b932ba8bd68a1 input=515709a127995109]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 566 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 567 |     return future_cancel(self); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 568 | } | 
 | 569 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 570 | /*[clinic input] | 
 | 571 | _asyncio.Future.cancelled | 
 | 572 |  | 
 | 573 | Return True if the future was cancelled. | 
 | 574 | [clinic start generated code]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 575 |  | 
 | 576 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 577 | _asyncio_Future_cancelled_impl(FutureObj *self) | 
 | 578 | /*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 579 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 580 |     if (self->fut_state == STATE_CANCELLED) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 581 |         Py_RETURN_TRUE; | 
 | 582 |     } | 
 | 583 |     else { | 
 | 584 |         Py_RETURN_FALSE; | 
 | 585 |     } | 
 | 586 | } | 
 | 587 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 588 | /*[clinic input] | 
 | 589 | _asyncio.Future.done | 
 | 590 |  | 
 | 591 | Return True if the future is done. | 
 | 592 |  | 
 | 593 | Done means either that a result / exception are available, or that the | 
 | 594 | future was cancelled. | 
 | 595 | [clinic start generated code]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 596 |  | 
 | 597 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 598 | _asyncio_Future_done_impl(FutureObj *self) | 
 | 599 | /*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 600 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 601 |     if (self->fut_state == STATE_PENDING) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 602 |         Py_RETURN_FALSE; | 
 | 603 |     } | 
 | 604 |     else { | 
 | 605 |         Py_RETURN_TRUE; | 
 | 606 |     } | 
 | 607 | } | 
 | 608 |  | 
 | 609 | static PyObject * | 
 | 610 | FutureObj_get_blocking(FutureObj *fut) | 
 | 611 | { | 
 | 612 |     if (fut->fut_blocking) { | 
 | 613 |         Py_RETURN_TRUE; | 
 | 614 |     } | 
 | 615 |     else { | 
 | 616 |         Py_RETURN_FALSE; | 
 | 617 |     } | 
 | 618 | } | 
 | 619 |  | 
 | 620 | static int | 
 | 621 | FutureObj_set_blocking(FutureObj *fut, PyObject *val) | 
 | 622 | { | 
 | 623 |     int is_true = PyObject_IsTrue(val); | 
 | 624 |     if (is_true < 0) { | 
 | 625 |         return -1; | 
 | 626 |     } | 
 | 627 |     fut->fut_blocking = is_true; | 
 | 628 |     return 0; | 
 | 629 | } | 
 | 630 |  | 
 | 631 | static PyObject * | 
 | 632 | FutureObj_get_log_traceback(FutureObj *fut) | 
 | 633 | { | 
 | 634 |     if (fut->fut_log_tb) { | 
 | 635 |         Py_RETURN_TRUE; | 
 | 636 |     } | 
 | 637 |     else { | 
 | 638 |         Py_RETURN_FALSE; | 
 | 639 |     } | 
 | 640 | } | 
 | 641 |  | 
 | 642 | static PyObject * | 
 | 643 | FutureObj_get_loop(FutureObj *fut) | 
 | 644 | { | 
 | 645 |     if (fut->fut_loop == NULL) { | 
 | 646 |         Py_RETURN_NONE; | 
 | 647 |     } | 
 | 648 |     Py_INCREF(fut->fut_loop); | 
 | 649 |     return fut->fut_loop; | 
 | 650 | } | 
 | 651 |  | 
 | 652 | static PyObject * | 
 | 653 | FutureObj_get_callbacks(FutureObj *fut) | 
 | 654 | { | 
 | 655 |     if (fut->fut_callbacks == NULL) { | 
 | 656 |         Py_RETURN_NONE; | 
 | 657 |     } | 
 | 658 |     Py_INCREF(fut->fut_callbacks); | 
 | 659 |     return fut->fut_callbacks; | 
 | 660 | } | 
 | 661 |  | 
 | 662 | static PyObject * | 
 | 663 | FutureObj_get_result(FutureObj *fut) | 
 | 664 | { | 
 | 665 |     if (fut->fut_result == NULL) { | 
 | 666 |         Py_RETURN_NONE; | 
 | 667 |     } | 
 | 668 |     Py_INCREF(fut->fut_result); | 
 | 669 |     return fut->fut_result; | 
 | 670 | } | 
 | 671 |  | 
 | 672 | static PyObject * | 
 | 673 | FutureObj_get_exception(FutureObj *fut) | 
 | 674 | { | 
 | 675 |     if (fut->fut_exception == NULL) { | 
 | 676 |         Py_RETURN_NONE; | 
 | 677 |     } | 
 | 678 |     Py_INCREF(fut->fut_exception); | 
 | 679 |     return fut->fut_exception; | 
 | 680 | } | 
 | 681 |  | 
 | 682 | static PyObject * | 
 | 683 | FutureObj_get_source_traceback(FutureObj *fut) | 
 | 684 | { | 
 | 685 |     if (fut->fut_source_tb == NULL) { | 
 | 686 |         Py_RETURN_NONE; | 
 | 687 |     } | 
 | 688 |     Py_INCREF(fut->fut_source_tb); | 
 | 689 |     return fut->fut_source_tb; | 
 | 690 | } | 
 | 691 |  | 
 | 692 | static PyObject * | 
 | 693 | FutureObj_get_state(FutureObj *fut) | 
 | 694 | { | 
 | 695 |     _Py_IDENTIFIER(PENDING); | 
 | 696 |     _Py_IDENTIFIER(CANCELLED); | 
 | 697 |     _Py_IDENTIFIER(FINISHED); | 
 | 698 |     PyObject *ret = NULL; | 
 | 699 |  | 
 | 700 |     switch (fut->fut_state) { | 
 | 701 |     case STATE_PENDING: | 
 | 702 |         ret = _PyUnicode_FromId(&PyId_PENDING); | 
 | 703 |         break; | 
 | 704 |     case STATE_CANCELLED: | 
 | 705 |         ret = _PyUnicode_FromId(&PyId_CANCELLED); | 
 | 706 |         break; | 
 | 707 |     case STATE_FINISHED: | 
 | 708 |         ret = _PyUnicode_FromId(&PyId_FINISHED); | 
 | 709 |         break; | 
 | 710 |     default: | 
 | 711 |         assert (0); | 
 | 712 |     } | 
 | 713 |     Py_INCREF(ret); | 
 | 714 |     return ret; | 
 | 715 | } | 
 | 716 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 717 | /*[clinic input] | 
 | 718 | _asyncio.Future._repr_info | 
 | 719 | [clinic start generated code]*/ | 
 | 720 |  | 
 | 721 | static PyObject * | 
 | 722 | _asyncio_Future__repr_info_impl(FutureObj *self) | 
 | 723 | /*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 724 | { | 
| Victor Stinner | de4ae3d | 2016-12-04 22:59:09 +0100 | [diff] [blame] | 725 |     return PyObject_CallFunctionObjArgs( | 
 | 726 |         asyncio_future_repr_info_func, self, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 727 | } | 
 | 728 |  | 
 | 729 | /*[clinic input] | 
 | 730 | _asyncio.Future._schedule_callbacks | 
 | 731 | [clinic start generated code]*/ | 
 | 732 |  | 
 | 733 | static PyObject * | 
 | 734 | _asyncio_Future__schedule_callbacks_impl(FutureObj *self) | 
 | 735 | /*[clinic end generated code: output=5e8958d89ea1c5dc input=4f5f295f263f4a88]*/ | 
 | 736 | { | 
 | 737 |     int ret = future_schedule_callbacks(self); | 
 | 738 |     if (ret == -1) { | 
 | 739 |         return NULL; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 740 |     } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 741 |     Py_RETURN_NONE; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 742 | } | 
 | 743 |  | 
 | 744 | static PyObject * | 
 | 745 | FutureObj_repr(FutureObj *fut) | 
 | 746 | { | 
 | 747 |     _Py_IDENTIFIER(_repr_info); | 
 | 748 |  | 
 | 749 |     PyObject *_repr_info = _PyUnicode_FromId(&PyId__repr_info);  // borrowed | 
 | 750 |     if (_repr_info == NULL) { | 
 | 751 |         return NULL; | 
 | 752 |     } | 
 | 753 |  | 
 | 754 |     PyObject *rinfo = PyObject_CallMethodObjArgs((PyObject*)fut, _repr_info, | 
 | 755 |                                                  NULL); | 
 | 756 |     if (rinfo == NULL) { | 
 | 757 |         return NULL; | 
 | 758 |     } | 
 | 759 |  | 
 | 760 |     PyObject *sp = PyUnicode_FromString(" "); | 
 | 761 |     if (sp == NULL) { | 
 | 762 |         Py_DECREF(rinfo); | 
 | 763 |         return NULL; | 
 | 764 |     } | 
 | 765 |  | 
 | 766 |     PyObject *rinfo_s = PyUnicode_Join(sp, rinfo); | 
 | 767 |     Py_DECREF(sp); | 
 | 768 |     Py_DECREF(rinfo); | 
 | 769 |     if (rinfo_s == NULL) { | 
 | 770 |         return NULL; | 
 | 771 |     } | 
 | 772 |  | 
 | 773 |     PyObject *rstr = NULL; | 
 | 774 |     PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), | 
 | 775 |                                                  "__name__"); | 
 | 776 |     if (type_name != NULL) { | 
 | 777 |         rstr = PyUnicode_FromFormat("<%S %S>", type_name, rinfo_s); | 
 | 778 |         Py_DECREF(type_name); | 
 | 779 |     } | 
 | 780 |     Py_DECREF(rinfo_s); | 
 | 781 |     return rstr; | 
 | 782 | } | 
 | 783 |  | 
 | 784 | static void | 
 | 785 | FutureObj_finalize(FutureObj *fut) | 
 | 786 | { | 
 | 787 |     _Py_IDENTIFIER(call_exception_handler); | 
 | 788 |     _Py_IDENTIFIER(message); | 
 | 789 |     _Py_IDENTIFIER(exception); | 
 | 790 |     _Py_IDENTIFIER(future); | 
 | 791 |     _Py_IDENTIFIER(source_traceback); | 
 | 792 |  | 
 | 793 |     if (!fut->fut_log_tb) { | 
 | 794 |         return; | 
 | 795 |     } | 
 | 796 |     assert(fut->fut_exception != NULL); | 
 | 797 |     fut->fut_log_tb = 0;; | 
 | 798 |  | 
 | 799 |     PyObject *error_type, *error_value, *error_traceback; | 
 | 800 |     /* Save the current exception, if any. */ | 
 | 801 |     PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
 | 802 |  | 
 | 803 |     PyObject *context = NULL; | 
 | 804 |     PyObject *type_name = NULL; | 
 | 805 |     PyObject *message = NULL; | 
 | 806 |     PyObject *func = NULL; | 
 | 807 |     PyObject *res = NULL; | 
 | 808 |  | 
 | 809 |     context = PyDict_New(); | 
 | 810 |     if (context == NULL) { | 
 | 811 |         goto finally; | 
 | 812 |     } | 
 | 813 |  | 
 | 814 |     type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__"); | 
 | 815 |     if (type_name == NULL) { | 
 | 816 |         goto finally; | 
 | 817 |     } | 
 | 818 |  | 
 | 819 |     message = PyUnicode_FromFormat( | 
 | 820 |         "%S exception was never retrieved", type_name); | 
 | 821 |     if (message == NULL) { | 
 | 822 |         goto finally; | 
 | 823 |     } | 
 | 824 |  | 
 | 825 |     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || | 
 | 826 |         _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || | 
 | 827 |         _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { | 
 | 828 |         goto finally; | 
 | 829 |     } | 
 | 830 |     if (fut->fut_source_tb != NULL) { | 
 | 831 |         if (_PyDict_SetItemId(context, &PyId_source_traceback, | 
 | 832 |                               fut->fut_source_tb) < 0) { | 
 | 833 |             goto finally; | 
 | 834 |         } | 
 | 835 |     } | 
 | 836 |  | 
 | 837 |     func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); | 
 | 838 |     if (func != NULL) { | 
| Victor Stinner | 7bfb42d | 2016-12-05 17:04:32 +0100 | [diff] [blame] | 839 |         res = PyObject_CallFunctionObjArgs(func, context, NULL); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 840 |         if (res == NULL) { | 
 | 841 |             PyErr_WriteUnraisable(func); | 
 | 842 |         } | 
 | 843 |     } | 
 | 844 |  | 
 | 845 | finally: | 
 | 846 |     Py_CLEAR(context); | 
 | 847 |     Py_CLEAR(type_name); | 
 | 848 |     Py_CLEAR(message); | 
 | 849 |     Py_CLEAR(func); | 
 | 850 |     Py_CLEAR(res); | 
 | 851 |  | 
 | 852 |     /* Restore the saved exception. */ | 
 | 853 |     PyErr_Restore(error_type, error_value, error_traceback); | 
 | 854 | } | 
 | 855 |  | 
 | 856 |  | 
 | 857 | static PyAsyncMethods FutureType_as_async = { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 858 |     (unaryfunc)future_new_iter,         /* am_await */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 859 |     0,                                  /* am_aiter */ | 
 | 860 |     0                                   /* am_anext */ | 
 | 861 | }; | 
 | 862 |  | 
 | 863 | static PyMethodDef FutureType_methods[] = { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 864 |     _ASYNCIO_FUTURE_RESULT_METHODDEF | 
 | 865 |     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF | 
 | 866 |     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF | 
 | 867 |     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF | 
 | 868 |     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF | 
 | 869 |     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF | 
 | 870 |     _ASYNCIO_FUTURE_CANCEL_METHODDEF | 
 | 871 |     _ASYNCIO_FUTURE_CANCELLED_METHODDEF | 
 | 872 |     _ASYNCIO_FUTURE_DONE_METHODDEF | 
 | 873 |     _ASYNCIO_FUTURE__REPR_INFO_METHODDEF | 
 | 874 |     _ASYNCIO_FUTURE__SCHEDULE_CALLBACKS_METHODDEF | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 875 |     {NULL, NULL}        /* Sentinel */ | 
 | 876 | }; | 
 | 877 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 878 | #define FUTURE_COMMON_GETSETLIST                                              \ | 
 | 879 |     {"_state", (getter)FutureObj_get_state, NULL, NULL},                      \ | 
 | 880 |     {"_asyncio_future_blocking", (getter)FutureObj_get_blocking,              \ | 
 | 881 |                                  (setter)FutureObj_set_blocking, NULL},       \ | 
 | 882 |     {"_loop", (getter)FutureObj_get_loop, NULL, NULL},                        \ | 
 | 883 |     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \ | 
 | 884 |     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \ | 
 | 885 |     {"_exception", (getter)FutureObj_get_exception, NULL, NULL},              \ | 
 | 886 |     {"_log_traceback", (getter)FutureObj_get_log_traceback, NULL, NULL},      \ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 887 |     {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL}, | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 888 |  | 
 | 889 | static PyGetSetDef FutureType_getsetlist[] = { | 
 | 890 |     FUTURE_COMMON_GETSETLIST | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 891 |     {NULL} /* Sentinel */ | 
 | 892 | }; | 
 | 893 |  | 
 | 894 | static void FutureObj_dealloc(PyObject *self); | 
 | 895 |  | 
 | 896 | static PyTypeObject FutureType = { | 
| Victor Stinner | 1aea8fb | 2016-10-28 19:13:52 +0200 | [diff] [blame] | 897 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 898 |     "_asyncio.Future", | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 899 |     sizeof(FutureObj),                       /* tp_basicsize */ | 
 | 900 |     .tp_dealloc = FutureObj_dealloc, | 
 | 901 |     .tp_as_async = &FutureType_as_async, | 
 | 902 |     .tp_repr = (reprfunc)FutureObj_repr, | 
 | 903 |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 
 | 904 |         | Py_TPFLAGS_HAVE_FINALIZE, | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 905 |     .tp_doc = _asyncio_Future___init____doc__, | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 906 |     .tp_traverse = (traverseproc)FutureObj_traverse, | 
 | 907 |     .tp_clear = (inquiry)FutureObj_clear, | 
 | 908 |     .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 909 |     .tp_iter = (getiterfunc)future_new_iter, | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 910 |     .tp_methods = FutureType_methods, | 
 | 911 |     .tp_getset = FutureType_getsetlist, | 
 | 912 |     .tp_dictoffset = offsetof(FutureObj, dict), | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 913 |     .tp_init = (initproc)_asyncio_Future___init__, | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 914 |     .tp_new = PyType_GenericNew, | 
 | 915 |     .tp_finalize = (destructor)FutureObj_finalize, | 
 | 916 | }; | 
 | 917 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 918 | #define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType) | 
 | 919 |  | 
 | 920 | static inline int | 
 | 921 | future_call_schedule_callbacks(FutureObj *fut) | 
 | 922 | { | 
 | 923 |     if (Future_CheckExact(fut)) { | 
 | 924 |         return future_schedule_callbacks(fut); | 
 | 925 |     } | 
 | 926 |     else { | 
 | 927 |         /* `fut` is a subclass of Future */ | 
 | 928 |         PyObject *ret = _PyObject_CallMethodId( | 
 | 929 |             (PyObject*)fut, &PyId__schedule_callbacks, NULL); | 
 | 930 |         if (ret == NULL) { | 
 | 931 |             return -1; | 
 | 932 |         } | 
 | 933 |  | 
 | 934 |         Py_DECREF(ret); | 
 | 935 |         return 0; | 
 | 936 |     } | 
 | 937 | } | 
 | 938 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 939 | static void | 
 | 940 | FutureObj_dealloc(PyObject *self) | 
 | 941 | { | 
 | 942 |     FutureObj *fut = (FutureObj *)self; | 
 | 943 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 944 |     if (Future_CheckExact(fut)) { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 945 |         /* When fut is subclass of Future, finalizer is called from | 
 | 946 |          * subtype_dealloc. | 
 | 947 |          */ | 
 | 948 |         if (PyObject_CallFinalizerFromDealloc(self) < 0) { | 
 | 949 |             // resurrected. | 
 | 950 |             return; | 
 | 951 |         } | 
 | 952 |     } | 
 | 953 |  | 
 | 954 |     if (fut->fut_weakreflist != NULL) { | 
 | 955 |         PyObject_ClearWeakRefs(self); | 
 | 956 |     } | 
 | 957 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 958 |     (void)FutureObj_clear(fut); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 959 |     Py_TYPE(fut)->tp_free(fut); | 
 | 960 | } | 
 | 961 |  | 
 | 962 |  | 
 | 963 | /*********************** Future Iterator **************************/ | 
 | 964 |  | 
 | 965 | typedef struct { | 
 | 966 |     PyObject_HEAD | 
 | 967 |     FutureObj *future; | 
 | 968 | } futureiterobject; | 
 | 969 |  | 
 | 970 | static void | 
 | 971 | FutureIter_dealloc(futureiterobject *it) | 
 | 972 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 973 |     PyObject_GC_UnTrack(it); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 974 |     Py_XDECREF(it->future); | 
 | 975 |     PyObject_GC_Del(it); | 
 | 976 | } | 
 | 977 |  | 
 | 978 | static PyObject * | 
 | 979 | FutureIter_iternext(futureiterobject *it) | 
 | 980 | { | 
 | 981 |     PyObject *res; | 
 | 982 |     FutureObj *fut = it->future; | 
 | 983 |  | 
 | 984 |     if (fut == NULL) { | 
 | 985 |         return NULL; | 
 | 986 |     } | 
 | 987 |  | 
 | 988 |     if (fut->fut_state == STATE_PENDING) { | 
 | 989 |         if (!fut->fut_blocking) { | 
 | 990 |             fut->fut_blocking = 1; | 
 | 991 |             Py_INCREF(fut); | 
 | 992 |             return (PyObject *)fut; | 
 | 993 |         } | 
 | 994 |         PyErr_Format(PyExc_AssertionError, | 
 | 995 |                      "yield from wasn't used with future"); | 
 | 996 |         return NULL; | 
 | 997 |     } | 
 | 998 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 999 |     res = _asyncio_Future_result_impl(fut); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1000 |     if (res != NULL) { | 
| Serhiy Storchaka | 60e49aa | 2016-11-06 18:47:03 +0200 | [diff] [blame] | 1001 |         /* The result of the Future is not an exception. */ | 
 | 1002 |         if (_PyGen_SetStopIterationValue(res) < 0) { | 
 | 1003 |             Py_DECREF(res); | 
| Yury Selivanov | a4b884f | 2016-10-20 15:54:20 -0400 | [diff] [blame] | 1004 |             return NULL; | 
 | 1005 |         } | 
| Serhiy Storchaka | 60e49aa | 2016-11-06 18:47:03 +0200 | [diff] [blame] | 1006 |         Py_DECREF(res); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1007 |     } | 
 | 1008 |  | 
 | 1009 |     it->future = NULL; | 
 | 1010 |     Py_DECREF(fut); | 
 | 1011 |     return NULL; | 
 | 1012 | } | 
 | 1013 |  | 
 | 1014 | static PyObject * | 
| INADA Naoki | 74c1753 | 2016-10-25 19:00:45 +0900 | [diff] [blame] | 1015 | FutureIter_send(futureiterobject *self, PyObject *unused) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1016 | { | 
| INADA Naoki | 74c1753 | 2016-10-25 19:00:45 +0900 | [diff] [blame] | 1017 |     /* Future.__iter__ doesn't care about values that are pushed to the | 
 | 1018 |      * generator, it just returns "self.result(). | 
 | 1019 |      */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1020 |     return FutureIter_iternext(self); | 
 | 1021 | } | 
 | 1022 |  | 
 | 1023 | static PyObject * | 
 | 1024 | FutureIter_throw(futureiterobject *self, PyObject *args) | 
 | 1025 | { | 
 | 1026 |     PyObject *type=NULL, *val=NULL, *tb=NULL; | 
 | 1027 |     if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) | 
 | 1028 |         return NULL; | 
 | 1029 |  | 
 | 1030 |     if (val == Py_None) { | 
 | 1031 |         val = NULL; | 
 | 1032 |     } | 
 | 1033 |     if (tb == Py_None) { | 
 | 1034 |         tb = NULL; | 
| Benjamin Peterson | 996fc1f | 2016-11-14 00:15:44 -0800 | [diff] [blame] | 1035 |     } else if (tb != NULL && !PyTraceBack_Check(tb)) { | 
 | 1036 |         PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback"); | 
 | 1037 |         return NULL; | 
 | 1038 |     } | 
 | 1039 |  | 
 | 1040 |     Py_INCREF(type); | 
 | 1041 |     Py_XINCREF(val); | 
 | 1042 |     Py_XINCREF(tb); | 
 | 1043 |  | 
 | 1044 |     if (PyExceptionClass_Check(type)) { | 
 | 1045 |         PyErr_NormalizeException(&type, &val, &tb); | 
| Yury Selivanov | edfe886 | 2016-12-01 11:37:47 -0500 | [diff] [blame] | 1046 |         /* No need to call PyException_SetTraceback since we'll be calling | 
 | 1047 |            PyErr_Restore for `type`, `val`, and `tb`. */ | 
| Benjamin Peterson | 996fc1f | 2016-11-14 00:15:44 -0800 | [diff] [blame] | 1048 |     } else if (PyExceptionInstance_Check(type)) { | 
 | 1049 |         if (val) { | 
 | 1050 |             PyErr_SetString(PyExc_TypeError, | 
 | 1051 |                             "instance exception may not have a separate value"); | 
 | 1052 |             goto fail; | 
 | 1053 |         } | 
 | 1054 |         val = type; | 
 | 1055 |         type = PyExceptionInstance_Class(type); | 
 | 1056 |         Py_INCREF(type); | 
 | 1057 |         if (tb == NULL) | 
 | 1058 |             tb = PyException_GetTraceback(val); | 
 | 1059 |     } else { | 
 | 1060 |         PyErr_SetString(PyExc_TypeError, | 
 | 1061 |                         "exceptions must be classes deriving BaseException or " | 
 | 1062 |                         "instances of such a class"); | 
 | 1063 |         goto fail; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1064 |     } | 
 | 1065 |  | 
 | 1066 |     Py_CLEAR(self->future); | 
 | 1067 |  | 
| Benjamin Peterson | 996fc1f | 2016-11-14 00:15:44 -0800 | [diff] [blame] | 1068 |     PyErr_Restore(type, val, tb); | 
 | 1069 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1070 |     return FutureIter_iternext(self); | 
| Benjamin Peterson | 996fc1f | 2016-11-14 00:15:44 -0800 | [diff] [blame] | 1071 |  | 
 | 1072 |   fail: | 
 | 1073 |     Py_DECREF(type); | 
 | 1074 |     Py_XDECREF(val); | 
 | 1075 |     Py_XDECREF(tb); | 
 | 1076 |     return NULL; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1077 | } | 
 | 1078 |  | 
 | 1079 | static PyObject * | 
 | 1080 | FutureIter_close(futureiterobject *self, PyObject *arg) | 
 | 1081 | { | 
 | 1082 |     Py_CLEAR(self->future); | 
 | 1083 |     Py_RETURN_NONE; | 
 | 1084 | } | 
 | 1085 |  | 
 | 1086 | static int | 
 | 1087 | FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) | 
 | 1088 | { | 
 | 1089 |     Py_VISIT(it->future); | 
 | 1090 |     return 0; | 
 | 1091 | } | 
 | 1092 |  | 
 | 1093 | static PyMethodDef FutureIter_methods[] = { | 
 | 1094 |     {"send",  (PyCFunction)FutureIter_send, METH_O, NULL}, | 
 | 1095 |     {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, | 
 | 1096 |     {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, | 
 | 1097 |     {NULL, NULL}        /* Sentinel */ | 
 | 1098 | }; | 
 | 1099 |  | 
 | 1100 | static PyTypeObject FutureIterType = { | 
| Victor Stinner | 1aea8fb | 2016-10-28 19:13:52 +0200 | [diff] [blame] | 1101 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 1102 |     "_asyncio.FutureIter", | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1103 |     .tp_basicsize = sizeof(futureiterobject), | 
 | 1104 |     .tp_itemsize = 0, | 
 | 1105 |     .tp_dealloc = (destructor)FutureIter_dealloc, | 
 | 1106 |     .tp_getattro = PyObject_GenericGetAttr, | 
 | 1107 |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, | 
 | 1108 |     .tp_traverse = (traverseproc)FutureIter_traverse, | 
 | 1109 |     .tp_iter = PyObject_SelfIter, | 
 | 1110 |     .tp_iternext = (iternextfunc)FutureIter_iternext, | 
 | 1111 |     .tp_methods = FutureIter_methods, | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1112 | }; | 
 | 1113 |  | 
 | 1114 | static PyObject * | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1115 | future_new_iter(PyObject *fut) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1116 | { | 
 | 1117 |     futureiterobject *it; | 
 | 1118 |  | 
 | 1119 |     if (!PyObject_TypeCheck(fut, &FutureType)) { | 
 | 1120 |         PyErr_BadInternalCall(); | 
 | 1121 |         return NULL; | 
 | 1122 |     } | 
 | 1123 |     it = PyObject_GC_New(futureiterobject, &FutureIterType); | 
 | 1124 |     if (it == NULL) { | 
 | 1125 |         return NULL; | 
 | 1126 |     } | 
 | 1127 |     Py_INCREF(fut); | 
 | 1128 |     it->future = (FutureObj*)fut; | 
| INADA Naoki | 1be427b | 2016-10-11 02:12:34 +0900 | [diff] [blame] | 1129 |     PyObject_GC_Track(it); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1130 |     return (PyObject*)it; | 
 | 1131 | } | 
 | 1132 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1133 |  | 
 | 1134 | /*********************** Task **************************/ | 
 | 1135 |  | 
 | 1136 |  | 
 | 1137 | /*[clinic input] | 
 | 1138 | class _asyncio.Task "TaskObj *" "&Task_Type" | 
 | 1139 | [clinic start generated code]*/ | 
 | 1140 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/ | 
 | 1141 |  | 
 | 1142 | static int task_call_step_soon(TaskObj *, PyObject *); | 
 | 1143 | static inline PyObject * task_call_wakeup(TaskObj *, PyObject *); | 
 | 1144 | static inline PyObject * task_call_step(TaskObj *, PyObject *); | 
 | 1145 | static PyObject * task_wakeup(TaskObj *, PyObject *); | 
 | 1146 | static PyObject * task_step(TaskObj *, PyObject *); | 
 | 1147 |  | 
 | 1148 | /* ----- Task._step wrapper */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1149 |  | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1150 | static int | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1151 | TaskSendMethWrapper_clear(TaskSendMethWrapper *o) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1152 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1153 |     Py_CLEAR(o->sw_task); | 
 | 1154 |     Py_CLEAR(o->sw_arg); | 
 | 1155 |     return 0; | 
 | 1156 | } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1157 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1158 | static void | 
 | 1159 | TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o) | 
 | 1160 | { | 
 | 1161 |     PyObject_GC_UnTrack(o); | 
 | 1162 |     (void)TaskSendMethWrapper_clear(o); | 
 | 1163 |     Py_TYPE(o)->tp_free(o); | 
 | 1164 | } | 
 | 1165 |  | 
 | 1166 | static PyObject * | 
 | 1167 | TaskSendMethWrapper_call(TaskSendMethWrapper *o, | 
 | 1168 |                          PyObject *args, PyObject *kwds) | 
 | 1169 | { | 
 | 1170 |     return task_call_step(o->sw_task, o->sw_arg); | 
 | 1171 | } | 
 | 1172 |  | 
 | 1173 | static int | 
 | 1174 | TaskSendMethWrapper_traverse(TaskSendMethWrapper *o, | 
 | 1175 |                              visitproc visit, void *arg) | 
 | 1176 | { | 
 | 1177 |     Py_VISIT(o->sw_task); | 
 | 1178 |     Py_VISIT(o->sw_arg); | 
 | 1179 |     return 0; | 
 | 1180 | } | 
 | 1181 |  | 
 | 1182 | static PyObject * | 
 | 1183 | TaskSendMethWrapper_get___self__(TaskSendMethWrapper *o) | 
 | 1184 | { | 
 | 1185 |     if (o->sw_task) { | 
 | 1186 |         Py_INCREF(o->sw_task); | 
 | 1187 |         return (PyObject*)o->sw_task; | 
 | 1188 |     } | 
 | 1189 |     Py_RETURN_NONE; | 
 | 1190 | } | 
 | 1191 |  | 
 | 1192 | static PyGetSetDef TaskSendMethWrapper_getsetlist[] = { | 
 | 1193 |     {"__self__", (getter)TaskSendMethWrapper_get___self__, NULL, NULL}, | 
 | 1194 |     {NULL} /* Sentinel */ | 
 | 1195 | }; | 
 | 1196 |  | 
 | 1197 | PyTypeObject TaskSendMethWrapper_Type = { | 
| Victor Stinner | 1aea8fb | 2016-10-28 19:13:52 +0200 | [diff] [blame] | 1198 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1199 |     "TaskSendMethWrapper", | 
 | 1200 |     .tp_basicsize = sizeof(TaskSendMethWrapper), | 
 | 1201 |     .tp_itemsize = 0, | 
 | 1202 |     .tp_getset = TaskSendMethWrapper_getsetlist, | 
 | 1203 |     .tp_dealloc = (destructor)TaskSendMethWrapper_dealloc, | 
 | 1204 |     .tp_call = (ternaryfunc)TaskSendMethWrapper_call, | 
 | 1205 |     .tp_getattro = PyObject_GenericGetAttr, | 
 | 1206 |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, | 
 | 1207 |     .tp_traverse = (traverseproc)TaskSendMethWrapper_traverse, | 
 | 1208 |     .tp_clear = (inquiry)TaskSendMethWrapper_clear, | 
 | 1209 | }; | 
 | 1210 |  | 
 | 1211 | static PyObject * | 
 | 1212 | TaskSendMethWrapper_new(TaskObj *task, PyObject *arg) | 
 | 1213 | { | 
 | 1214 |     TaskSendMethWrapper *o; | 
 | 1215 |     o = PyObject_GC_New(TaskSendMethWrapper, &TaskSendMethWrapper_Type); | 
 | 1216 |     if (o == NULL) { | 
 | 1217 |         return NULL; | 
 | 1218 |     } | 
 | 1219 |  | 
 | 1220 |     Py_INCREF(task); | 
 | 1221 |     o->sw_task = task; | 
 | 1222 |  | 
 | 1223 |     Py_XINCREF(arg); | 
 | 1224 |     o->sw_arg = arg; | 
 | 1225 |  | 
 | 1226 |     PyObject_GC_Track(o); | 
 | 1227 |     return (PyObject*) o; | 
 | 1228 | } | 
 | 1229 |  | 
 | 1230 | /* ----- Task._wakeup wrapper */ | 
 | 1231 |  | 
 | 1232 | static PyObject * | 
 | 1233 | TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o, | 
 | 1234 |                            PyObject *args, PyObject *kwds) | 
 | 1235 | { | 
 | 1236 |     PyObject *fut; | 
 | 1237 |  | 
 | 1238 |     if (!PyArg_ParseTuple(args, "O|", &fut)) { | 
 | 1239 |         return NULL; | 
 | 1240 |     } | 
 | 1241 |  | 
 | 1242 |     return task_call_wakeup(o->ww_task, fut); | 
 | 1243 | } | 
 | 1244 |  | 
 | 1245 | static int | 
 | 1246 | TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o) | 
 | 1247 | { | 
 | 1248 |     Py_CLEAR(o->ww_task); | 
 | 1249 |     return 0; | 
 | 1250 | } | 
 | 1251 |  | 
 | 1252 | static int | 
 | 1253 | TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, | 
 | 1254 |                                visitproc visit, void *arg) | 
 | 1255 | { | 
 | 1256 |     Py_VISIT(o->ww_task); | 
 | 1257 |     return 0; | 
 | 1258 | } | 
 | 1259 |  | 
 | 1260 | static void | 
 | 1261 | TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) | 
 | 1262 | { | 
 | 1263 |     PyObject_GC_UnTrack(o); | 
 | 1264 |     (void)TaskWakeupMethWrapper_clear(o); | 
 | 1265 |     Py_TYPE(o)->tp_free(o); | 
 | 1266 | } | 
 | 1267 |  | 
 | 1268 | PyTypeObject TaskWakeupMethWrapper_Type = { | 
| Victor Stinner | 1aea8fb | 2016-10-28 19:13:52 +0200 | [diff] [blame] | 1269 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1270 |     "TaskWakeupMethWrapper", | 
 | 1271 |     .tp_basicsize = sizeof(TaskWakeupMethWrapper), | 
 | 1272 |     .tp_itemsize = 0, | 
 | 1273 |     .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc, | 
 | 1274 |     .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call, | 
 | 1275 |     .tp_getattro = PyObject_GenericGetAttr, | 
 | 1276 |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, | 
 | 1277 |     .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse, | 
 | 1278 |     .tp_clear = (inquiry)TaskWakeupMethWrapper_clear, | 
 | 1279 | }; | 
 | 1280 |  | 
 | 1281 | static PyObject * | 
 | 1282 | TaskWakeupMethWrapper_new(TaskObj *task) | 
 | 1283 | { | 
 | 1284 |     TaskWakeupMethWrapper *o; | 
 | 1285 |     o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type); | 
 | 1286 |     if (o == NULL) { | 
 | 1287 |         return NULL; | 
 | 1288 |     } | 
 | 1289 |  | 
 | 1290 |     Py_INCREF(task); | 
 | 1291 |     o->ww_task = task; | 
 | 1292 |  | 
 | 1293 |     PyObject_GC_Track(o); | 
 | 1294 |     return (PyObject*) o; | 
 | 1295 | } | 
 | 1296 |  | 
 | 1297 | /* ----- Task */ | 
 | 1298 |  | 
 | 1299 | /*[clinic input] | 
 | 1300 | _asyncio.Task.__init__ | 
 | 1301 |  | 
 | 1302 |     coro: 'O' | 
 | 1303 |     * | 
 | 1304 |     loop: 'O' = NULL | 
 | 1305 |  | 
 | 1306 | A coroutine wrapped in a Future. | 
 | 1307 | [clinic start generated code]*/ | 
 | 1308 |  | 
 | 1309 | static int | 
 | 1310 | _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop) | 
 | 1311 | /*[clinic end generated code: output=9f24774c2287fc2f input=71d8d28c201a18cd]*/ | 
 | 1312 | { | 
 | 1313 |     PyObject *res; | 
 | 1314 |     _Py_IDENTIFIER(add); | 
 | 1315 |  | 
 | 1316 |     if (future_init((FutureObj*)self, loop)) { | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1317 |         return -1; | 
 | 1318 |     } | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1319 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1320 |     self->task_fut_waiter = NULL; | 
 | 1321 |     self->task_must_cancel = 0; | 
 | 1322 |     self->task_log_destroy_pending = 1; | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1323 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1324 |     Py_INCREF(coro); | 
 | 1325 |     self->task_coro = coro; | 
 | 1326 |  | 
 | 1327 |     if (task_call_step_soon(self, NULL)) { | 
 | 1328 |         return -1; | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1329 |     } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1330 |  | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1331 |     res = _PyObject_CallMethodIdObjArgs(all_tasks, &PyId_add, self, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1332 |     if (res == NULL) { | 
 | 1333 |         return -1; | 
 | 1334 |     } | 
 | 1335 |     Py_DECREF(res); | 
 | 1336 |  | 
 | 1337 |     return 0; | 
 | 1338 | } | 
 | 1339 |  | 
 | 1340 | static int | 
 | 1341 | TaskObj_clear(TaskObj *task) | 
 | 1342 | { | 
 | 1343 |     (void)FutureObj_clear((FutureObj*) task); | 
 | 1344 |     Py_CLEAR(task->task_coro); | 
 | 1345 |     Py_CLEAR(task->task_fut_waiter); | 
 | 1346 |     return 0; | 
 | 1347 | } | 
 | 1348 |  | 
 | 1349 | static int | 
 | 1350 | TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) | 
 | 1351 | { | 
 | 1352 |     Py_VISIT(task->task_coro); | 
 | 1353 |     Py_VISIT(task->task_fut_waiter); | 
 | 1354 |     (void)FutureObj_traverse((FutureObj*) task, visit, arg); | 
 | 1355 |     return 0; | 
 | 1356 | } | 
 | 1357 |  | 
 | 1358 | static PyObject * | 
 | 1359 | TaskObj_get_log_destroy_pending(TaskObj *task) | 
 | 1360 | { | 
 | 1361 |     if (task->task_log_destroy_pending) { | 
 | 1362 |         Py_RETURN_TRUE; | 
 | 1363 |     } | 
 | 1364 |     else { | 
 | 1365 |         Py_RETURN_FALSE; | 
 | 1366 |     } | 
 | 1367 | } | 
 | 1368 |  | 
 | 1369 | static int | 
 | 1370 | TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val) | 
 | 1371 | { | 
 | 1372 |     int is_true = PyObject_IsTrue(val); | 
 | 1373 |     if (is_true < 0) { | 
 | 1374 |         return -1; | 
 | 1375 |     } | 
 | 1376 |     task->task_log_destroy_pending = is_true; | 
 | 1377 |     return 0; | 
 | 1378 | } | 
 | 1379 |  | 
 | 1380 | static PyObject * | 
 | 1381 | TaskObj_get_must_cancel(TaskObj *task) | 
 | 1382 | { | 
 | 1383 |     if (task->task_must_cancel) { | 
 | 1384 |         Py_RETURN_TRUE; | 
 | 1385 |     } | 
 | 1386 |     else { | 
 | 1387 |         Py_RETURN_FALSE; | 
 | 1388 |     } | 
 | 1389 | } | 
 | 1390 |  | 
 | 1391 | static PyObject * | 
 | 1392 | TaskObj_get_coro(TaskObj *task) | 
 | 1393 | { | 
 | 1394 |     if (task->task_coro) { | 
 | 1395 |         Py_INCREF(task->task_coro); | 
 | 1396 |         return task->task_coro; | 
 | 1397 |     } | 
 | 1398 |  | 
 | 1399 |     Py_RETURN_NONE; | 
 | 1400 | } | 
 | 1401 |  | 
 | 1402 | static PyObject * | 
 | 1403 | TaskObj_get_fut_waiter(TaskObj *task) | 
 | 1404 | { | 
 | 1405 |     if (task->task_fut_waiter) { | 
 | 1406 |         Py_INCREF(task->task_fut_waiter); | 
 | 1407 |         return task->task_fut_waiter; | 
 | 1408 |     } | 
 | 1409 |  | 
 | 1410 |     Py_RETURN_NONE; | 
 | 1411 | } | 
 | 1412 |  | 
 | 1413 | /*[clinic input] | 
 | 1414 | @classmethod | 
 | 1415 | _asyncio.Task.current_task | 
 | 1416 |  | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1417 |     loop: 'O' = None | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1418 |  | 
 | 1419 | Return the currently running task in an event loop or None. | 
 | 1420 |  | 
 | 1421 | By default the current task for the current event loop is returned. | 
 | 1422 |  | 
 | 1423 | None is returned when called not in the context of a Task. | 
 | 1424 | [clinic start generated code]*/ | 
 | 1425 |  | 
 | 1426 | static PyObject * | 
 | 1427 | _asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1428 | /*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/ | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1429 | { | 
 | 1430 |     PyObject *res; | 
 | 1431 |  | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1432 |     if (loop == Py_None) { | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 1433 |         loop = _PyObject_CallNoArg(asyncio_get_event_loop); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1434 |         if (loop == NULL) { | 
 | 1435 |             return NULL; | 
 | 1436 |         } | 
 | 1437 |  | 
| Yury Selivanov | 684ef2c | 2016-10-28 19:01:21 -0400 | [diff] [blame] | 1438 |         res = PyDict_GetItem(current_tasks, loop); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1439 |         Py_DECREF(loop); | 
 | 1440 |     } | 
 | 1441 |     else { | 
| Yury Selivanov | 684ef2c | 2016-10-28 19:01:21 -0400 | [diff] [blame] | 1442 |         res = PyDict_GetItem(current_tasks, loop); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1443 |     } | 
 | 1444 |  | 
 | 1445 |     if (res == NULL) { | 
 | 1446 |         Py_RETURN_NONE; | 
 | 1447 |     } | 
 | 1448 |     else { | 
 | 1449 |         Py_INCREF(res); | 
 | 1450 |         return res; | 
 | 1451 |     } | 
 | 1452 | } | 
 | 1453 |  | 
 | 1454 | static PyObject * | 
 | 1455 | task_all_tasks(PyObject *loop) | 
 | 1456 | { | 
 | 1457 |     PyObject *task; | 
 | 1458 |     PyObject *task_loop; | 
 | 1459 |     PyObject *set; | 
 | 1460 |     PyObject *iter; | 
 | 1461 |  | 
 | 1462 |     assert(loop != NULL); | 
 | 1463 |  | 
 | 1464 |     set = PySet_New(NULL); | 
 | 1465 |     if (set == NULL) { | 
 | 1466 |         return NULL; | 
 | 1467 |     } | 
 | 1468 |  | 
 | 1469 |     iter = PyObject_GetIter(all_tasks); | 
 | 1470 |     if (iter == NULL) { | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1471 |         goto fail; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1472 |     } | 
 | 1473 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1474 |     while ((task = PyIter_Next(iter))) { | 
 | 1475 |         task_loop = PyObject_GetAttrString(task, "_loop"); | 
 | 1476 |         if (task_loop == NULL) { | 
 | 1477 |             Py_DECREF(task); | 
 | 1478 |             goto fail; | 
 | 1479 |         } | 
 | 1480 |         if (task_loop == loop) { | 
 | 1481 |             if (PySet_Add(set, task) == -1) { | 
 | 1482 |                 Py_DECREF(task_loop); | 
 | 1483 |                 Py_DECREF(task); | 
 | 1484 |                 goto fail; | 
 | 1485 |             } | 
 | 1486 |         } | 
 | 1487 |         Py_DECREF(task_loop); | 
 | 1488 |         Py_DECREF(task); | 
 | 1489 |     } | 
 | 1490 |  | 
 | 1491 |     Py_DECREF(iter); | 
 | 1492 |     return set; | 
 | 1493 |  | 
 | 1494 | fail: | 
 | 1495 |     Py_XDECREF(set); | 
 | 1496 |     Py_XDECREF(iter); | 
 | 1497 |     return NULL; | 
 | 1498 | } | 
 | 1499 |  | 
 | 1500 | /*[clinic input] | 
 | 1501 | @classmethod | 
 | 1502 | _asyncio.Task.all_tasks | 
 | 1503 |  | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1504 |     loop: 'O' = None | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1505 |  | 
 | 1506 | Return a set of all tasks for an event loop. | 
 | 1507 |  | 
 | 1508 | By default all tasks for the current event loop are returned. | 
 | 1509 | [clinic start generated code]*/ | 
 | 1510 |  | 
 | 1511 | static PyObject * | 
 | 1512 | _asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1513 | /*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/ | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1514 | { | 
 | 1515 |     PyObject *res; | 
 | 1516 |  | 
| Yury Selivanov | 8d26aa9 | 2017-03-02 22:16:33 -0500 | [diff] [blame] | 1517 |     if (loop == Py_None) { | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 1518 |         loop = _PyObject_CallNoArg(asyncio_get_event_loop); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1519 |         if (loop == NULL) { | 
 | 1520 |             return NULL; | 
 | 1521 |         } | 
 | 1522 |  | 
 | 1523 |         res = task_all_tasks(loop); | 
 | 1524 |         Py_DECREF(loop); | 
 | 1525 |     } | 
 | 1526 |     else { | 
 | 1527 |         res = task_all_tasks(loop); | 
 | 1528 |     } | 
 | 1529 |  | 
 | 1530 |     return res; | 
 | 1531 | } | 
 | 1532 |  | 
 | 1533 | /*[clinic input] | 
 | 1534 | _asyncio.Task._repr_info | 
 | 1535 | [clinic start generated code]*/ | 
 | 1536 |  | 
 | 1537 | static PyObject * | 
 | 1538 | _asyncio_Task__repr_info_impl(TaskObj *self) | 
 | 1539 | /*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ | 
 | 1540 | { | 
| Victor Stinner | de4ae3d | 2016-12-04 22:59:09 +0100 | [diff] [blame] | 1541 |     return PyObject_CallFunctionObjArgs( | 
 | 1542 |         asyncio_task_repr_info_func, self, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1543 | } | 
 | 1544 |  | 
 | 1545 | /*[clinic input] | 
 | 1546 | _asyncio.Task.cancel | 
 | 1547 |  | 
 | 1548 | Request that this task cancel itself. | 
 | 1549 |  | 
 | 1550 | This arranges for a CancelledError to be thrown into the | 
 | 1551 | wrapped coroutine on the next cycle through the event loop. | 
 | 1552 | The coroutine then has a chance to clean up or even deny | 
 | 1553 | the request using try/except/finally. | 
 | 1554 |  | 
 | 1555 | Unlike Future.cancel, this does not guarantee that the | 
 | 1556 | task will be cancelled: the exception might be caught and | 
 | 1557 | acted upon, delaying cancellation of the task or preventing | 
 | 1558 | cancellation completely.  The task may also return a value or | 
 | 1559 | raise a different exception. | 
 | 1560 |  | 
 | 1561 | Immediately after this method is called, Task.cancelled() will | 
 | 1562 | not return True (unless the task was already cancelled).  A | 
 | 1563 | task will be marked as cancelled when the wrapped coroutine | 
 | 1564 | terminates with a CancelledError exception (even if cancel() | 
 | 1565 | was not called). | 
 | 1566 | [clinic start generated code]*/ | 
 | 1567 |  | 
 | 1568 | static PyObject * | 
 | 1569 | _asyncio_Task_cancel_impl(TaskObj *self) | 
 | 1570 | /*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/ | 
 | 1571 | { | 
 | 1572 |     if (self->task_state != STATE_PENDING) { | 
 | 1573 |         Py_RETURN_FALSE; | 
 | 1574 |     } | 
 | 1575 |  | 
 | 1576 |     if (self->task_fut_waiter) { | 
 | 1577 |         PyObject *res; | 
 | 1578 |         int is_true; | 
 | 1579 |  | 
 | 1580 |         res = _PyObject_CallMethodId( | 
 | 1581 |             self->task_fut_waiter, &PyId_cancel, NULL); | 
 | 1582 |         if (res == NULL) { | 
 | 1583 |             return NULL; | 
 | 1584 |         } | 
 | 1585 |  | 
 | 1586 |         is_true = PyObject_IsTrue(res); | 
 | 1587 |         Py_DECREF(res); | 
 | 1588 |         if (is_true < 0) { | 
 | 1589 |             return NULL; | 
 | 1590 |         } | 
 | 1591 |  | 
 | 1592 |         if (is_true) { | 
 | 1593 |             Py_RETURN_TRUE; | 
 | 1594 |         } | 
 | 1595 |     } | 
 | 1596 |  | 
 | 1597 |     self->task_must_cancel = 1; | 
 | 1598 |     Py_RETURN_TRUE; | 
 | 1599 | } | 
 | 1600 |  | 
 | 1601 | /*[clinic input] | 
 | 1602 | _asyncio.Task.get_stack | 
 | 1603 |  | 
 | 1604 |     * | 
 | 1605 |     limit: 'O' = None | 
 | 1606 |  | 
 | 1607 | Return the list of stack frames for this task's coroutine. | 
 | 1608 |  | 
 | 1609 | If the coroutine is not done, this returns the stack where it is | 
 | 1610 | suspended.  If the coroutine has completed successfully or was | 
 | 1611 | cancelled, this returns an empty list.  If the coroutine was | 
 | 1612 | terminated by an exception, this returns the list of traceback | 
 | 1613 | frames. | 
 | 1614 |  | 
 | 1615 | The frames are always ordered from oldest to newest. | 
 | 1616 |  | 
 | 1617 | The optional limit gives the maximum number of frames to | 
 | 1618 | return; by default all available frames are returned.  Its | 
 | 1619 | meaning differs depending on whether a stack or a traceback is | 
 | 1620 | returned: the newest frames of a stack are returned, but the | 
 | 1621 | oldest frames of a traceback are returned.  (This matches the | 
 | 1622 | behavior of the traceback module.) | 
 | 1623 |  | 
 | 1624 | For reasons beyond our control, only one stack frame is | 
 | 1625 | returned for a suspended coroutine. | 
 | 1626 | [clinic start generated code]*/ | 
 | 1627 |  | 
 | 1628 | static PyObject * | 
 | 1629 | _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) | 
 | 1630 | /*[clinic end generated code: output=c9aeeeebd1e18118 input=b1920230a766d17a]*/ | 
 | 1631 | { | 
 | 1632 |     return PyObject_CallFunctionObjArgs( | 
 | 1633 |         asyncio_task_get_stack_func, self, limit, NULL); | 
 | 1634 | } | 
 | 1635 |  | 
 | 1636 | /*[clinic input] | 
 | 1637 | _asyncio.Task.print_stack | 
 | 1638 |  | 
 | 1639 |     * | 
 | 1640 |     limit: 'O' = None | 
 | 1641 |     file: 'O' = None | 
 | 1642 |  | 
 | 1643 | Print the stack or traceback for this task's coroutine. | 
 | 1644 |  | 
 | 1645 | This produces output similar to that of the traceback module, | 
 | 1646 | for the frames retrieved by get_stack().  The limit argument | 
 | 1647 | is passed to get_stack().  The file argument is an I/O stream | 
 | 1648 | to which the output is written; by default output is written | 
 | 1649 | to sys.stderr. | 
 | 1650 | [clinic start generated code]*/ | 
 | 1651 |  | 
 | 1652 | static PyObject * | 
 | 1653 | _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, | 
 | 1654 |                                PyObject *file) | 
 | 1655 | /*[clinic end generated code: output=7339e10314cd3f4d input=19f1e99ab5400bc3]*/ | 
 | 1656 | { | 
 | 1657 |     return PyObject_CallFunctionObjArgs( | 
 | 1658 |         asyncio_task_print_stack_func, self, limit, file, NULL); | 
 | 1659 | } | 
 | 1660 |  | 
 | 1661 | /*[clinic input] | 
 | 1662 | _asyncio.Task._step | 
 | 1663 |  | 
 | 1664 |     exc: 'O' = NULL | 
 | 1665 | [clinic start generated code]*/ | 
 | 1666 |  | 
 | 1667 | static PyObject * | 
 | 1668 | _asyncio_Task__step_impl(TaskObj *self, PyObject *exc) | 
 | 1669 | /*[clinic end generated code: output=7ed23f0cefd5ae42 input=ada4b2324e5370af]*/ | 
 | 1670 | { | 
 | 1671 |     return task_step(self, exc == Py_None ? NULL : exc); | 
 | 1672 | } | 
 | 1673 |  | 
 | 1674 | /*[clinic input] | 
 | 1675 | _asyncio.Task._wakeup | 
 | 1676 |  | 
 | 1677 |     fut: 'O' | 
 | 1678 | [clinic start generated code]*/ | 
 | 1679 |  | 
 | 1680 | static PyObject * | 
 | 1681 | _asyncio_Task__wakeup_impl(TaskObj *self, PyObject *fut) | 
 | 1682 | /*[clinic end generated code: output=75cb341c760fd071 input=11ee4918a5bdbf21]*/ | 
 | 1683 | { | 
 | 1684 |     return task_wakeup(self, fut); | 
 | 1685 | } | 
 | 1686 |  | 
 | 1687 | static void | 
 | 1688 | TaskObj_finalize(TaskObj *task) | 
 | 1689 | { | 
 | 1690 |     _Py_IDENTIFIER(call_exception_handler); | 
 | 1691 |     _Py_IDENTIFIER(task); | 
 | 1692 |     _Py_IDENTIFIER(message); | 
 | 1693 |     _Py_IDENTIFIER(source_traceback); | 
 | 1694 |  | 
 | 1695 |     PyObject *message = NULL; | 
 | 1696 |     PyObject *context = NULL; | 
 | 1697 |     PyObject *func = NULL; | 
 | 1698 |     PyObject *res = NULL; | 
 | 1699 |  | 
 | 1700 |     PyObject *error_type, *error_value, *error_traceback; | 
 | 1701 |  | 
 | 1702 |     if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) { | 
 | 1703 |         goto done; | 
 | 1704 |     } | 
 | 1705 |  | 
 | 1706 |     /* Save the current exception, if any. */ | 
 | 1707 |     PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
 | 1708 |  | 
 | 1709 |     context = PyDict_New(); | 
 | 1710 |     if (context == NULL) { | 
 | 1711 |         goto finally; | 
 | 1712 |     } | 
 | 1713 |  | 
 | 1714 |     message = PyUnicode_FromString("Task was destroyed but it is pending!"); | 
 | 1715 |     if (message == NULL) { | 
 | 1716 |         goto finally; | 
 | 1717 |     } | 
 | 1718 |  | 
 | 1719 |     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || | 
 | 1720 |         _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0) | 
 | 1721 |     { | 
 | 1722 |         goto finally; | 
 | 1723 |     } | 
 | 1724 |  | 
 | 1725 |     if (task->task_source_tb != NULL) { | 
 | 1726 |         if (_PyDict_SetItemId(context, &PyId_source_traceback, | 
 | 1727 |                               task->task_source_tb) < 0) | 
 | 1728 |         { | 
 | 1729 |             goto finally; | 
 | 1730 |         } | 
 | 1731 |     } | 
 | 1732 |  | 
 | 1733 |     func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); | 
 | 1734 |     if (func != NULL) { | 
| Victor Stinner | 7bfb42d | 2016-12-05 17:04:32 +0100 | [diff] [blame] | 1735 |         res = PyObject_CallFunctionObjArgs(func, context, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1736 |         if (res == NULL) { | 
 | 1737 |             PyErr_WriteUnraisable(func); | 
 | 1738 |         } | 
 | 1739 |     } | 
 | 1740 |  | 
 | 1741 | finally: | 
 | 1742 |     Py_CLEAR(context); | 
 | 1743 |     Py_CLEAR(message); | 
 | 1744 |     Py_CLEAR(func); | 
 | 1745 |     Py_CLEAR(res); | 
 | 1746 |  | 
 | 1747 |     /* Restore the saved exception. */ | 
 | 1748 |     PyErr_Restore(error_type, error_value, error_traceback); | 
 | 1749 |  | 
 | 1750 | done: | 
 | 1751 |     FutureObj_finalize((FutureObj*)task); | 
 | 1752 | } | 
 | 1753 |  | 
 | 1754 | static void TaskObj_dealloc(PyObject *);  /* Needs Task_CheckExact */ | 
 | 1755 |  | 
 | 1756 | static PyMethodDef TaskType_methods[] = { | 
 | 1757 |     _ASYNCIO_FUTURE_RESULT_METHODDEF | 
 | 1758 |     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF | 
 | 1759 |     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF | 
 | 1760 |     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF | 
 | 1761 |     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF | 
 | 1762 |     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF | 
 | 1763 |     _ASYNCIO_FUTURE_CANCELLED_METHODDEF | 
 | 1764 |     _ASYNCIO_FUTURE_DONE_METHODDEF | 
 | 1765 |     _ASYNCIO_TASK_CURRENT_TASK_METHODDEF | 
 | 1766 |     _ASYNCIO_TASK_ALL_TASKS_METHODDEF | 
 | 1767 |     _ASYNCIO_TASK_CANCEL_METHODDEF | 
 | 1768 |     _ASYNCIO_TASK_GET_STACK_METHODDEF | 
 | 1769 |     _ASYNCIO_TASK_PRINT_STACK_METHODDEF | 
 | 1770 |     _ASYNCIO_TASK__WAKEUP_METHODDEF | 
 | 1771 |     _ASYNCIO_TASK__STEP_METHODDEF | 
 | 1772 |     _ASYNCIO_TASK__REPR_INFO_METHODDEF | 
 | 1773 |     {NULL, NULL}        /* Sentinel */ | 
 | 1774 | }; | 
 | 1775 |  | 
 | 1776 | static PyGetSetDef TaskType_getsetlist[] = { | 
 | 1777 |     FUTURE_COMMON_GETSETLIST | 
 | 1778 |     {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending, | 
 | 1779 |                              (setter)TaskObj_set_log_destroy_pending, NULL}, | 
 | 1780 |     {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL}, | 
 | 1781 |     {"_coro", (getter)TaskObj_get_coro, NULL, NULL}, | 
 | 1782 |     {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL}, | 
 | 1783 |     {NULL} /* Sentinel */ | 
 | 1784 | }; | 
 | 1785 |  | 
 | 1786 | static PyTypeObject TaskType = { | 
| Victor Stinner | 1aea8fb | 2016-10-28 19:13:52 +0200 | [diff] [blame] | 1787 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1788 |     "_asyncio.Task", | 
 | 1789 |     sizeof(TaskObj),                       /* tp_basicsize */ | 
 | 1790 |     .tp_base = &FutureType, | 
 | 1791 |     .tp_dealloc = TaskObj_dealloc, | 
 | 1792 |     .tp_as_async = &FutureType_as_async, | 
 | 1793 |     .tp_repr = (reprfunc)FutureObj_repr, | 
 | 1794 |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 
 | 1795 |         | Py_TPFLAGS_HAVE_FINALIZE, | 
 | 1796 |     .tp_doc = _asyncio_Task___init____doc__, | 
 | 1797 |     .tp_traverse = (traverseproc)TaskObj_traverse, | 
 | 1798 |     .tp_clear = (inquiry)TaskObj_clear, | 
 | 1799 |     .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist), | 
 | 1800 |     .tp_iter = (getiterfunc)future_new_iter, | 
 | 1801 |     .tp_methods = TaskType_methods, | 
 | 1802 |     .tp_getset = TaskType_getsetlist, | 
 | 1803 |     .tp_dictoffset = offsetof(TaskObj, dict), | 
 | 1804 |     .tp_init = (initproc)_asyncio_Task___init__, | 
 | 1805 |     .tp_new = PyType_GenericNew, | 
 | 1806 |     .tp_finalize = (destructor)TaskObj_finalize, | 
 | 1807 | }; | 
 | 1808 |  | 
 | 1809 | #define Task_CheckExact(obj) (Py_TYPE(obj) == &TaskType) | 
 | 1810 |  | 
 | 1811 | static void | 
 | 1812 | TaskObj_dealloc(PyObject *self) | 
 | 1813 | { | 
 | 1814 |     TaskObj *task = (TaskObj *)self; | 
 | 1815 |  | 
 | 1816 |     if (Task_CheckExact(self)) { | 
 | 1817 |         /* When fut is subclass of Task, finalizer is called from | 
 | 1818 |          * subtype_dealloc. | 
 | 1819 |          */ | 
 | 1820 |         if (PyObject_CallFinalizerFromDealloc(self) < 0) { | 
 | 1821 |             // resurrected. | 
 | 1822 |             return; | 
 | 1823 |         } | 
 | 1824 |     } | 
 | 1825 |  | 
 | 1826 |     if (task->task_weakreflist != NULL) { | 
 | 1827 |         PyObject_ClearWeakRefs(self); | 
 | 1828 |     } | 
 | 1829 |  | 
 | 1830 |     (void)TaskObj_clear(task); | 
 | 1831 |     Py_TYPE(task)->tp_free(task); | 
 | 1832 | } | 
 | 1833 |  | 
 | 1834 | static inline PyObject * | 
 | 1835 | task_call_wakeup(TaskObj *task, PyObject *fut) | 
 | 1836 | { | 
 | 1837 |     if (Task_CheckExact(task)) { | 
 | 1838 |         return task_wakeup(task, fut); | 
 | 1839 |     } | 
 | 1840 |     else { | 
 | 1841 |         /* `task` is a subclass of Task */ | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1842 |         return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__wakeup, | 
 | 1843 |                                              fut, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1844 |     } | 
 | 1845 | } | 
 | 1846 |  | 
 | 1847 | static inline PyObject * | 
 | 1848 | task_call_step(TaskObj *task, PyObject *arg) | 
 | 1849 | { | 
 | 1850 |     if (Task_CheckExact(task)) { | 
 | 1851 |         return task_step(task, arg); | 
 | 1852 |     } | 
 | 1853 |     else { | 
 | 1854 |         /* `task` is a subclass of Task */ | 
 | 1855 |         if (arg == NULL) { | 
 | 1856 |             arg = Py_None; | 
 | 1857 |         } | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1858 |         return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step, | 
 | 1859 |                                              arg, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1860 |     } | 
 | 1861 | } | 
 | 1862 |  | 
 | 1863 | static int | 
 | 1864 | task_call_step_soon(TaskObj *task, PyObject *arg) | 
 | 1865 | { | 
 | 1866 |     PyObject *handle; | 
 | 1867 |  | 
 | 1868 |     PyObject *cb = TaskSendMethWrapper_new(task, arg); | 
 | 1869 |     if (cb == NULL) { | 
 | 1870 |         return -1; | 
 | 1871 |     } | 
 | 1872 |  | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1873 |     handle = _PyObject_CallMethodIdObjArgs(task->task_loop, &PyId_call_soon, | 
 | 1874 |                                            cb, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1875 |     Py_DECREF(cb); | 
 | 1876 |     if (handle == NULL) { | 
 | 1877 |         return -1; | 
 | 1878 |     } | 
 | 1879 |  | 
 | 1880 |     Py_DECREF(handle); | 
 | 1881 |     return 0; | 
 | 1882 | } | 
 | 1883 |  | 
 | 1884 | static PyObject * | 
 | 1885 | task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) | 
 | 1886 | { | 
 | 1887 |     PyObject* msg; | 
 | 1888 |  | 
 | 1889 |     va_list vargs; | 
 | 1890 | #ifdef HAVE_STDARG_PROTOTYPES | 
 | 1891 |     va_start(vargs, format); | 
 | 1892 | #else | 
 | 1893 |     va_start(vargs); | 
 | 1894 | #endif | 
 | 1895 |     msg = PyUnicode_FromFormatV(format, vargs); | 
 | 1896 |     va_end(vargs); | 
 | 1897 |  | 
 | 1898 |     if (msg == NULL) { | 
 | 1899 |         return NULL; | 
 | 1900 |     } | 
 | 1901 |  | 
| Victor Stinner | de4ae3d | 2016-12-04 22:59:09 +0100 | [diff] [blame] | 1902 |     PyObject *e = PyObject_CallFunctionObjArgs(et, msg, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1903 |     Py_DECREF(msg); | 
 | 1904 |     if (e == NULL) { | 
 | 1905 |         return NULL; | 
 | 1906 |     } | 
 | 1907 |  | 
 | 1908 |     if (task_call_step_soon(task, e) == -1) { | 
 | 1909 |         Py_DECREF(e); | 
 | 1910 |         return NULL; | 
 | 1911 |     } | 
 | 1912 |  | 
 | 1913 |     Py_DECREF(e); | 
 | 1914 |     Py_RETURN_NONE; | 
 | 1915 | } | 
 | 1916 |  | 
 | 1917 | static PyObject * | 
 | 1918 | task_step_impl(TaskObj *task, PyObject *exc) | 
 | 1919 | { | 
 | 1920 |     int res; | 
 | 1921 |     int clear_exc = 0; | 
 | 1922 |     PyObject *result = NULL; | 
 | 1923 |     PyObject *coro = task->task_coro; | 
 | 1924 |     PyObject *o; | 
 | 1925 |  | 
 | 1926 |     if (task->task_state != STATE_PENDING) { | 
 | 1927 |         PyErr_Format(PyExc_AssertionError, | 
 | 1928 |                      "_step(): already done: %R %R", | 
 | 1929 |                      task, | 
 | 1930 |                      exc ? exc : Py_None); | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 1931 |         goto fail; | 
 | 1932 |     } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 1933 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1934 |     if (task->task_must_cancel) { | 
 | 1935 |         assert(exc != Py_None); | 
 | 1936 |  | 
 | 1937 |         if (exc) { | 
 | 1938 |             /* Check if exc is a CancelledError */ | 
 | 1939 |             res = PyObject_IsInstance(exc, asyncio_CancelledError); | 
 | 1940 |             if (res == -1) { | 
 | 1941 |                 /* An error occurred, abort */ | 
 | 1942 |                 goto fail; | 
 | 1943 |             } | 
 | 1944 |             if (res == 0) { | 
 | 1945 |                 /* exc is not CancelledError; reset it to NULL */ | 
 | 1946 |                 exc = NULL; | 
 | 1947 |             } | 
 | 1948 |         } | 
 | 1949 |  | 
 | 1950 |         if (!exc) { | 
 | 1951 |             /* exc was not a CancelledError */ | 
| Victor Stinner | f17c3de | 2016-12-06 18:46:19 +0100 | [diff] [blame] | 1952 |             exc = _PyObject_CallNoArg(asyncio_CancelledError); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1953 |             if (!exc) { | 
 | 1954 |                 goto fail; | 
 | 1955 |             } | 
 | 1956 |             clear_exc = 1; | 
 | 1957 |         } | 
 | 1958 |  | 
 | 1959 |         task->task_must_cancel = 0; | 
 | 1960 |     } | 
 | 1961 |  | 
 | 1962 |     Py_CLEAR(task->task_fut_waiter); | 
 | 1963 |  | 
 | 1964 |     if (exc == NULL) { | 
 | 1965 |         if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { | 
 | 1966 |             result = _PyGen_Send((PyGenObject*)coro, Py_None); | 
 | 1967 |         } | 
 | 1968 |         else { | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1969 |             result = _PyObject_CallMethodIdObjArgs(coro, &PyId_send, | 
 | 1970 |                                                    Py_None, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1971 |         } | 
 | 1972 |     } | 
 | 1973 |     else { | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 1974 |         result = _PyObject_CallMethodIdObjArgs(coro, &PyId_throw, | 
 | 1975 |                                                exc, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 1976 |         if (clear_exc) { | 
 | 1977 |             /* We created 'exc' during this call */ | 
 | 1978 |             Py_CLEAR(exc); | 
 | 1979 |         } | 
 | 1980 |     } | 
 | 1981 |  | 
 | 1982 |     if (result == NULL) { | 
 | 1983 |         PyObject *et, *ev, *tb; | 
 | 1984 |  | 
 | 1985 |         if (_PyGen_FetchStopIterationValue(&o) == 0) { | 
 | 1986 |             /* The error is StopIteration and that means that | 
 | 1987 |                the underlying coroutine has resolved */ | 
 | 1988 |             PyObject *res = future_set_result((FutureObj*)task, o); | 
 | 1989 |             Py_DECREF(o); | 
 | 1990 |             if (res == NULL) { | 
 | 1991 |                 return NULL; | 
 | 1992 |             } | 
 | 1993 |             Py_DECREF(res); | 
 | 1994 |             Py_RETURN_NONE; | 
 | 1995 |         } | 
 | 1996 |  | 
 | 1997 |         if (PyErr_ExceptionMatches(asyncio_CancelledError)) { | 
 | 1998 |             /* CancelledError */ | 
 | 1999 |             PyErr_Clear(); | 
 | 2000 |             return future_cancel((FutureObj*)task); | 
 | 2001 |         } | 
 | 2002 |  | 
 | 2003 |         /* Some other exception; pop it and call Task.set_exception() */ | 
 | 2004 |         PyErr_Fetch(&et, &ev, &tb); | 
 | 2005 |         assert(et); | 
 | 2006 |         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { | 
 | 2007 |             PyErr_NormalizeException(&et, &ev, &tb); | 
 | 2008 |         } | 
| Yury Selivanov | edfe886 | 2016-12-01 11:37:47 -0500 | [diff] [blame] | 2009 |         if (tb != NULL) { | 
 | 2010 |             PyException_SetTraceback(ev, tb); | 
 | 2011 |         } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2012 |         o = future_set_exception((FutureObj*)task, ev); | 
 | 2013 |         if (!o) { | 
 | 2014 |             /* An exception in Task.set_exception() */ | 
 | 2015 |             Py_XDECREF(et); | 
 | 2016 |             Py_XDECREF(tb); | 
 | 2017 |             Py_XDECREF(ev); | 
 | 2018 |             goto fail; | 
 | 2019 |         } | 
 | 2020 |         assert(o == Py_None); | 
 | 2021 |         Py_CLEAR(o); | 
 | 2022 |  | 
 | 2023 |         if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) { | 
 | 2024 |             /* We've got a BaseException; re-raise it */ | 
 | 2025 |             PyErr_Restore(et, ev, tb); | 
 | 2026 |             goto fail; | 
 | 2027 |         } | 
 | 2028 |  | 
 | 2029 |         Py_XDECREF(et); | 
 | 2030 |         Py_XDECREF(tb); | 
 | 2031 |         Py_XDECREF(ev); | 
 | 2032 |  | 
 | 2033 |         Py_RETURN_NONE; | 
 | 2034 |     } | 
 | 2035 |  | 
 | 2036 |     if (result == (PyObject*)task) { | 
 | 2037 |         /* We have a task that wants to await on itself */ | 
 | 2038 |         goto self_await; | 
 | 2039 |     } | 
 | 2040 |  | 
 | 2041 |     /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ | 
 | 2042 |     if (Future_CheckExact(result) || Task_CheckExact(result)) { | 
 | 2043 |         PyObject *wrapper; | 
 | 2044 |         PyObject *res; | 
 | 2045 |         FutureObj *fut = (FutureObj*)result; | 
 | 2046 |  | 
 | 2047 |         /* Check if `result` future is attached to a different loop */ | 
 | 2048 |         if (fut->fut_loop != task->task_loop) { | 
 | 2049 |             goto different_loop; | 
 | 2050 |         } | 
 | 2051 |  | 
 | 2052 |         if (fut->fut_blocking) { | 
 | 2053 |             fut->fut_blocking = 0; | 
 | 2054 |  | 
 | 2055 |             /* result.add_done_callback(task._wakeup) */ | 
 | 2056 |             wrapper = TaskWakeupMethWrapper_new(task); | 
 | 2057 |             if (wrapper == NULL) { | 
 | 2058 |                 goto fail; | 
 | 2059 |             } | 
 | 2060 |             res = future_add_done_callback((FutureObj*)result, wrapper); | 
 | 2061 |             Py_DECREF(wrapper); | 
 | 2062 |             if (res == NULL) { | 
 | 2063 |                 goto fail; | 
 | 2064 |             } | 
 | 2065 |             Py_DECREF(res); | 
 | 2066 |  | 
 | 2067 |             /* task._fut_waiter = result */ | 
 | 2068 |             task->task_fut_waiter = result;  /* no incref is necessary */ | 
 | 2069 |  | 
 | 2070 |             if (task->task_must_cancel) { | 
 | 2071 |                 PyObject *r; | 
 | 2072 |                 r = future_cancel(fut); | 
 | 2073 |                 if (r == NULL) { | 
 | 2074 |                     return NULL; | 
 | 2075 |                 } | 
 | 2076 |                 if (r == Py_True) { | 
 | 2077 |                     task->task_must_cancel = 0; | 
 | 2078 |                 } | 
 | 2079 |                 Py_DECREF(r); | 
 | 2080 |             } | 
 | 2081 |  | 
 | 2082 |             Py_RETURN_NONE; | 
 | 2083 |         } | 
 | 2084 |         else { | 
 | 2085 |             goto yield_insteadof_yf; | 
 | 2086 |         } | 
 | 2087 |     } | 
 | 2088 |  | 
 | 2089 |     /* Check if `result` is a Future-compatible object */ | 
 | 2090 |     o = PyObject_GetAttrString(result, "_asyncio_future_blocking"); | 
 | 2091 |     if (o == NULL) { | 
 | 2092 |         if (PyErr_ExceptionMatches(PyExc_AttributeError)) { | 
 | 2093 |             PyErr_Clear(); | 
 | 2094 |         } | 
 | 2095 |         else { | 
 | 2096 |             goto fail; | 
 | 2097 |         } | 
 | 2098 |     } | 
 | 2099 |     else { | 
 | 2100 |         if (o == Py_None) { | 
 | 2101 |             Py_CLEAR(o); | 
 | 2102 |         } | 
 | 2103 |         else { | 
 | 2104 |             /* `result` is a Future-compatible object */ | 
 | 2105 |             PyObject *wrapper; | 
 | 2106 |             PyObject *res; | 
 | 2107 |  | 
 | 2108 |             int blocking = PyObject_IsTrue(o); | 
 | 2109 |             Py_CLEAR(o); | 
 | 2110 |             if (blocking < 0) { | 
 | 2111 |                 goto fail; | 
 | 2112 |             } | 
 | 2113 |  | 
 | 2114 |             /* Check if `result` future is attached to a different loop */ | 
 | 2115 |             PyObject *oloop = PyObject_GetAttrString(result, "_loop"); | 
 | 2116 |             if (oloop == NULL) { | 
 | 2117 |                 goto fail; | 
 | 2118 |             } | 
 | 2119 |             if (oloop != task->task_loop) { | 
 | 2120 |                 Py_DECREF(oloop); | 
 | 2121 |                 goto different_loop; | 
 | 2122 |             } | 
 | 2123 |             else { | 
 | 2124 |                 Py_DECREF(oloop); | 
 | 2125 |             } | 
 | 2126 |  | 
 | 2127 |             if (blocking) { | 
 | 2128 |                 /* result._asyncio_future_blocking = False */ | 
 | 2129 |                 if (PyObject_SetAttrString( | 
 | 2130 |                         result, "_asyncio_future_blocking", Py_False) == -1) { | 
 | 2131 |                     goto fail; | 
 | 2132 |                 } | 
 | 2133 |  | 
 | 2134 |                 /* result.add_done_callback(task._wakeup) */ | 
 | 2135 |                 wrapper = TaskWakeupMethWrapper_new(task); | 
 | 2136 |                 if (wrapper == NULL) { | 
 | 2137 |                     goto fail; | 
 | 2138 |                 } | 
| Victor Stinner | b6ed57d | 2016-12-09 14:24:02 +0100 | [diff] [blame] | 2139 |                 res = _PyObject_CallMethodIdObjArgs(result, | 
 | 2140 |                                                     &PyId_add_done_callback, | 
 | 2141 |                                                     wrapper, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2142 |                 Py_DECREF(wrapper); | 
 | 2143 |                 if (res == NULL) { | 
 | 2144 |                     goto fail; | 
 | 2145 |                 } | 
 | 2146 |                 Py_DECREF(res); | 
 | 2147 |  | 
 | 2148 |                 /* task._fut_waiter = result */ | 
 | 2149 |                 task->task_fut_waiter = result;  /* no incref is necessary */ | 
 | 2150 |  | 
 | 2151 |                 if (task->task_must_cancel) { | 
 | 2152 |                     PyObject *r; | 
 | 2153 |                     int is_true; | 
 | 2154 |                     r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); | 
 | 2155 |                     if (r == NULL) { | 
 | 2156 |                         return NULL; | 
 | 2157 |                     } | 
 | 2158 |                     is_true = PyObject_IsTrue(r); | 
 | 2159 |                     Py_DECREF(r); | 
 | 2160 |                     if (is_true < 0) { | 
 | 2161 |                         return NULL; | 
 | 2162 |                     } | 
 | 2163 |                     else if (is_true) { | 
 | 2164 |                         task->task_must_cancel = 0; | 
 | 2165 |                     } | 
 | 2166 |                 } | 
 | 2167 |  | 
 | 2168 |                 Py_RETURN_NONE; | 
 | 2169 |             } | 
 | 2170 |             else { | 
 | 2171 |                 goto yield_insteadof_yf; | 
 | 2172 |             } | 
 | 2173 |         } | 
 | 2174 |     } | 
 | 2175 |  | 
 | 2176 |     /* Check if `result` is None */ | 
 | 2177 |     if (result == Py_None) { | 
 | 2178 |         /* Bare yield relinquishes control for one event loop iteration. */ | 
 | 2179 |         if (task_call_step_soon(task, NULL)) { | 
 | 2180 |             goto fail; | 
 | 2181 |         } | 
 | 2182 |         return result; | 
 | 2183 |     } | 
 | 2184 |  | 
 | 2185 |     /* Check if `result` is a generator */ | 
| Victor Stinner | de4ae3d | 2016-12-04 22:59:09 +0100 | [diff] [blame] | 2186 |     o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2187 |     if (o == NULL) { | 
 | 2188 |         /* An exception in inspect.isgenerator */ | 
 | 2189 |         goto fail; | 
 | 2190 |     } | 
 | 2191 |     res = PyObject_IsTrue(o); | 
 | 2192 |     Py_CLEAR(o); | 
 | 2193 |     if (res == -1) { | 
 | 2194 |         /* An exception while checking if 'val' is True */ | 
 | 2195 |         goto fail; | 
 | 2196 |     } | 
 | 2197 |     if (res == 1) { | 
 | 2198 |         /* `result` is a generator */ | 
 | 2199 |         PyObject *ret; | 
 | 2200 |         ret = task_set_error_soon( | 
 | 2201 |             task, PyExc_RuntimeError, | 
 | 2202 |             "yield was used instead of yield from for " | 
 | 2203 |             "generator in task %R with %S", task, result); | 
 | 2204 |         Py_DECREF(result); | 
 | 2205 |         return ret; | 
 | 2206 |     } | 
 | 2207 |  | 
 | 2208 |     /* The `result` is none of the above */ | 
 | 2209 |     Py_DECREF(result); | 
 | 2210 |     return task_set_error_soon( | 
 | 2211 |         task, PyExc_RuntimeError, "Task got bad yield: %R", result); | 
 | 2212 |  | 
 | 2213 | self_await: | 
 | 2214 |     o = task_set_error_soon( | 
 | 2215 |         task, PyExc_RuntimeError, | 
 | 2216 |         "Task cannot await on itself: %R", task); | 
 | 2217 |     Py_DECREF(result); | 
 | 2218 |     return o; | 
 | 2219 |  | 
 | 2220 | yield_insteadof_yf: | 
 | 2221 |     o = task_set_error_soon( | 
 | 2222 |         task, PyExc_RuntimeError, | 
 | 2223 |         "yield was used instead of yield from " | 
 | 2224 |         "in task %R with %R", | 
 | 2225 |         task, result); | 
 | 2226 |     Py_DECREF(result); | 
 | 2227 |     return o; | 
 | 2228 |  | 
 | 2229 | different_loop: | 
 | 2230 |     o = task_set_error_soon( | 
 | 2231 |         task, PyExc_RuntimeError, | 
 | 2232 |         "Task %R got Future %R attached to a different loop", | 
 | 2233 |         task, result); | 
 | 2234 |     Py_DECREF(result); | 
 | 2235 |     return o; | 
 | 2236 |  | 
 | 2237 | fail: | 
 | 2238 |     Py_XDECREF(result); | 
 | 2239 |     return NULL; | 
 | 2240 | } | 
 | 2241 |  | 
 | 2242 | static PyObject * | 
 | 2243 | task_step(TaskObj *task, PyObject *exc) | 
 | 2244 | { | 
 | 2245 |     PyObject *res; | 
 | 2246 |     PyObject *ot; | 
 | 2247 |  | 
| Yury Selivanov | 684ef2c | 2016-10-28 19:01:21 -0400 | [diff] [blame] | 2248 |     if (PyDict_SetItem(current_tasks, | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2249 |                        task->task_loop, (PyObject*)task) == -1) | 
 | 2250 |     { | 
 | 2251 |         return NULL; | 
 | 2252 |     } | 
 | 2253 |  | 
 | 2254 |     res = task_step_impl(task, exc); | 
 | 2255 |  | 
 | 2256 |     if (res == NULL) { | 
 | 2257 |         PyObject *et, *ev, *tb; | 
 | 2258 |         PyErr_Fetch(&et, &ev, &tb); | 
 | 2259 |         ot = _PyDict_Pop(current_tasks, task->task_loop, NULL); | 
 | 2260 |         if (ot == NULL) { | 
 | 2261 |             Py_XDECREF(et); | 
 | 2262 |             Py_XDECREF(tb); | 
 | 2263 |             Py_XDECREF(ev); | 
 | 2264 |             return NULL; | 
 | 2265 |         } | 
 | 2266 |         Py_DECREF(ot); | 
 | 2267 |         PyErr_Restore(et, ev, tb); | 
 | 2268 |         return NULL; | 
 | 2269 |     } | 
 | 2270 |     else { | 
 | 2271 |         ot = _PyDict_Pop(current_tasks, task->task_loop, NULL); | 
 | 2272 |         if (ot == NULL) { | 
 | 2273 |             Py_DECREF(res); | 
 | 2274 |             return NULL; | 
 | 2275 |         } | 
 | 2276 |         else { | 
 | 2277 |             Py_DECREF(ot); | 
 | 2278 |             return res; | 
 | 2279 |         } | 
 | 2280 |     } | 
 | 2281 | } | 
 | 2282 |  | 
 | 2283 | static PyObject * | 
 | 2284 | task_wakeup(TaskObj *task, PyObject *o) | 
 | 2285 | { | 
 | 2286 |     assert(o); | 
 | 2287 |  | 
 | 2288 |     if (Future_CheckExact(o) || Task_CheckExact(o)) { | 
 | 2289 |         PyObject *fut_result = NULL; | 
 | 2290 |         int res = future_get_result((FutureObj*)o, &fut_result); | 
 | 2291 |         PyObject *result; | 
 | 2292 |  | 
 | 2293 |         switch(res) { | 
 | 2294 |         case -1: | 
 | 2295 |             assert(fut_result == NULL); | 
 | 2296 |             return NULL; | 
 | 2297 |         case 0: | 
 | 2298 |             Py_DECREF(fut_result); | 
 | 2299 |             return task_call_step(task, NULL); | 
 | 2300 |         default: | 
 | 2301 |             assert(res == 1); | 
 | 2302 |             result = task_call_step(task, fut_result); | 
 | 2303 |             Py_DECREF(fut_result); | 
 | 2304 |             return result; | 
 | 2305 |         } | 
 | 2306 |     } | 
 | 2307 |  | 
 | 2308 |     PyObject *fut_result = PyObject_CallMethod(o, "result", NULL); | 
 | 2309 |     if (fut_result == NULL) { | 
 | 2310 |         PyObject *et, *ev, *tb; | 
 | 2311 |         PyObject *res; | 
 | 2312 |  | 
 | 2313 |         PyErr_Fetch(&et, &ev, &tb); | 
 | 2314 |         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { | 
 | 2315 |             PyErr_NormalizeException(&et, &ev, &tb); | 
 | 2316 |         } | 
 | 2317 |  | 
 | 2318 |         res = task_call_step(task, ev); | 
 | 2319 |  | 
 | 2320 |         Py_XDECREF(et); | 
 | 2321 |         Py_XDECREF(tb); | 
 | 2322 |         Py_XDECREF(ev); | 
 | 2323 |  | 
 | 2324 |         return res; | 
 | 2325 |     } | 
 | 2326 |     else { | 
 | 2327 |         Py_DECREF(fut_result); | 
 | 2328 |         return task_call_step(task, NULL); | 
 | 2329 |     } | 
 | 2330 | } | 
 | 2331 |  | 
 | 2332 |  | 
 | 2333 | /*********************** Module **************************/ | 
 | 2334 |  | 
 | 2335 |  | 
 | 2336 | static void | 
 | 2337 | module_free(void *m) | 
 | 2338 | { | 
 | 2339 |     Py_CLEAR(current_tasks); | 
 | 2340 |     Py_CLEAR(all_tasks); | 
 | 2341 |     Py_CLEAR(traceback_extract_stack); | 
 | 2342 |     Py_CLEAR(asyncio_get_event_loop); | 
 | 2343 |     Py_CLEAR(asyncio_future_repr_info_func); | 
 | 2344 |     Py_CLEAR(asyncio_task_repr_info_func); | 
 | 2345 |     Py_CLEAR(asyncio_task_get_stack_func); | 
 | 2346 |     Py_CLEAR(asyncio_task_print_stack_func); | 
 | 2347 |     Py_CLEAR(asyncio_InvalidStateError); | 
 | 2348 |     Py_CLEAR(asyncio_CancelledError); | 
 | 2349 |     Py_CLEAR(inspect_isgenerator); | 
 | 2350 | } | 
 | 2351 |  | 
 | 2352 | static int | 
 | 2353 | module_init(void) | 
 | 2354 | { | 
 | 2355 |     PyObject *module = NULL; | 
 | 2356 |     PyObject *cls; | 
 | 2357 |  | 
 | 2358 | #define WITH_MOD(NAME) \ | 
 | 2359 |     Py_CLEAR(module); \ | 
 | 2360 |     module = PyImport_ImportModule(NAME); \ | 
 | 2361 |     if (module == NULL) { \ | 
 | 2362 |         return -1; \ | 
 | 2363 |     } | 
 | 2364 |  | 
 | 2365 | #define GET_MOD_ATTR(VAR, NAME) \ | 
 | 2366 |     VAR = PyObject_GetAttrString(module, NAME); \ | 
 | 2367 |     if (VAR == NULL) { \ | 
 | 2368 |         goto fail; \ | 
 | 2369 |     } | 
 | 2370 |  | 
 | 2371 |     WITH_MOD("asyncio.events") | 
 | 2372 |     GET_MOD_ATTR(asyncio_get_event_loop, "get_event_loop") | 
 | 2373 |  | 
 | 2374 |     WITH_MOD("asyncio.base_futures") | 
 | 2375 |     GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info") | 
 | 2376 |     GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") | 
 | 2377 |     GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") | 
 | 2378 |  | 
 | 2379 |     WITH_MOD("asyncio.base_tasks") | 
 | 2380 |     GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info") | 
 | 2381 |     GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") | 
 | 2382 |     GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") | 
 | 2383 |  | 
 | 2384 |     WITH_MOD("inspect") | 
 | 2385 |     GET_MOD_ATTR(inspect_isgenerator, "isgenerator") | 
 | 2386 |  | 
 | 2387 |     WITH_MOD("traceback") | 
 | 2388 |     GET_MOD_ATTR(traceback_extract_stack, "extract_stack") | 
 | 2389 |  | 
 | 2390 |     WITH_MOD("weakref") | 
 | 2391 |     GET_MOD_ATTR(cls, "WeakSet") | 
| Victor Stinner | a5ed5f0 | 2016-12-06 18:45:50 +0100 | [diff] [blame] | 2392 |     all_tasks = _PyObject_CallNoArg(cls); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2393 |     Py_CLEAR(cls); | 
 | 2394 |     if (all_tasks == NULL) { | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2395 |         goto fail; | 
 | 2396 |     } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2397 |  | 
| Yury Selivanov | 684ef2c | 2016-10-28 19:01:21 -0400 | [diff] [blame] | 2398 |     current_tasks = PyDict_New(); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2399 |     if (current_tasks == NULL) { | 
 | 2400 |         goto fail; | 
 | 2401 |     } | 
 | 2402 |  | 
 | 2403 |     Py_CLEAR(module); | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2404 |     return 0; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2405 |  | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2406 | fail: | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2407 |     Py_CLEAR(module); | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2408 |     module_free(NULL); | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2409 |     return -1; | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2410 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2411 | #undef WITH_MOD | 
 | 2412 | #undef GET_MOD_ATTR | 
 | 2413 | } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2414 |  | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2415 | PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2416 |  | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 2417 | static struct PyModuleDef _asynciomodule = { | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2418 |     PyModuleDef_HEAD_INIT,      /* m_base */ | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 2419 |     "_asyncio",                 /* m_name */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2420 |     module_doc,                 /* m_doc */ | 
 | 2421 |     -1,                         /* m_size */ | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2422 |     NULL,                       /* m_methods */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2423 |     NULL,                       /* m_slots */ | 
 | 2424 |     NULL,                       /* m_traverse */ | 
 | 2425 |     NULL,                       /* m_clear */ | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2426 |     (freefunc)module_free       /* m_free */ | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2427 | }; | 
 | 2428 |  | 
 | 2429 |  | 
 | 2430 | PyMODINIT_FUNC | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 2431 | PyInit__asyncio(void) | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2432 | { | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2433 |     if (module_init() < 0) { | 
| INADA Naoki | c411a7d | 2016-10-18 11:48:14 +0900 | [diff] [blame] | 2434 |         return NULL; | 
 | 2435 |     } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2436 |     if (PyType_Ready(&FutureType) < 0) { | 
 | 2437 |         return NULL; | 
 | 2438 |     } | 
 | 2439 |     if (PyType_Ready(&FutureIterType) < 0) { | 
 | 2440 |         return NULL; | 
 | 2441 |     } | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2442 |     if (PyType_Ready(&TaskSendMethWrapper_Type) < 0) { | 
 | 2443 |         return NULL; | 
 | 2444 |     } | 
 | 2445 |     if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { | 
 | 2446 |         return NULL; | 
 | 2447 |     } | 
 | 2448 |     if (PyType_Ready(&TaskType) < 0) { | 
 | 2449 |         return NULL; | 
 | 2450 |     } | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2451 |  | 
| INADA Naoki | 9f2ce25 | 2016-10-15 15:39:19 +0900 | [diff] [blame] | 2452 |     PyObject *m = PyModule_Create(&_asynciomodule); | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2453 |     if (m == NULL) { | 
 | 2454 |         return NULL; | 
 | 2455 |     } | 
 | 2456 |  | 
 | 2457 |     Py_INCREF(&FutureType); | 
 | 2458 |     if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { | 
 | 2459 |         Py_DECREF(&FutureType); | 
 | 2460 |         return NULL; | 
 | 2461 |     } | 
 | 2462 |  | 
| Yury Selivanov | a0c1ba6 | 2016-10-28 12:52:37 -0400 | [diff] [blame] | 2463 |     Py_INCREF(&TaskType); | 
 | 2464 |     if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { | 
 | 2465 |         Py_DECREF(&TaskType); | 
 | 2466 |         return NULL; | 
 | 2467 |     } | 
 | 2468 |  | 
| INADA Naoki | 9e4e38e | 2016-10-09 14:44:47 +0900 | [diff] [blame] | 2469 |     return m; | 
 | 2470 | } |