blob: d4b313480e9a1072ce4e71b5b0a671ae388df69b [file] [log] [blame]
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001#include "Python.h"
2#include "structmember.h"
3
4
Yury Selivanova0c1ba62016-10-28 12:52:37 -04005/*[clinic input]
6module _asyncio
7[clinic start generated code]*/
8/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/
9
10
INADA Naoki9e4e38e2016-10-09 14:44:47 +090011/* identifiers used from some functions */
Yury Selivanova0c1ba62016-10-28 12:52:37 -040012_Py_IDENTIFIER(add_done_callback);
INADA Naoki9e4e38e2016-10-09 14:44:47 +090013_Py_IDENTIFIER(call_soon);
Yury Selivanova0c1ba62016-10-28 12:52:37 -040014_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 Naoki9e4e38e2016-10-09 14:44:47 +090020
21
INADA Naoki9f2ce252016-10-15 15:39:19 +090022/* State of the _asyncio module */
Yury Selivanova0c1ba62016-10-28 12:52:37 -040023static PyObject *all_tasks;
Yury Selivanov684ef2c2016-10-28 19:01:21 -040024static PyObject *current_tasks;
INADA Naoki9e4e38e2016-10-09 14:44:47 +090025static PyObject *traceback_extract_stack;
26static PyObject *asyncio_get_event_loop;
Yury Selivanova0c1ba62016-10-28 12:52:37 -040027static PyObject *asyncio_future_repr_info_func;
28static PyObject *asyncio_task_repr_info_func;
29static PyObject *asyncio_task_get_stack_func;
30static PyObject *asyncio_task_print_stack_func;
INADA Naoki9e4e38e2016-10-09 14:44:47 +090031static PyObject *asyncio_InvalidStateError;
32static PyObject *asyncio_CancelledError;
Yury Selivanova0c1ba62016-10-28 12:52:37 -040033static PyObject *inspect_isgenerator;
INADA Naoki9e4e38e2016-10-09 14:44:47 +090034
35
INADA Naoki9e4e38e2016-10-09 14:44:47 +090036typedef enum {
37 STATE_PENDING,
38 STATE_CANCELLED,
39 STATE_FINISHED
40} fut_state;
41
Yury Selivanova0c1ba62016-10-28 12:52:37 -040042#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
55typedef struct {
56 FutureObj_HEAD(fut)
57} FutureObj;
58
59typedef 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 Naoki9e4e38e2016-10-09 14:44:47 +090066
67typedef struct {
68 PyObject_HEAD
Yury Selivanova0c1ba62016-10-28 12:52:37 -040069 TaskObj *sw_task;
70 PyObject *sw_arg;
71} TaskSendMethWrapper;
INADA Naoki9e4e38e2016-10-09 14:44:47 +090072
Yury Selivanova0c1ba62016-10-28 12:52:37 -040073typedef struct {
74 PyObject_HEAD
75 TaskObj *ww_task;
76} TaskWakeupMethWrapper;
77
78
79#include "clinic/_asynciomodule.c.h"
80
81
82/*[clinic input]
83class _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 */
88static PyObject* future_new_iter(PyObject *);
89static inline int future_call_schedule_callbacks(FutureObj *);
INADA Naoki9e4e38e2016-10-09 14:44:47 +090090
91static int
Yury Selivanova0c1ba62016-10-28 12:52:37 -040092future_schedule_callbacks(FutureObj *fut)
INADA Naoki9e4e38e2016-10-09 14:44:47 +090093{
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 Stinnerb6ed57d2016-12-09 14:24:02 +0100121 handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop, &PyId_call_soon,
122 cb, fut, NULL);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900123
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
137static int
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400138future_init(FutureObj *fut, PyObject *loop)
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900139{
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900140 PyObject *res = NULL;
141 _Py_IDENTIFIER(get_debug);
142
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900143 if (loop == NULL || loop == Py_None) {
Victor Stinnera5ed5f02016-12-06 18:45:50 +0100144 loop = _PyObject_CallNoArg(asyncio_get_event_loop);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900145 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 Stinnerf94d1ee2016-10-29 09:05:39 +0200155 res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900156 if (res == NULL) {
157 return -1;
158 }
159 if (PyObject_IsTrue(res)) {
160 Py_CLEAR(res);
Victor Stinnera5ed5f02016-12-06 18:45:50 +0100161 fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900162 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 Selivanova0c1ba62016-10-28 12:52:37 -0400174
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900175 return 0;
176}
177
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900178static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400179future_set_result(FutureObj *fut, PyObject *res)
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900180{
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900181 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 Selivanova0c1ba62016-10-28 12:52:37 -0400190 if (future_call_schedule_callbacks(fut) == -1) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900191 return NULL;
192 }
193 Py_RETURN_NONE;
194}
195
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900196static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400197future_set_exception(FutureObj *fut, PyObject *exc)
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900198{
199 PyObject *exc_val = NULL;
200
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900201 if (fut->fut_state != STATE_PENDING) {
202 PyErr_SetString(asyncio_InvalidStateError, "invalid state");
203 return NULL;
204 }
205
206 if (PyExceptionClass_Check(exc)) {
Victor Stinnera5ed5f02016-12-06 18:45:50 +0100207 exc_val = _PyObject_CallNoArg(exc);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900208 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 Selivanova0c1ba62016-10-28 12:52:37 -0400232 if (future_call_schedule_callbacks(fut) == -1) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900233 return NULL;
234 }
235
236 fut->fut_log_tb = 1;
237 Py_RETURN_NONE;
238}
239
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400240static int
241future_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 Stinner7bfb42d2016-12-05 17:04:32 +0100260 exc = PyObject_CallFunctionObjArgs(asyncio_InvalidStateError, msg, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400261 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 Naoki9e4e38e2016-10-09 14:44:47 +0900281
282static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400283future_add_done_callback(FutureObj *fut, PyObject *arg)
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900284{
285 if (fut->fut_state != STATE_PENDING) {
Victor Stinnerb6ed57d2016-12-09 14:24:02 +0100286 PyObject *handle = _PyObject_CallMethodIdObjArgs(fut->fut_loop,
287 &PyId_call_soon,
288 arg, fut, NULL);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900289
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 Selivanova0c1ba62016-10-28 12:52:37 -0400306static PyObject *
307future_cancel(FutureObj *fut)
308{
Yury Selivanov7ce1c6f2017-06-11 13:49:18 +0000309 fut->fut_log_tb = 0;
310
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400311 if (fut->fut_state != STATE_PENDING) {
312 Py_RETURN_FALSE;
313 }
314 fut->fut_state = STATE_CANCELLED;
315
316 if (future_call_schedule_callbacks(fut) == -1) {
317 return NULL;
318 }
319
320 Py_RETURN_TRUE;
321}
322
323/*[clinic input]
324_asyncio.Future.__init__
325
326 *
327 loop: 'O' = NULL
328
329This class is *almost* compatible with concurrent.futures.Future.
330
331 Differences:
332
333 - result() and exception() do not take a timeout argument and
334 raise an exception when the future isn't done yet.
335
336 - Callbacks registered with add_done_callback() are always called
337 via the event loop's call_soon_threadsafe().
338
339 - This class is not compatible with the wait() and as_completed()
340 methods in the concurrent.futures package.
341[clinic start generated code]*/
342
343static int
344_asyncio_Future___init___impl(FutureObj *self, PyObject *loop)
345/*[clinic end generated code: output=9ed75799eaccb5d6 input=8e1681f23605be2d]*/
346
347{
348 return future_init(self, loop);
349}
350
351static int
352FutureObj_clear(FutureObj *fut)
353{
354 Py_CLEAR(fut->fut_loop);
355 Py_CLEAR(fut->fut_callbacks);
356 Py_CLEAR(fut->fut_result);
357 Py_CLEAR(fut->fut_exception);
358 Py_CLEAR(fut->fut_source_tb);
359 Py_CLEAR(fut->dict);
360 return 0;
361}
362
363static int
364FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg)
365{
366 Py_VISIT(fut->fut_loop);
367 Py_VISIT(fut->fut_callbacks);
368 Py_VISIT(fut->fut_result);
369 Py_VISIT(fut->fut_exception);
370 Py_VISIT(fut->fut_source_tb);
371 Py_VISIT(fut->dict);
372 return 0;
373}
374
375/*[clinic input]
376_asyncio.Future.result
377
378Return the result this future represents.
379
380If the future has been cancelled, raises CancelledError. If the
381future's result isn't yet available, raises InvalidStateError. If
382the future is done and has an exception set, this exception is raised.
383[clinic start generated code]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900384
385static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400386_asyncio_Future_result_impl(FutureObj *self)
387/*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/
388{
389 PyObject *result;
390 int res = future_get_result(self, &result);
391
392 if (res == -1) {
393 return NULL;
394 }
395
396 if (res == 0) {
397 return result;
398 }
399
400 assert(res == 1);
401
402 PyErr_SetObject(PyExceptionInstance_Class(result), result);
403 Py_DECREF(result);
404 return NULL;
405}
406
407/*[clinic input]
408_asyncio.Future.exception
409
410Return the exception that was set on this future.
411
412The exception (or None if no exception was set) is returned only if
413the future is done. If the future has been cancelled, raises
414CancelledError. If the future isn't done yet, raises
415InvalidStateError.
416[clinic start generated code]*/
417
418static PyObject *
419_asyncio_Future_exception_impl(FutureObj *self)
420/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/
421{
422 if (self->fut_state == STATE_CANCELLED) {
423 PyErr_SetString(asyncio_CancelledError, "");
424 return NULL;
425 }
426
427 if (self->fut_state != STATE_FINISHED) {
428 PyErr_SetString(asyncio_InvalidStateError, "Result is not ready.");
429 return NULL;
430 }
431
432 if (self->fut_exception != NULL) {
433 self->fut_log_tb = 0;
434 Py_INCREF(self->fut_exception);
435 return self->fut_exception;
436 }
437
438 Py_RETURN_NONE;
439}
440
441/*[clinic input]
442_asyncio.Future.set_result
443
444 res: 'O'
445 /
446
447Mark the future done and set its result.
448
449If the future is already done when this method is called, raises
450InvalidStateError.
451[clinic start generated code]*/
452
453static PyObject *
454_asyncio_Future_set_result(FutureObj *self, PyObject *res)
455/*[clinic end generated code: output=a620abfc2796bfb6 input=8619565e0503357e]*/
456{
457 return future_set_result(self, res);
458}
459
460/*[clinic input]
461_asyncio.Future.set_exception
462
463 exception: 'O'
464 /
465
466Mark the future done and set an exception.
467
468If the future is already done when this method is called, raises
469InvalidStateError.
470[clinic start generated code]*/
471
472static PyObject *
473_asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
474/*[clinic end generated code: output=f1c1b0cd321be360 input=1377dbe15e6ea186]*/
475{
476 return future_set_exception(self, exception);
477}
478
479/*[clinic input]
480_asyncio.Future.add_done_callback
481
482 fn: 'O'
483 /
484
485Add a callback to be run when the future becomes done.
486
487The callback is called with a single argument - the future object. If
488the future is already done when this is called, the callback is
489scheduled with call_soon.
490[clinic start generated code]*/
491
492static PyObject *
493_asyncio_Future_add_done_callback(FutureObj *self, PyObject *fn)
494/*[clinic end generated code: output=819e09629b2ec2b5 input=8cce187e32cec6a8]*/
495{
496 return future_add_done_callback(self, fn);
497}
498
499/*[clinic input]
500_asyncio.Future.remove_done_callback
501
502 fn: 'O'
503 /
504
505Remove all instances of a callback from the "call when done" list.
506
507Returns the number of callbacks removed.
508[clinic start generated code]*/
509
510static PyObject *
511_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
512/*[clinic end generated code: output=5ab1fb52b24ef31f input=3fedb73e1409c31c]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900513{
514 PyObject *newlist;
515 Py_ssize_t len, i, j=0;
516
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400517 len = PyList_GET_SIZE(self->fut_callbacks);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900518 if (len == 0) {
519 return PyLong_FromSsize_t(0);
520 }
521
522 newlist = PyList_New(len);
523 if (newlist == NULL) {
524 return NULL;
525 }
526
Yury Selivanov84af9032017-03-02 23:46:56 -0500527 for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900528 int ret;
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400529 PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900530
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400531 if ((ret = PyObject_RichCompareBool(fn, item, Py_EQ)) < 0) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900532 goto fail;
533 }
534 if (ret == 0) {
Yury Selivanov833a3b02017-07-05 13:32:03 -0400535 if (j < len) {
536 Py_INCREF(item);
537 PyList_SET_ITEM(newlist, j, item);
538 j++;
539 }
540 else {
541 if (PyList_Append(newlist, item)) {
542 goto fail;
543 }
544 }
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900545 }
546 }
547
548 if (PyList_SetSlice(newlist, j, len, NULL) < 0) {
549 goto fail;
550 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400551 if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900552 goto fail;
553 }
554 Py_DECREF(newlist);
555 return PyLong_FromSsize_t(len - j);
556
557fail:
558 Py_DECREF(newlist);
559 return NULL;
560}
561
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400562/*[clinic input]
563_asyncio.Future.cancel
564
565Cancel the future and schedule callbacks.
566
567If the future is already done or cancelled, return False. Otherwise,
568change the future's state to cancelled, schedule the callbacks and
569return True.
570[clinic start generated code]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900571
572static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400573_asyncio_Future_cancel_impl(FutureObj *self)
574/*[clinic end generated code: output=e45b932ba8bd68a1 input=515709a127995109]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900575{
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400576 return future_cancel(self);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900577}
578
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400579/*[clinic input]
580_asyncio.Future.cancelled
581
582Return True if the future was cancelled.
583[clinic start generated code]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900584
585static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400586_asyncio_Future_cancelled_impl(FutureObj *self)
587/*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900588{
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400589 if (self->fut_state == STATE_CANCELLED) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900590 Py_RETURN_TRUE;
591 }
592 else {
593 Py_RETURN_FALSE;
594 }
595}
596
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400597/*[clinic input]
598_asyncio.Future.done
599
600Return True if the future is done.
601
602Done means either that a result / exception are available, or that the
603future was cancelled.
604[clinic start generated code]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900605
606static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400607_asyncio_Future_done_impl(FutureObj *self)
608/*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900609{
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400610 if (self->fut_state == STATE_PENDING) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900611 Py_RETURN_FALSE;
612 }
613 else {
614 Py_RETURN_TRUE;
615 }
616}
617
618static PyObject *
619FutureObj_get_blocking(FutureObj *fut)
620{
621 if (fut->fut_blocking) {
622 Py_RETURN_TRUE;
623 }
624 else {
625 Py_RETURN_FALSE;
626 }
627}
628
629static int
630FutureObj_set_blocking(FutureObj *fut, PyObject *val)
631{
632 int is_true = PyObject_IsTrue(val);
633 if (is_true < 0) {
634 return -1;
635 }
636 fut->fut_blocking = is_true;
637 return 0;
638}
639
640static PyObject *
641FutureObj_get_log_traceback(FutureObj *fut)
642{
643 if (fut->fut_log_tb) {
644 Py_RETURN_TRUE;
645 }
646 else {
647 Py_RETURN_FALSE;
648 }
649}
650
Yury Selivanov7ce1c6f2017-06-11 13:49:18 +0000651static int
652FutureObj_set_log_traceback(FutureObj *fut, PyObject *val)
653{
654 int is_true = PyObject_IsTrue(val);
655 if (is_true < 0) {
656 return -1;
657 }
658 fut->fut_log_tb = is_true;
659 return 0;
660}
661
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900662static PyObject *
663FutureObj_get_loop(FutureObj *fut)
664{
665 if (fut->fut_loop == NULL) {
666 Py_RETURN_NONE;
667 }
668 Py_INCREF(fut->fut_loop);
669 return fut->fut_loop;
670}
671
672static PyObject *
673FutureObj_get_callbacks(FutureObj *fut)
674{
675 if (fut->fut_callbacks == NULL) {
676 Py_RETURN_NONE;
677 }
678 Py_INCREF(fut->fut_callbacks);
679 return fut->fut_callbacks;
680}
681
682static PyObject *
683FutureObj_get_result(FutureObj *fut)
684{
685 if (fut->fut_result == NULL) {
686 Py_RETURN_NONE;
687 }
688 Py_INCREF(fut->fut_result);
689 return fut->fut_result;
690}
691
692static PyObject *
693FutureObj_get_exception(FutureObj *fut)
694{
695 if (fut->fut_exception == NULL) {
696 Py_RETURN_NONE;
697 }
698 Py_INCREF(fut->fut_exception);
699 return fut->fut_exception;
700}
701
702static PyObject *
703FutureObj_get_source_traceback(FutureObj *fut)
704{
705 if (fut->fut_source_tb == NULL) {
706 Py_RETURN_NONE;
707 }
708 Py_INCREF(fut->fut_source_tb);
709 return fut->fut_source_tb;
710}
711
712static PyObject *
713FutureObj_get_state(FutureObj *fut)
714{
715 _Py_IDENTIFIER(PENDING);
716 _Py_IDENTIFIER(CANCELLED);
717 _Py_IDENTIFIER(FINISHED);
718 PyObject *ret = NULL;
719
720 switch (fut->fut_state) {
721 case STATE_PENDING:
722 ret = _PyUnicode_FromId(&PyId_PENDING);
723 break;
724 case STATE_CANCELLED:
725 ret = _PyUnicode_FromId(&PyId_CANCELLED);
726 break;
727 case STATE_FINISHED:
728 ret = _PyUnicode_FromId(&PyId_FINISHED);
729 break;
730 default:
731 assert (0);
732 }
733 Py_INCREF(ret);
734 return ret;
735}
736
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400737/*[clinic input]
738_asyncio.Future._repr_info
739[clinic start generated code]*/
740
741static PyObject *
742_asyncio_Future__repr_info_impl(FutureObj *self)
743/*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900744{
Victor Stinnerde4ae3d2016-12-04 22:59:09 +0100745 return PyObject_CallFunctionObjArgs(
746 asyncio_future_repr_info_func, self, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400747}
748
749/*[clinic input]
750_asyncio.Future._schedule_callbacks
751[clinic start generated code]*/
752
753static PyObject *
754_asyncio_Future__schedule_callbacks_impl(FutureObj *self)
755/*[clinic end generated code: output=5e8958d89ea1c5dc input=4f5f295f263f4a88]*/
756{
757 int ret = future_schedule_callbacks(self);
758 if (ret == -1) {
759 return NULL;
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900760 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400761 Py_RETURN_NONE;
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900762}
763
764static PyObject *
765FutureObj_repr(FutureObj *fut)
766{
767 _Py_IDENTIFIER(_repr_info);
768
769 PyObject *_repr_info = _PyUnicode_FromId(&PyId__repr_info); // borrowed
770 if (_repr_info == NULL) {
771 return NULL;
772 }
773
774 PyObject *rinfo = PyObject_CallMethodObjArgs((PyObject*)fut, _repr_info,
775 NULL);
776 if (rinfo == NULL) {
777 return NULL;
778 }
779
780 PyObject *sp = PyUnicode_FromString(" ");
781 if (sp == NULL) {
782 Py_DECREF(rinfo);
783 return NULL;
784 }
785
786 PyObject *rinfo_s = PyUnicode_Join(sp, rinfo);
787 Py_DECREF(sp);
788 Py_DECREF(rinfo);
789 if (rinfo_s == NULL) {
790 return NULL;
791 }
792
793 PyObject *rstr = NULL;
794 PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut),
795 "__name__");
796 if (type_name != NULL) {
797 rstr = PyUnicode_FromFormat("<%S %S>", type_name, rinfo_s);
798 Py_DECREF(type_name);
799 }
800 Py_DECREF(rinfo_s);
801 return rstr;
802}
803
804static void
805FutureObj_finalize(FutureObj *fut)
806{
807 _Py_IDENTIFIER(call_exception_handler);
808 _Py_IDENTIFIER(message);
809 _Py_IDENTIFIER(exception);
810 _Py_IDENTIFIER(future);
811 _Py_IDENTIFIER(source_traceback);
812
813 if (!fut->fut_log_tb) {
814 return;
815 }
816 assert(fut->fut_exception != NULL);
817 fut->fut_log_tb = 0;;
818
819 PyObject *error_type, *error_value, *error_traceback;
820 /* Save the current exception, if any. */
821 PyErr_Fetch(&error_type, &error_value, &error_traceback);
822
823 PyObject *context = NULL;
824 PyObject *type_name = NULL;
825 PyObject *message = NULL;
826 PyObject *func = NULL;
827 PyObject *res = NULL;
828
829 context = PyDict_New();
830 if (context == NULL) {
831 goto finally;
832 }
833
834 type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__");
835 if (type_name == NULL) {
836 goto finally;
837 }
838
839 message = PyUnicode_FromFormat(
840 "%S exception was never retrieved", type_name);
841 if (message == NULL) {
842 goto finally;
843 }
844
845 if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
846 _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 ||
847 _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) {
848 goto finally;
849 }
850 if (fut->fut_source_tb != NULL) {
851 if (_PyDict_SetItemId(context, &PyId_source_traceback,
852 fut->fut_source_tb) < 0) {
853 goto finally;
854 }
855 }
856
857 func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler);
858 if (func != NULL) {
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100859 res = PyObject_CallFunctionObjArgs(func, context, NULL);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900860 if (res == NULL) {
861 PyErr_WriteUnraisable(func);
862 }
863 }
864
865finally:
866 Py_CLEAR(context);
867 Py_CLEAR(type_name);
868 Py_CLEAR(message);
869 Py_CLEAR(func);
870 Py_CLEAR(res);
871
872 /* Restore the saved exception. */
873 PyErr_Restore(error_type, error_value, error_traceback);
874}
875
876
877static PyAsyncMethods FutureType_as_async = {
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400878 (unaryfunc)future_new_iter, /* am_await */
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900879 0, /* am_aiter */
880 0 /* am_anext */
881};
882
883static PyMethodDef FutureType_methods[] = {
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400884 _ASYNCIO_FUTURE_RESULT_METHODDEF
885 _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
886 _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
887 _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
888 _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
889 _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
890 _ASYNCIO_FUTURE_CANCEL_METHODDEF
891 _ASYNCIO_FUTURE_CANCELLED_METHODDEF
892 _ASYNCIO_FUTURE_DONE_METHODDEF
893 _ASYNCIO_FUTURE__REPR_INFO_METHODDEF
894 _ASYNCIO_FUTURE__SCHEDULE_CALLBACKS_METHODDEF
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900895 {NULL, NULL} /* Sentinel */
896};
897
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400898#define FUTURE_COMMON_GETSETLIST \
899 {"_state", (getter)FutureObj_get_state, NULL, NULL}, \
900 {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, \
901 (setter)FutureObj_set_blocking, NULL}, \
902 {"_loop", (getter)FutureObj_get_loop, NULL, NULL}, \
903 {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL}, \
904 {"_result", (getter)FutureObj_get_result, NULL, NULL}, \
905 {"_exception", (getter)FutureObj_get_exception, NULL, NULL}, \
Yury Selivanov7ce1c6f2017-06-11 13:49:18 +0000906 {"_log_traceback", (getter)FutureObj_get_log_traceback, \
907 (setter)FutureObj_set_log_traceback, NULL}, \
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900908 {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL},
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400909
910static PyGetSetDef FutureType_getsetlist[] = {
911 FUTURE_COMMON_GETSETLIST
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900912 {NULL} /* Sentinel */
913};
914
915static void FutureObj_dealloc(PyObject *self);
916
917static PyTypeObject FutureType = {
Victor Stinner1aea8fb2016-10-28 19:13:52 +0200918 PyVarObject_HEAD_INIT(NULL, 0)
INADA Naoki9f2ce252016-10-15 15:39:19 +0900919 "_asyncio.Future",
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900920 sizeof(FutureObj), /* tp_basicsize */
921 .tp_dealloc = FutureObj_dealloc,
922 .tp_as_async = &FutureType_as_async,
923 .tp_repr = (reprfunc)FutureObj_repr,
924 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE
925 | Py_TPFLAGS_HAVE_FINALIZE,
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400926 .tp_doc = _asyncio_Future___init____doc__,
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900927 .tp_traverse = (traverseproc)FutureObj_traverse,
928 .tp_clear = (inquiry)FutureObj_clear,
929 .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist),
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400930 .tp_iter = (getiterfunc)future_new_iter,
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900931 .tp_methods = FutureType_methods,
932 .tp_getset = FutureType_getsetlist,
933 .tp_dictoffset = offsetof(FutureObj, dict),
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400934 .tp_init = (initproc)_asyncio_Future___init__,
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900935 .tp_new = PyType_GenericNew,
936 .tp_finalize = (destructor)FutureObj_finalize,
937};
938
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400939#define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType)
940
941static inline int
942future_call_schedule_callbacks(FutureObj *fut)
943{
944 if (Future_CheckExact(fut)) {
945 return future_schedule_callbacks(fut);
946 }
947 else {
948 /* `fut` is a subclass of Future */
949 PyObject *ret = _PyObject_CallMethodId(
950 (PyObject*)fut, &PyId__schedule_callbacks, NULL);
951 if (ret == NULL) {
952 return -1;
953 }
954
955 Py_DECREF(ret);
956 return 0;
957 }
958}
959
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900960static void
961FutureObj_dealloc(PyObject *self)
962{
963 FutureObj *fut = (FutureObj *)self;
964
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400965 if (Future_CheckExact(fut)) {
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900966 /* When fut is subclass of Future, finalizer is called from
967 * subtype_dealloc.
968 */
969 if (PyObject_CallFinalizerFromDealloc(self) < 0) {
970 // resurrected.
971 return;
972 }
973 }
974
Alexander Mohrde34cbe2017-08-01 23:31:07 -0700975 PyObject_GC_UnTrack(self);
976
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900977 if (fut->fut_weakreflist != NULL) {
978 PyObject_ClearWeakRefs(self);
979 }
980
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400981 (void)FutureObj_clear(fut);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900982 Py_TYPE(fut)->tp_free(fut);
983}
984
985
986/*********************** Future Iterator **************************/
987
988typedef struct {
989 PyObject_HEAD
990 FutureObj *future;
991} futureiterobject;
992
993static void
994FutureIter_dealloc(futureiterobject *it)
995{
Yury Selivanova0c1ba62016-10-28 12:52:37 -0400996 PyObject_GC_UnTrack(it);
INADA Naoki9e4e38e2016-10-09 14:44:47 +0900997 Py_XDECREF(it->future);
998 PyObject_GC_Del(it);
999}
1000
1001static PyObject *
1002FutureIter_iternext(futureiterobject *it)
1003{
1004 PyObject *res;
1005 FutureObj *fut = it->future;
1006
1007 if (fut == NULL) {
1008 return NULL;
1009 }
1010
1011 if (fut->fut_state == STATE_PENDING) {
1012 if (!fut->fut_blocking) {
1013 fut->fut_blocking = 1;
1014 Py_INCREF(fut);
1015 return (PyObject *)fut;
1016 }
1017 PyErr_Format(PyExc_AssertionError,
1018 "yield from wasn't used with future");
1019 return NULL;
1020 }
1021
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001022 res = _asyncio_Future_result_impl(fut);
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001023 if (res != NULL) {
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +02001024 /* The result of the Future is not an exception. */
1025 if (_PyGen_SetStopIterationValue(res) < 0) {
1026 Py_DECREF(res);
Yury Selivanova4b884f2016-10-20 15:54:20 -04001027 return NULL;
1028 }
Serhiy Storchaka60e49aa2016-11-06 18:47:03 +02001029 Py_DECREF(res);
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001030 }
1031
1032 it->future = NULL;
1033 Py_DECREF(fut);
1034 return NULL;
1035}
1036
1037static PyObject *
INADA Naoki74c17532016-10-25 19:00:45 +09001038FutureIter_send(futureiterobject *self, PyObject *unused)
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001039{
INADA Naoki74c17532016-10-25 19:00:45 +09001040 /* Future.__iter__ doesn't care about values that are pushed to the
1041 * generator, it just returns "self.result().
1042 */
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001043 return FutureIter_iternext(self);
1044}
1045
1046static PyObject *
1047FutureIter_throw(futureiterobject *self, PyObject *args)
1048{
1049 PyObject *type=NULL, *val=NULL, *tb=NULL;
1050 if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb))
1051 return NULL;
1052
1053 if (val == Py_None) {
1054 val = NULL;
1055 }
1056 if (tb == Py_None) {
1057 tb = NULL;
Benjamin Peterson996fc1f2016-11-14 00:15:44 -08001058 } else if (tb != NULL && !PyTraceBack_Check(tb)) {
1059 PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback");
1060 return NULL;
1061 }
1062
1063 Py_INCREF(type);
1064 Py_XINCREF(val);
1065 Py_XINCREF(tb);
1066
1067 if (PyExceptionClass_Check(type)) {
1068 PyErr_NormalizeException(&type, &val, &tb);
Yury Selivanovedfe8862016-12-01 11:37:47 -05001069 /* No need to call PyException_SetTraceback since we'll be calling
1070 PyErr_Restore for `type`, `val`, and `tb`. */
Benjamin Peterson996fc1f2016-11-14 00:15:44 -08001071 } else if (PyExceptionInstance_Check(type)) {
1072 if (val) {
1073 PyErr_SetString(PyExc_TypeError,
1074 "instance exception may not have a separate value");
1075 goto fail;
1076 }
1077 val = type;
1078 type = PyExceptionInstance_Class(type);
1079 Py_INCREF(type);
1080 if (tb == NULL)
1081 tb = PyException_GetTraceback(val);
1082 } else {
1083 PyErr_SetString(PyExc_TypeError,
1084 "exceptions must be classes deriving BaseException or "
1085 "instances of such a class");
1086 goto fail;
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001087 }
1088
1089 Py_CLEAR(self->future);
1090
Benjamin Peterson996fc1f2016-11-14 00:15:44 -08001091 PyErr_Restore(type, val, tb);
1092
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001093 return FutureIter_iternext(self);
Benjamin Peterson996fc1f2016-11-14 00:15:44 -08001094
1095 fail:
1096 Py_DECREF(type);
1097 Py_XDECREF(val);
1098 Py_XDECREF(tb);
1099 return NULL;
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001100}
1101
1102static PyObject *
1103FutureIter_close(futureiterobject *self, PyObject *arg)
1104{
1105 Py_CLEAR(self->future);
1106 Py_RETURN_NONE;
1107}
1108
1109static int
1110FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg)
1111{
1112 Py_VISIT(it->future);
1113 return 0;
1114}
1115
1116static PyMethodDef FutureIter_methods[] = {
1117 {"send", (PyCFunction)FutureIter_send, METH_O, NULL},
1118 {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL},
1119 {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL},
1120 {NULL, NULL} /* Sentinel */
1121};
1122
1123static PyTypeObject FutureIterType = {
Victor Stinner1aea8fb2016-10-28 19:13:52 +02001124 PyVarObject_HEAD_INIT(NULL, 0)
INADA Naoki9f2ce252016-10-15 15:39:19 +09001125 "_asyncio.FutureIter",
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001126 .tp_basicsize = sizeof(futureiterobject),
1127 .tp_itemsize = 0,
1128 .tp_dealloc = (destructor)FutureIter_dealloc,
1129 .tp_getattro = PyObject_GenericGetAttr,
1130 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1131 .tp_traverse = (traverseproc)FutureIter_traverse,
1132 .tp_iter = PyObject_SelfIter,
1133 .tp_iternext = (iternextfunc)FutureIter_iternext,
1134 .tp_methods = FutureIter_methods,
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001135};
1136
1137static PyObject *
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001138future_new_iter(PyObject *fut)
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001139{
1140 futureiterobject *it;
1141
1142 if (!PyObject_TypeCheck(fut, &FutureType)) {
1143 PyErr_BadInternalCall();
1144 return NULL;
1145 }
1146 it = PyObject_GC_New(futureiterobject, &FutureIterType);
1147 if (it == NULL) {
1148 return NULL;
1149 }
1150 Py_INCREF(fut);
1151 it->future = (FutureObj*)fut;
INADA Naoki1be427b2016-10-11 02:12:34 +09001152 PyObject_GC_Track(it);
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001153 return (PyObject*)it;
1154}
1155
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001156
1157/*********************** Task **************************/
1158
1159
1160/*[clinic input]
1161class _asyncio.Task "TaskObj *" "&Task_Type"
1162[clinic start generated code]*/
1163/*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/
1164
1165static int task_call_step_soon(TaskObj *, PyObject *);
1166static inline PyObject * task_call_wakeup(TaskObj *, PyObject *);
1167static inline PyObject * task_call_step(TaskObj *, PyObject *);
1168static PyObject * task_wakeup(TaskObj *, PyObject *);
1169static PyObject * task_step(TaskObj *, PyObject *);
1170
1171/* ----- Task._step wrapper */
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001172
INADA Naokic411a7d2016-10-18 11:48:14 +09001173static int
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001174TaskSendMethWrapper_clear(TaskSendMethWrapper *o)
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001175{
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001176 Py_CLEAR(o->sw_task);
1177 Py_CLEAR(o->sw_arg);
1178 return 0;
1179}
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001180
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001181static void
1182TaskSendMethWrapper_dealloc(TaskSendMethWrapper *o)
1183{
1184 PyObject_GC_UnTrack(o);
1185 (void)TaskSendMethWrapper_clear(o);
1186 Py_TYPE(o)->tp_free(o);
1187}
1188
1189static PyObject *
1190TaskSendMethWrapper_call(TaskSendMethWrapper *o,
1191 PyObject *args, PyObject *kwds)
1192{
1193 return task_call_step(o->sw_task, o->sw_arg);
1194}
1195
1196static int
1197TaskSendMethWrapper_traverse(TaskSendMethWrapper *o,
1198 visitproc visit, void *arg)
1199{
1200 Py_VISIT(o->sw_task);
1201 Py_VISIT(o->sw_arg);
1202 return 0;
1203}
1204
1205static PyObject *
1206TaskSendMethWrapper_get___self__(TaskSendMethWrapper *o)
1207{
1208 if (o->sw_task) {
1209 Py_INCREF(o->sw_task);
1210 return (PyObject*)o->sw_task;
1211 }
1212 Py_RETURN_NONE;
1213}
1214
1215static PyGetSetDef TaskSendMethWrapper_getsetlist[] = {
1216 {"__self__", (getter)TaskSendMethWrapper_get___self__, NULL, NULL},
1217 {NULL} /* Sentinel */
1218};
1219
1220PyTypeObject TaskSendMethWrapper_Type = {
Victor Stinner1aea8fb2016-10-28 19:13:52 +02001221 PyVarObject_HEAD_INIT(NULL, 0)
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001222 "TaskSendMethWrapper",
1223 .tp_basicsize = sizeof(TaskSendMethWrapper),
1224 .tp_itemsize = 0,
1225 .tp_getset = TaskSendMethWrapper_getsetlist,
1226 .tp_dealloc = (destructor)TaskSendMethWrapper_dealloc,
1227 .tp_call = (ternaryfunc)TaskSendMethWrapper_call,
1228 .tp_getattro = PyObject_GenericGetAttr,
1229 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1230 .tp_traverse = (traverseproc)TaskSendMethWrapper_traverse,
1231 .tp_clear = (inquiry)TaskSendMethWrapper_clear,
1232};
1233
1234static PyObject *
1235TaskSendMethWrapper_new(TaskObj *task, PyObject *arg)
1236{
1237 TaskSendMethWrapper *o;
1238 o = PyObject_GC_New(TaskSendMethWrapper, &TaskSendMethWrapper_Type);
1239 if (o == NULL) {
1240 return NULL;
1241 }
1242
1243 Py_INCREF(task);
1244 o->sw_task = task;
1245
1246 Py_XINCREF(arg);
1247 o->sw_arg = arg;
1248
1249 PyObject_GC_Track(o);
1250 return (PyObject*) o;
1251}
1252
1253/* ----- Task._wakeup wrapper */
1254
1255static PyObject *
1256TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o,
1257 PyObject *args, PyObject *kwds)
1258{
1259 PyObject *fut;
1260
1261 if (!PyArg_ParseTuple(args, "O|", &fut)) {
1262 return NULL;
1263 }
1264
1265 return task_call_wakeup(o->ww_task, fut);
1266}
1267
1268static int
1269TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o)
1270{
1271 Py_CLEAR(o->ww_task);
1272 return 0;
1273}
1274
1275static int
1276TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o,
1277 visitproc visit, void *arg)
1278{
1279 Py_VISIT(o->ww_task);
1280 return 0;
1281}
1282
1283static void
1284TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o)
1285{
1286 PyObject_GC_UnTrack(o);
1287 (void)TaskWakeupMethWrapper_clear(o);
1288 Py_TYPE(o)->tp_free(o);
1289}
1290
1291PyTypeObject TaskWakeupMethWrapper_Type = {
Victor Stinner1aea8fb2016-10-28 19:13:52 +02001292 PyVarObject_HEAD_INIT(NULL, 0)
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001293 "TaskWakeupMethWrapper",
1294 .tp_basicsize = sizeof(TaskWakeupMethWrapper),
1295 .tp_itemsize = 0,
1296 .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc,
1297 .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call,
1298 .tp_getattro = PyObject_GenericGetAttr,
1299 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1300 .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse,
1301 .tp_clear = (inquiry)TaskWakeupMethWrapper_clear,
1302};
1303
1304static PyObject *
1305TaskWakeupMethWrapper_new(TaskObj *task)
1306{
1307 TaskWakeupMethWrapper *o;
1308 o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type);
1309 if (o == NULL) {
1310 return NULL;
1311 }
1312
1313 Py_INCREF(task);
1314 o->ww_task = task;
1315
1316 PyObject_GC_Track(o);
1317 return (PyObject*) o;
1318}
1319
1320/* ----- Task */
1321
1322/*[clinic input]
1323_asyncio.Task.__init__
1324
1325 coro: 'O'
1326 *
1327 loop: 'O' = NULL
1328
1329A coroutine wrapped in a Future.
1330[clinic start generated code]*/
1331
1332static int
1333_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
1334/*[clinic end generated code: output=9f24774c2287fc2f input=71d8d28c201a18cd]*/
1335{
1336 PyObject *res;
1337 _Py_IDENTIFIER(add);
1338
1339 if (future_init((FutureObj*)self, loop)) {
INADA Naokic411a7d2016-10-18 11:48:14 +09001340 return -1;
1341 }
INADA Naokic411a7d2016-10-18 11:48:14 +09001342
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001343 self->task_fut_waiter = NULL;
1344 self->task_must_cancel = 0;
1345 self->task_log_destroy_pending = 1;
INADA Naokic411a7d2016-10-18 11:48:14 +09001346
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001347 Py_INCREF(coro);
1348 self->task_coro = coro;
1349
1350 if (task_call_step_soon(self, NULL)) {
1351 return -1;
INADA Naokic411a7d2016-10-18 11:48:14 +09001352 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001353
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01001354 res = _PyObject_CallMethodIdObjArgs(all_tasks, &PyId_add, self, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001355 if (res == NULL) {
1356 return -1;
1357 }
1358 Py_DECREF(res);
1359
1360 return 0;
1361}
1362
1363static int
1364TaskObj_clear(TaskObj *task)
1365{
1366 (void)FutureObj_clear((FutureObj*) task);
1367 Py_CLEAR(task->task_coro);
1368 Py_CLEAR(task->task_fut_waiter);
1369 return 0;
1370}
1371
1372static int
1373TaskObj_traverse(TaskObj *task, visitproc visit, void *arg)
1374{
1375 Py_VISIT(task->task_coro);
1376 Py_VISIT(task->task_fut_waiter);
1377 (void)FutureObj_traverse((FutureObj*) task, visit, arg);
1378 return 0;
1379}
1380
1381static PyObject *
1382TaskObj_get_log_destroy_pending(TaskObj *task)
1383{
1384 if (task->task_log_destroy_pending) {
1385 Py_RETURN_TRUE;
1386 }
1387 else {
1388 Py_RETURN_FALSE;
1389 }
1390}
1391
1392static int
1393TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val)
1394{
1395 int is_true = PyObject_IsTrue(val);
1396 if (is_true < 0) {
1397 return -1;
1398 }
1399 task->task_log_destroy_pending = is_true;
1400 return 0;
1401}
1402
1403static PyObject *
1404TaskObj_get_must_cancel(TaskObj *task)
1405{
1406 if (task->task_must_cancel) {
1407 Py_RETURN_TRUE;
1408 }
1409 else {
1410 Py_RETURN_FALSE;
1411 }
1412}
1413
1414static PyObject *
1415TaskObj_get_coro(TaskObj *task)
1416{
1417 if (task->task_coro) {
1418 Py_INCREF(task->task_coro);
1419 return task->task_coro;
1420 }
1421
1422 Py_RETURN_NONE;
1423}
1424
1425static PyObject *
1426TaskObj_get_fut_waiter(TaskObj *task)
1427{
1428 if (task->task_fut_waiter) {
1429 Py_INCREF(task->task_fut_waiter);
1430 return task->task_fut_waiter;
1431 }
1432
1433 Py_RETURN_NONE;
1434}
1435
1436/*[clinic input]
1437@classmethod
1438_asyncio.Task.current_task
1439
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001440 loop: 'O' = None
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001441
1442Return the currently running task in an event loop or None.
1443
1444By default the current task for the current event loop is returned.
1445
1446None is returned when called not in the context of a Task.
1447[clinic start generated code]*/
1448
1449static PyObject *
1450_asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop)
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001451/*[clinic end generated code: output=99fbe7332c516e03 input=a0d6cdf2e3b243e1]*/
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001452{
1453 PyObject *res;
1454
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001455 if (loop == Py_None) {
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001456 loop = _PyObject_CallNoArg(asyncio_get_event_loop);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001457 if (loop == NULL) {
1458 return NULL;
1459 }
1460
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001461 res = PyDict_GetItem(current_tasks, loop);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001462 Py_DECREF(loop);
1463 }
1464 else {
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001465 res = PyDict_GetItem(current_tasks, loop);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001466 }
1467
1468 if (res == NULL) {
1469 Py_RETURN_NONE;
1470 }
1471 else {
1472 Py_INCREF(res);
1473 return res;
1474 }
1475}
1476
1477static PyObject *
1478task_all_tasks(PyObject *loop)
1479{
1480 PyObject *task;
1481 PyObject *task_loop;
1482 PyObject *set;
1483 PyObject *iter;
1484
1485 assert(loop != NULL);
1486
1487 set = PySet_New(NULL);
1488 if (set == NULL) {
1489 return NULL;
1490 }
1491
1492 iter = PyObject_GetIter(all_tasks);
1493 if (iter == NULL) {
INADA Naokic411a7d2016-10-18 11:48:14 +09001494 goto fail;
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001495 }
1496
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001497 while ((task = PyIter_Next(iter))) {
1498 task_loop = PyObject_GetAttrString(task, "_loop");
1499 if (task_loop == NULL) {
1500 Py_DECREF(task);
1501 goto fail;
1502 }
1503 if (task_loop == loop) {
1504 if (PySet_Add(set, task) == -1) {
1505 Py_DECREF(task_loop);
1506 Py_DECREF(task);
1507 goto fail;
1508 }
1509 }
1510 Py_DECREF(task_loop);
1511 Py_DECREF(task);
1512 }
1513
1514 Py_DECREF(iter);
1515 return set;
1516
1517fail:
1518 Py_XDECREF(set);
1519 Py_XDECREF(iter);
1520 return NULL;
1521}
1522
1523/*[clinic input]
1524@classmethod
1525_asyncio.Task.all_tasks
1526
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001527 loop: 'O' = None
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001528
1529Return a set of all tasks for an event loop.
1530
1531By default all tasks for the current event loop are returned.
1532[clinic start generated code]*/
1533
1534static PyObject *
1535_asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop)
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001536/*[clinic end generated code: output=11f9b20749ccca5d input=c6f5b53bd487488f]*/
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001537{
1538 PyObject *res;
1539
Yury Selivanov8d26aa92017-03-02 22:16:33 -05001540 if (loop == Py_None) {
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001541 loop = _PyObject_CallNoArg(asyncio_get_event_loop);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001542 if (loop == NULL) {
1543 return NULL;
1544 }
1545
1546 res = task_all_tasks(loop);
1547 Py_DECREF(loop);
1548 }
1549 else {
1550 res = task_all_tasks(loop);
1551 }
1552
1553 return res;
1554}
1555
1556/*[clinic input]
1557_asyncio.Task._repr_info
1558[clinic start generated code]*/
1559
1560static PyObject *
1561_asyncio_Task__repr_info_impl(TaskObj *self)
1562/*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/
1563{
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001564 return PyObject_CallFunctionObjArgs(
1565 asyncio_task_repr_info_func, self, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001566}
1567
1568/*[clinic input]
1569_asyncio.Task.cancel
1570
1571Request that this task cancel itself.
1572
1573This arranges for a CancelledError to be thrown into the
1574wrapped coroutine on the next cycle through the event loop.
1575The coroutine then has a chance to clean up or even deny
1576the request using try/except/finally.
1577
1578Unlike Future.cancel, this does not guarantee that the
1579task will be cancelled: the exception might be caught and
1580acted upon, delaying cancellation of the task or preventing
1581cancellation completely. The task may also return a value or
1582raise a different exception.
1583
1584Immediately after this method is called, Task.cancelled() will
1585not return True (unless the task was already cancelled). A
1586task will be marked as cancelled when the wrapped coroutine
1587terminates with a CancelledError exception (even if cancel()
1588was not called).
1589[clinic start generated code]*/
1590
1591static PyObject *
1592_asyncio_Task_cancel_impl(TaskObj *self)
1593/*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/
1594{
Yury Selivanov7ce1c6f2017-06-11 13:49:18 +00001595 self->task_log_tb = 0;
1596
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001597 if (self->task_state != STATE_PENDING) {
1598 Py_RETURN_FALSE;
1599 }
1600
1601 if (self->task_fut_waiter) {
1602 PyObject *res;
1603 int is_true;
1604
1605 res = _PyObject_CallMethodId(
1606 self->task_fut_waiter, &PyId_cancel, NULL);
1607 if (res == NULL) {
1608 return NULL;
1609 }
1610
1611 is_true = PyObject_IsTrue(res);
1612 Py_DECREF(res);
1613 if (is_true < 0) {
1614 return NULL;
1615 }
1616
1617 if (is_true) {
1618 Py_RETURN_TRUE;
1619 }
1620 }
1621
1622 self->task_must_cancel = 1;
1623 Py_RETURN_TRUE;
1624}
1625
1626/*[clinic input]
1627_asyncio.Task.get_stack
1628
1629 *
1630 limit: 'O' = None
1631
1632Return the list of stack frames for this task's coroutine.
1633
1634If the coroutine is not done, this returns the stack where it is
1635suspended. If the coroutine has completed successfully or was
1636cancelled, this returns an empty list. If the coroutine was
1637terminated by an exception, this returns the list of traceback
1638frames.
1639
1640The frames are always ordered from oldest to newest.
1641
1642The optional limit gives the maximum number of frames to
1643return; by default all available frames are returned. Its
1644meaning differs depending on whether a stack or a traceback is
1645returned: the newest frames of a stack are returned, but the
1646oldest frames of a traceback are returned. (This matches the
1647behavior of the traceback module.)
1648
1649For reasons beyond our control, only one stack frame is
1650returned for a suspended coroutine.
1651[clinic start generated code]*/
1652
1653static PyObject *
1654_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
1655/*[clinic end generated code: output=c9aeeeebd1e18118 input=b1920230a766d17a]*/
1656{
1657 return PyObject_CallFunctionObjArgs(
1658 asyncio_task_get_stack_func, self, limit, NULL);
1659}
1660
1661/*[clinic input]
1662_asyncio.Task.print_stack
1663
1664 *
1665 limit: 'O' = None
1666 file: 'O' = None
1667
1668Print the stack or traceback for this task's coroutine.
1669
1670This produces output similar to that of the traceback module,
1671for the frames retrieved by get_stack(). The limit argument
1672is passed to get_stack(). The file argument is an I/O stream
1673to which the output is written; by default output is written
1674to sys.stderr.
1675[clinic start generated code]*/
1676
1677static PyObject *
1678_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
1679 PyObject *file)
1680/*[clinic end generated code: output=7339e10314cd3f4d input=19f1e99ab5400bc3]*/
1681{
1682 return PyObject_CallFunctionObjArgs(
1683 asyncio_task_print_stack_func, self, limit, file, NULL);
1684}
1685
1686/*[clinic input]
1687_asyncio.Task._step
1688
1689 exc: 'O' = NULL
1690[clinic start generated code]*/
1691
1692static PyObject *
1693_asyncio_Task__step_impl(TaskObj *self, PyObject *exc)
1694/*[clinic end generated code: output=7ed23f0cefd5ae42 input=ada4b2324e5370af]*/
1695{
1696 return task_step(self, exc == Py_None ? NULL : exc);
1697}
1698
1699/*[clinic input]
1700_asyncio.Task._wakeup
1701
1702 fut: 'O'
1703[clinic start generated code]*/
1704
1705static PyObject *
1706_asyncio_Task__wakeup_impl(TaskObj *self, PyObject *fut)
1707/*[clinic end generated code: output=75cb341c760fd071 input=11ee4918a5bdbf21]*/
1708{
1709 return task_wakeup(self, fut);
1710}
1711
1712static void
1713TaskObj_finalize(TaskObj *task)
1714{
1715 _Py_IDENTIFIER(call_exception_handler);
1716 _Py_IDENTIFIER(task);
1717 _Py_IDENTIFIER(message);
1718 _Py_IDENTIFIER(source_traceback);
1719
1720 PyObject *message = NULL;
1721 PyObject *context = NULL;
1722 PyObject *func = NULL;
1723 PyObject *res = NULL;
1724
1725 PyObject *error_type, *error_value, *error_traceback;
1726
1727 if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
1728 goto done;
1729 }
1730
1731 /* Save the current exception, if any. */
1732 PyErr_Fetch(&error_type, &error_value, &error_traceback);
1733
1734 context = PyDict_New();
1735 if (context == NULL) {
1736 goto finally;
1737 }
1738
1739 message = PyUnicode_FromString("Task was destroyed but it is pending!");
1740 if (message == NULL) {
1741 goto finally;
1742 }
1743
1744 if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
1745 _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0)
1746 {
1747 goto finally;
1748 }
1749
1750 if (task->task_source_tb != NULL) {
1751 if (_PyDict_SetItemId(context, &PyId_source_traceback,
1752 task->task_source_tb) < 0)
1753 {
1754 goto finally;
1755 }
1756 }
1757
1758 func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler);
1759 if (func != NULL) {
Victor Stinner7bfb42d2016-12-05 17:04:32 +01001760 res = PyObject_CallFunctionObjArgs(func, context, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001761 if (res == NULL) {
1762 PyErr_WriteUnraisable(func);
1763 }
1764 }
1765
1766finally:
1767 Py_CLEAR(context);
1768 Py_CLEAR(message);
1769 Py_CLEAR(func);
1770 Py_CLEAR(res);
1771
1772 /* Restore the saved exception. */
1773 PyErr_Restore(error_type, error_value, error_traceback);
1774
1775done:
1776 FutureObj_finalize((FutureObj*)task);
1777}
1778
1779static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */
1780
1781static PyMethodDef TaskType_methods[] = {
1782 _ASYNCIO_FUTURE_RESULT_METHODDEF
1783 _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
1784 _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
1785 _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
1786 _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
1787 _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
1788 _ASYNCIO_FUTURE_CANCELLED_METHODDEF
1789 _ASYNCIO_FUTURE_DONE_METHODDEF
1790 _ASYNCIO_TASK_CURRENT_TASK_METHODDEF
1791 _ASYNCIO_TASK_ALL_TASKS_METHODDEF
1792 _ASYNCIO_TASK_CANCEL_METHODDEF
1793 _ASYNCIO_TASK_GET_STACK_METHODDEF
1794 _ASYNCIO_TASK_PRINT_STACK_METHODDEF
1795 _ASYNCIO_TASK__WAKEUP_METHODDEF
1796 _ASYNCIO_TASK__STEP_METHODDEF
1797 _ASYNCIO_TASK__REPR_INFO_METHODDEF
1798 {NULL, NULL} /* Sentinel */
1799};
1800
1801static PyGetSetDef TaskType_getsetlist[] = {
1802 FUTURE_COMMON_GETSETLIST
1803 {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending,
1804 (setter)TaskObj_set_log_destroy_pending, NULL},
1805 {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL},
1806 {"_coro", (getter)TaskObj_get_coro, NULL, NULL},
1807 {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL},
1808 {NULL} /* Sentinel */
1809};
1810
1811static PyTypeObject TaskType = {
Victor Stinner1aea8fb2016-10-28 19:13:52 +02001812 PyVarObject_HEAD_INIT(NULL, 0)
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001813 "_asyncio.Task",
1814 sizeof(TaskObj), /* tp_basicsize */
1815 .tp_base = &FutureType,
1816 .tp_dealloc = TaskObj_dealloc,
1817 .tp_as_async = &FutureType_as_async,
1818 .tp_repr = (reprfunc)FutureObj_repr,
1819 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE
1820 | Py_TPFLAGS_HAVE_FINALIZE,
1821 .tp_doc = _asyncio_Task___init____doc__,
1822 .tp_traverse = (traverseproc)TaskObj_traverse,
1823 .tp_clear = (inquiry)TaskObj_clear,
1824 .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist),
1825 .tp_iter = (getiterfunc)future_new_iter,
1826 .tp_methods = TaskType_methods,
1827 .tp_getset = TaskType_getsetlist,
1828 .tp_dictoffset = offsetof(TaskObj, dict),
1829 .tp_init = (initproc)_asyncio_Task___init__,
1830 .tp_new = PyType_GenericNew,
1831 .tp_finalize = (destructor)TaskObj_finalize,
1832};
1833
1834#define Task_CheckExact(obj) (Py_TYPE(obj) == &TaskType)
1835
1836static void
1837TaskObj_dealloc(PyObject *self)
1838{
1839 TaskObj *task = (TaskObj *)self;
1840
1841 if (Task_CheckExact(self)) {
1842 /* When fut is subclass of Task, finalizer is called from
1843 * subtype_dealloc.
1844 */
1845 if (PyObject_CallFinalizerFromDealloc(self) < 0) {
1846 // resurrected.
1847 return;
1848 }
1849 }
1850
Alexander Mohrde34cbe2017-08-01 23:31:07 -07001851 PyObject_GC_UnTrack(self);
1852
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001853 if (task->task_weakreflist != NULL) {
1854 PyObject_ClearWeakRefs(self);
1855 }
1856
1857 (void)TaskObj_clear(task);
1858 Py_TYPE(task)->tp_free(task);
1859}
1860
1861static inline PyObject *
1862task_call_wakeup(TaskObj *task, PyObject *fut)
1863{
1864 if (Task_CheckExact(task)) {
1865 return task_wakeup(task, fut);
1866 }
1867 else {
1868 /* `task` is a subclass of Task */
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01001869 return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__wakeup,
1870 fut, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001871 }
1872}
1873
1874static inline PyObject *
1875task_call_step(TaskObj *task, PyObject *arg)
1876{
1877 if (Task_CheckExact(task)) {
1878 return task_step(task, arg);
1879 }
1880 else {
1881 /* `task` is a subclass of Task */
1882 if (arg == NULL) {
1883 arg = Py_None;
1884 }
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01001885 return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step,
1886 arg, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001887 }
1888}
1889
1890static int
1891task_call_step_soon(TaskObj *task, PyObject *arg)
1892{
1893 PyObject *handle;
1894
1895 PyObject *cb = TaskSendMethWrapper_new(task, arg);
1896 if (cb == NULL) {
1897 return -1;
1898 }
1899
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01001900 handle = _PyObject_CallMethodIdObjArgs(task->task_loop, &PyId_call_soon,
1901 cb, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001902 Py_DECREF(cb);
1903 if (handle == NULL) {
1904 return -1;
1905 }
1906
1907 Py_DECREF(handle);
1908 return 0;
1909}
1910
1911static PyObject *
1912task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...)
1913{
1914 PyObject* msg;
1915
1916 va_list vargs;
1917#ifdef HAVE_STDARG_PROTOTYPES
1918 va_start(vargs, format);
1919#else
1920 va_start(vargs);
1921#endif
1922 msg = PyUnicode_FromFormatV(format, vargs);
1923 va_end(vargs);
1924
1925 if (msg == NULL) {
1926 return NULL;
1927 }
1928
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01001929 PyObject *e = PyObject_CallFunctionObjArgs(et, msg, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001930 Py_DECREF(msg);
1931 if (e == NULL) {
1932 return NULL;
1933 }
1934
1935 if (task_call_step_soon(task, e) == -1) {
1936 Py_DECREF(e);
1937 return NULL;
1938 }
1939
1940 Py_DECREF(e);
1941 Py_RETURN_NONE;
1942}
1943
1944static PyObject *
1945task_step_impl(TaskObj *task, PyObject *exc)
1946{
1947 int res;
1948 int clear_exc = 0;
1949 PyObject *result = NULL;
1950 PyObject *coro = task->task_coro;
1951 PyObject *o;
1952
1953 if (task->task_state != STATE_PENDING) {
1954 PyErr_Format(PyExc_AssertionError,
1955 "_step(): already done: %R %R",
1956 task,
1957 exc ? exc : Py_None);
INADA Naokic411a7d2016-10-18 11:48:14 +09001958 goto fail;
1959 }
INADA Naoki9e4e38e2016-10-09 14:44:47 +09001960
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001961 if (task->task_must_cancel) {
1962 assert(exc != Py_None);
1963
1964 if (exc) {
1965 /* Check if exc is a CancelledError */
1966 res = PyObject_IsInstance(exc, asyncio_CancelledError);
1967 if (res == -1) {
1968 /* An error occurred, abort */
1969 goto fail;
1970 }
1971 if (res == 0) {
1972 /* exc is not CancelledError; reset it to NULL */
1973 exc = NULL;
1974 }
1975 }
1976
1977 if (!exc) {
1978 /* exc was not a CancelledError */
Victor Stinnerf17c3de2016-12-06 18:46:19 +01001979 exc = _PyObject_CallNoArg(asyncio_CancelledError);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001980 if (!exc) {
1981 goto fail;
1982 }
1983 clear_exc = 1;
1984 }
1985
1986 task->task_must_cancel = 0;
1987 }
1988
1989 Py_CLEAR(task->task_fut_waiter);
1990
1991 if (exc == NULL) {
1992 if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) {
1993 result = _PyGen_Send((PyGenObject*)coro, Py_None);
1994 }
1995 else {
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01001996 result = _PyObject_CallMethodIdObjArgs(coro, &PyId_send,
1997 Py_None, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04001998 }
1999 }
2000 else {
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01002001 result = _PyObject_CallMethodIdObjArgs(coro, &PyId_throw,
2002 exc, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002003 if (clear_exc) {
2004 /* We created 'exc' during this call */
2005 Py_CLEAR(exc);
2006 }
2007 }
2008
2009 if (result == NULL) {
2010 PyObject *et, *ev, *tb;
2011
2012 if (_PyGen_FetchStopIterationValue(&o) == 0) {
2013 /* The error is StopIteration and that means that
2014 the underlying coroutine has resolved */
INADA Naoki991adca2017-05-11 21:18:38 +09002015 if (task->task_must_cancel) {
2016 // Task is cancelled right before coro stops.
2017 Py_DECREF(o);
2018 task->task_must_cancel = 0;
2019 et = asyncio_CancelledError;
2020 Py_INCREF(et);
2021 ev = NULL;
2022 tb = NULL;
2023 goto set_exception;
2024 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002025 PyObject *res = future_set_result((FutureObj*)task, o);
2026 Py_DECREF(o);
2027 if (res == NULL) {
2028 return NULL;
2029 }
2030 Py_DECREF(res);
2031 Py_RETURN_NONE;
2032 }
2033
2034 if (PyErr_ExceptionMatches(asyncio_CancelledError)) {
2035 /* CancelledError */
2036 PyErr_Clear();
2037 return future_cancel((FutureObj*)task);
2038 }
2039
2040 /* Some other exception; pop it and call Task.set_exception() */
2041 PyErr_Fetch(&et, &ev, &tb);
INADA Naoki991adca2017-05-11 21:18:38 +09002042
2043set_exception:
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002044 assert(et);
2045 if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
2046 PyErr_NormalizeException(&et, &ev, &tb);
2047 }
Yury Selivanovedfe8862016-12-01 11:37:47 -05002048 if (tb != NULL) {
2049 PyException_SetTraceback(ev, tb);
2050 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002051 o = future_set_exception((FutureObj*)task, ev);
2052 if (!o) {
2053 /* An exception in Task.set_exception() */
2054 Py_XDECREF(et);
2055 Py_XDECREF(tb);
2056 Py_XDECREF(ev);
2057 goto fail;
2058 }
2059 assert(o == Py_None);
2060 Py_CLEAR(o);
2061
2062 if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) {
2063 /* We've got a BaseException; re-raise it */
2064 PyErr_Restore(et, ev, tb);
2065 goto fail;
2066 }
2067
2068 Py_XDECREF(et);
2069 Py_XDECREF(tb);
2070 Py_XDECREF(ev);
2071
2072 Py_RETURN_NONE;
2073 }
2074
2075 if (result == (PyObject*)task) {
2076 /* We have a task that wants to await on itself */
2077 goto self_await;
2078 }
2079
2080 /* Check if `result` is FutureObj or TaskObj (and not a subclass) */
2081 if (Future_CheckExact(result) || Task_CheckExact(result)) {
2082 PyObject *wrapper;
2083 PyObject *res;
2084 FutureObj *fut = (FutureObj*)result;
2085
2086 /* Check if `result` future is attached to a different loop */
2087 if (fut->fut_loop != task->task_loop) {
2088 goto different_loop;
2089 }
2090
2091 if (fut->fut_blocking) {
2092 fut->fut_blocking = 0;
2093
2094 /* result.add_done_callback(task._wakeup) */
2095 wrapper = TaskWakeupMethWrapper_new(task);
2096 if (wrapper == NULL) {
2097 goto fail;
2098 }
2099 res = future_add_done_callback((FutureObj*)result, wrapper);
2100 Py_DECREF(wrapper);
2101 if (res == NULL) {
2102 goto fail;
2103 }
2104 Py_DECREF(res);
2105
2106 /* task._fut_waiter = result */
2107 task->task_fut_waiter = result; /* no incref is necessary */
2108
2109 if (task->task_must_cancel) {
2110 PyObject *r;
2111 r = future_cancel(fut);
2112 if (r == NULL) {
2113 return NULL;
2114 }
2115 if (r == Py_True) {
2116 task->task_must_cancel = 0;
2117 }
2118 Py_DECREF(r);
2119 }
2120
2121 Py_RETURN_NONE;
2122 }
2123 else {
2124 goto yield_insteadof_yf;
2125 }
2126 }
2127
2128 /* Check if `result` is a Future-compatible object */
2129 o = PyObject_GetAttrString(result, "_asyncio_future_blocking");
2130 if (o == NULL) {
2131 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2132 PyErr_Clear();
2133 }
2134 else {
2135 goto fail;
2136 }
2137 }
2138 else {
2139 if (o == Py_None) {
2140 Py_CLEAR(o);
2141 }
2142 else {
2143 /* `result` is a Future-compatible object */
2144 PyObject *wrapper;
2145 PyObject *res;
2146
2147 int blocking = PyObject_IsTrue(o);
2148 Py_CLEAR(o);
2149 if (blocking < 0) {
2150 goto fail;
2151 }
2152
2153 /* Check if `result` future is attached to a different loop */
2154 PyObject *oloop = PyObject_GetAttrString(result, "_loop");
2155 if (oloop == NULL) {
2156 goto fail;
2157 }
2158 if (oloop != task->task_loop) {
2159 Py_DECREF(oloop);
2160 goto different_loop;
2161 }
2162 else {
2163 Py_DECREF(oloop);
2164 }
2165
2166 if (blocking) {
2167 /* result._asyncio_future_blocking = False */
2168 if (PyObject_SetAttrString(
2169 result, "_asyncio_future_blocking", Py_False) == -1) {
2170 goto fail;
2171 }
2172
2173 /* result.add_done_callback(task._wakeup) */
2174 wrapper = TaskWakeupMethWrapper_new(task);
2175 if (wrapper == NULL) {
2176 goto fail;
2177 }
Victor Stinnerb6ed57d2016-12-09 14:24:02 +01002178 res = _PyObject_CallMethodIdObjArgs(result,
2179 &PyId_add_done_callback,
2180 wrapper, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002181 Py_DECREF(wrapper);
2182 if (res == NULL) {
2183 goto fail;
2184 }
2185 Py_DECREF(res);
2186
2187 /* task._fut_waiter = result */
2188 task->task_fut_waiter = result; /* no incref is necessary */
2189
2190 if (task->task_must_cancel) {
2191 PyObject *r;
2192 int is_true;
2193 r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
2194 if (r == NULL) {
2195 return NULL;
2196 }
2197 is_true = PyObject_IsTrue(r);
2198 Py_DECREF(r);
2199 if (is_true < 0) {
2200 return NULL;
2201 }
2202 else if (is_true) {
2203 task->task_must_cancel = 0;
2204 }
2205 }
2206
2207 Py_RETURN_NONE;
2208 }
2209 else {
2210 goto yield_insteadof_yf;
2211 }
2212 }
2213 }
2214
2215 /* Check if `result` is None */
2216 if (result == Py_None) {
2217 /* Bare yield relinquishes control for one event loop iteration. */
2218 if (task_call_step_soon(task, NULL)) {
2219 goto fail;
2220 }
2221 return result;
2222 }
2223
2224 /* Check if `result` is a generator */
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002225 o = PyObject_CallFunctionObjArgs(inspect_isgenerator, result, NULL);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002226 if (o == NULL) {
2227 /* An exception in inspect.isgenerator */
2228 goto fail;
2229 }
2230 res = PyObject_IsTrue(o);
2231 Py_CLEAR(o);
2232 if (res == -1) {
2233 /* An exception while checking if 'val' is True */
2234 goto fail;
2235 }
2236 if (res == 1) {
2237 /* `result` is a generator */
2238 PyObject *ret;
2239 ret = task_set_error_soon(
2240 task, PyExc_RuntimeError,
2241 "yield was used instead of yield from for "
2242 "generator in task %R with %S", task, result);
2243 Py_DECREF(result);
2244 return ret;
2245 }
2246
2247 /* The `result` is none of the above */
2248 Py_DECREF(result);
2249 return task_set_error_soon(
2250 task, PyExc_RuntimeError, "Task got bad yield: %R", result);
2251
2252self_await:
2253 o = task_set_error_soon(
2254 task, PyExc_RuntimeError,
2255 "Task cannot await on itself: %R", task);
2256 Py_DECREF(result);
2257 return o;
2258
2259yield_insteadof_yf:
2260 o = task_set_error_soon(
2261 task, PyExc_RuntimeError,
2262 "yield was used instead of yield from "
2263 "in task %R with %R",
2264 task, result);
2265 Py_DECREF(result);
2266 return o;
2267
2268different_loop:
2269 o = task_set_error_soon(
2270 task, PyExc_RuntimeError,
2271 "Task %R got Future %R attached to a different loop",
2272 task, result);
2273 Py_DECREF(result);
2274 return o;
2275
2276fail:
2277 Py_XDECREF(result);
2278 return NULL;
2279}
2280
2281static PyObject *
2282task_step(TaskObj *task, PyObject *exc)
2283{
2284 PyObject *res;
2285 PyObject *ot;
2286
Yury Selivanov684ef2c2016-10-28 19:01:21 -04002287 if (PyDict_SetItem(current_tasks,
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002288 task->task_loop, (PyObject*)task) == -1)
2289 {
2290 return NULL;
2291 }
2292
2293 res = task_step_impl(task, exc);
2294
2295 if (res == NULL) {
2296 PyObject *et, *ev, *tb;
2297 PyErr_Fetch(&et, &ev, &tb);
2298 ot = _PyDict_Pop(current_tasks, task->task_loop, NULL);
2299 if (ot == NULL) {
2300 Py_XDECREF(et);
2301 Py_XDECREF(tb);
2302 Py_XDECREF(ev);
2303 return NULL;
2304 }
2305 Py_DECREF(ot);
2306 PyErr_Restore(et, ev, tb);
2307 return NULL;
2308 }
2309 else {
2310 ot = _PyDict_Pop(current_tasks, task->task_loop, NULL);
2311 if (ot == NULL) {
2312 Py_DECREF(res);
2313 return NULL;
2314 }
2315 else {
2316 Py_DECREF(ot);
2317 return res;
2318 }
2319 }
2320}
2321
2322static PyObject *
2323task_wakeup(TaskObj *task, PyObject *o)
2324{
2325 assert(o);
2326
2327 if (Future_CheckExact(o) || Task_CheckExact(o)) {
2328 PyObject *fut_result = NULL;
2329 int res = future_get_result((FutureObj*)o, &fut_result);
2330 PyObject *result;
2331
2332 switch(res) {
2333 case -1:
2334 assert(fut_result == NULL);
2335 return NULL;
2336 case 0:
2337 Py_DECREF(fut_result);
2338 return task_call_step(task, NULL);
2339 default:
2340 assert(res == 1);
2341 result = task_call_step(task, fut_result);
2342 Py_DECREF(fut_result);
2343 return result;
2344 }
2345 }
2346
2347 PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
2348 if (fut_result == NULL) {
2349 PyObject *et, *ev, *tb;
2350 PyObject *res;
2351
2352 PyErr_Fetch(&et, &ev, &tb);
2353 if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
2354 PyErr_NormalizeException(&et, &ev, &tb);
2355 }
2356
2357 res = task_call_step(task, ev);
2358
2359 Py_XDECREF(et);
2360 Py_XDECREF(tb);
2361 Py_XDECREF(ev);
2362
2363 return res;
2364 }
2365 else {
2366 Py_DECREF(fut_result);
2367 return task_call_step(task, NULL);
2368 }
2369}
2370
2371
2372/*********************** Module **************************/
2373
2374
2375static void
2376module_free(void *m)
2377{
2378 Py_CLEAR(current_tasks);
2379 Py_CLEAR(all_tasks);
2380 Py_CLEAR(traceback_extract_stack);
2381 Py_CLEAR(asyncio_get_event_loop);
2382 Py_CLEAR(asyncio_future_repr_info_func);
2383 Py_CLEAR(asyncio_task_repr_info_func);
2384 Py_CLEAR(asyncio_task_get_stack_func);
2385 Py_CLEAR(asyncio_task_print_stack_func);
2386 Py_CLEAR(asyncio_InvalidStateError);
2387 Py_CLEAR(asyncio_CancelledError);
2388 Py_CLEAR(inspect_isgenerator);
2389}
2390
2391static int
2392module_init(void)
2393{
2394 PyObject *module = NULL;
2395 PyObject *cls;
2396
2397#define WITH_MOD(NAME) \
2398 Py_CLEAR(module); \
2399 module = PyImport_ImportModule(NAME); \
2400 if (module == NULL) { \
2401 return -1; \
2402 }
2403
2404#define GET_MOD_ATTR(VAR, NAME) \
2405 VAR = PyObject_GetAttrString(module, NAME); \
2406 if (VAR == NULL) { \
2407 goto fail; \
2408 }
2409
2410 WITH_MOD("asyncio.events")
2411 GET_MOD_ATTR(asyncio_get_event_loop, "get_event_loop")
2412
2413 WITH_MOD("asyncio.base_futures")
2414 GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info")
2415 GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError")
2416 GET_MOD_ATTR(asyncio_CancelledError, "CancelledError")
2417
2418 WITH_MOD("asyncio.base_tasks")
2419 GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info")
2420 GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack")
2421 GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack")
2422
2423 WITH_MOD("inspect")
2424 GET_MOD_ATTR(inspect_isgenerator, "isgenerator")
2425
2426 WITH_MOD("traceback")
2427 GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
2428
2429 WITH_MOD("weakref")
2430 GET_MOD_ATTR(cls, "WeakSet")
Victor Stinnera5ed5f02016-12-06 18:45:50 +01002431 all_tasks = _PyObject_CallNoArg(cls);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002432 Py_CLEAR(cls);
2433 if (all_tasks == NULL) {
INADA Naokic411a7d2016-10-18 11:48:14 +09002434 goto fail;
2435 }
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002436
Yury Selivanov684ef2c2016-10-28 19:01:21 -04002437 current_tasks = PyDict_New();
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002438 if (current_tasks == NULL) {
2439 goto fail;
2440 }
2441
2442 Py_CLEAR(module);
INADA Naokic411a7d2016-10-18 11:48:14 +09002443 return 0;
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002444
INADA Naokic411a7d2016-10-18 11:48:14 +09002445fail:
INADA Naokic411a7d2016-10-18 11:48:14 +09002446 Py_CLEAR(module);
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002447 module_free(NULL);
INADA Naokic411a7d2016-10-18 11:48:14 +09002448 return -1;
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002449
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002450#undef WITH_MOD
2451#undef GET_MOD_ATTR
2452}
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002453
INADA Naokic411a7d2016-10-18 11:48:14 +09002454PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002455
INADA Naoki9f2ce252016-10-15 15:39:19 +09002456static struct PyModuleDef _asynciomodule = {
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002457 PyModuleDef_HEAD_INIT, /* m_base */
INADA Naoki9f2ce252016-10-15 15:39:19 +09002458 "_asyncio", /* m_name */
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002459 module_doc, /* m_doc */
2460 -1, /* m_size */
INADA Naokic411a7d2016-10-18 11:48:14 +09002461 NULL, /* m_methods */
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002462 NULL, /* m_slots */
2463 NULL, /* m_traverse */
2464 NULL, /* m_clear */
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002465 (freefunc)module_free /* m_free */
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002466};
2467
2468
2469PyMODINIT_FUNC
INADA Naoki9f2ce252016-10-15 15:39:19 +09002470PyInit__asyncio(void)
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002471{
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002472 if (module_init() < 0) {
INADA Naokic411a7d2016-10-18 11:48:14 +09002473 return NULL;
2474 }
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002475 if (PyType_Ready(&FutureType) < 0) {
2476 return NULL;
2477 }
2478 if (PyType_Ready(&FutureIterType) < 0) {
2479 return NULL;
2480 }
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002481 if (PyType_Ready(&TaskSendMethWrapper_Type) < 0) {
2482 return NULL;
2483 }
2484 if(PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) {
2485 return NULL;
2486 }
2487 if (PyType_Ready(&TaskType) < 0) {
2488 return NULL;
2489 }
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002490
INADA Naoki9f2ce252016-10-15 15:39:19 +09002491 PyObject *m = PyModule_Create(&_asynciomodule);
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002492 if (m == NULL) {
2493 return NULL;
2494 }
2495
2496 Py_INCREF(&FutureType);
2497 if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) {
2498 Py_DECREF(&FutureType);
2499 return NULL;
2500 }
2501
Yury Selivanova0c1ba62016-10-28 12:52:37 -04002502 Py_INCREF(&TaskType);
2503 if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) {
2504 Py_DECREF(&TaskType);
2505 return NULL;
2506 }
2507
INADA Naoki9e4e38e2016-10-09 14:44:47 +09002508 return m;
2509}