• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "Python.h"
2 #include "pycore_pyerrors.h"      // _PyErr_ClearExcState()
3 #include <stddef.h>               // offsetof()
4 
5 
6 /*[clinic input]
7 module _asyncio
8 [clinic start generated code]*/
9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/
10 
11 
12 /* identifiers used from some functions */
13 _Py_IDENTIFIER(__asyncio_running_event_loop__);
14 _Py_IDENTIFIER(_asyncio_future_blocking);
15 _Py_IDENTIFIER(add_done_callback);
16 _Py_IDENTIFIER(call_soon);
17 _Py_IDENTIFIER(cancel);
18 _Py_IDENTIFIER(get_event_loop);
19 _Py_IDENTIFIER(throw);
20 
21 
22 /* State of the _asyncio module */
23 static PyObject *asyncio_mod;
24 static PyObject *traceback_extract_stack;
25 static PyObject *asyncio_get_event_loop_policy;
26 static PyObject *asyncio_future_repr_info_func;
27 static PyObject *asyncio_iscoroutine_func;
28 static PyObject *asyncio_task_get_stack_func;
29 static PyObject *asyncio_task_print_stack_func;
30 static PyObject *asyncio_task_repr_info_func;
31 static PyObject *asyncio_InvalidStateError;
32 static PyObject *asyncio_CancelledError;
33 static PyObject *context_kwname;
34 static int module_initialized;
35 
36 static PyObject *cached_running_holder;
37 static volatile uint64_t cached_running_holder_tsid;
38 
39 /* Counter for autogenerated Task names */
40 static uint64_t task_name_counter = 0;
41 
42 /* WeakSet containing all alive tasks. */
43 static PyObject *all_tasks;
44 
45 /* Dictionary containing tasks that are currently active in
46    all running event loops.  {EventLoop: Task} */
47 static PyObject *current_tasks;
48 
49 /* An isinstance type cache for the 'is_coroutine()' function. */
50 static PyObject *iscoroutine_typecache;
51 
52 
53 typedef enum {
54     STATE_PENDING,
55     STATE_CANCELLED,
56     STATE_FINISHED
57 } fut_state;
58 
59 #define FutureObj_HEAD(prefix)                                              \
60     PyObject_HEAD                                                           \
61     PyObject *prefix##_loop;                                                \
62     PyObject *prefix##_callback0;                                           \
63     PyObject *prefix##_context0;                                            \
64     PyObject *prefix##_callbacks;                                           \
65     PyObject *prefix##_exception;                                           \
66     PyObject *prefix##_result;                                              \
67     PyObject *prefix##_source_tb;                                           \
68     PyObject *prefix##_cancel_msg;                                          \
69     fut_state prefix##_state;                                               \
70     int prefix##_log_tb;                                                    \
71     int prefix##_blocking;                                                  \
72     PyObject *dict;                                                         \
73     PyObject *prefix##_weakreflist;                                         \
74     _PyErr_StackItem prefix##_cancelled_exc_state;
75 
76 typedef struct {
77     FutureObj_HEAD(fut)
78 } FutureObj;
79 
80 typedef struct {
81     FutureObj_HEAD(task)
82     PyObject *task_fut_waiter;
83     PyObject *task_coro;
84     PyObject *task_name;
85     PyObject *task_context;
86     int task_must_cancel;
87     int task_log_destroy_pending;
88 } TaskObj;
89 
90 typedef struct {
91     PyObject_HEAD
92     TaskObj *sw_task;
93     PyObject *sw_arg;
94 } TaskStepMethWrapper;
95 
96 typedef struct {
97     PyObject_HEAD
98     PyObject *rl_loop;
99 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
100     pid_t rl_pid;
101 #endif
102 } PyRunningLoopHolder;
103 
104 
105 static PyTypeObject FutureType;
106 static PyTypeObject TaskType;
107 static PyTypeObject PyRunningLoopHolder_Type;
108 
109 
110 #define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType)
111 #define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType)
112 
113 #define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType)
114 #define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType)
115 
116 #include "clinic/_asynciomodule.c.h"
117 
118 
119 /*[clinic input]
120 class _asyncio.Future "FutureObj *" "&Future_Type"
121 [clinic start generated code]*/
122 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/
123 
124 
125 /* Get FutureIter from Future */
126 static PyObject * future_new_iter(PyObject *);
127 
128 static PyRunningLoopHolder * new_running_loop_holder(PyObject *);
129 
130 
131 static int
_is_coroutine(PyObject * coro)132 _is_coroutine(PyObject *coro)
133 {
134     /* 'coro' is not a native coroutine, call asyncio.iscoroutine()
135        to check if it's another coroutine flavour.
136 
137        Do this check after 'future_init()'; in case we need to raise
138        an error, __del__ needs a properly initialized object.
139     */
140     PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro);
141     if (res == NULL) {
142         return -1;
143     }
144 
145     int is_res_true = PyObject_IsTrue(res);
146     Py_DECREF(res);
147     if (is_res_true <= 0) {
148         return is_res_true;
149     }
150 
151     if (PySet_GET_SIZE(iscoroutine_typecache) < 100) {
152         /* Just in case we don't want to cache more than 100
153            positive types.  That shouldn't ever happen, unless
154            someone stressing the system on purpose.
155         */
156         if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) {
157             return -1;
158         }
159     }
160 
161     return 1;
162 }
163 
164 
165 static inline int
is_coroutine(PyObject * coro)166 is_coroutine(PyObject *coro)
167 {
168     if (PyCoro_CheckExact(coro)) {
169         return 1;
170     }
171 
172     /* Check if `type(coro)` is in the cache.
173        Caching makes is_coroutine() function almost as fast as
174        PyCoro_CheckExact() for non-native coroutine-like objects
175        (like coroutines compiled with Cython).
176 
177        asyncio.iscoroutine() has its own type caching mechanism.
178        This cache allows us to avoid the cost of even calling
179        a pure-Python function in 99.9% cases.
180     */
181     int has_it = PySet_Contains(
182         iscoroutine_typecache, (PyObject*) Py_TYPE(coro));
183     if (has_it == 0) {
184         /* type(coro) is not in iscoroutine_typecache */
185         return _is_coroutine(coro);
186     }
187 
188     /* either an error has occurred or
189        type(coro) is in iscoroutine_typecache
190     */
191     return has_it;
192 }
193 
194 
195 static PyObject *
get_future_loop(PyObject * fut)196 get_future_loop(PyObject *fut)
197 {
198     /* Implementation of `asyncio.futures._get_loop` */
199 
200     _Py_IDENTIFIER(get_loop);
201     _Py_IDENTIFIER(_loop);
202     PyObject *getloop;
203 
204     if (Future_CheckExact(fut) || Task_CheckExact(fut)) {
205         PyObject *loop = ((FutureObj *)fut)->fut_loop;
206         Py_INCREF(loop);
207         return loop;
208     }
209 
210     if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) {
211         return NULL;
212     }
213     if (getloop != NULL) {
214         PyObject *res = PyObject_CallNoArgs(getloop);
215         Py_DECREF(getloop);
216         return res;
217     }
218 
219     return _PyObject_GetAttrId(fut, &PyId__loop);
220 }
221 
222 
223 static int
get_running_loop(PyObject ** loop)224 get_running_loop(PyObject **loop)
225 {
226     PyObject *rl;
227 
228     PyThreadState *ts = PyThreadState_Get();
229     uint64_t ts_id = PyThreadState_GetID(ts);
230     if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) {
231         // Fast path, check the cache.
232         rl = cached_running_holder;  // borrowed
233     }
234     else {
235         PyObject *ts_dict = _PyThreadState_GetDict(ts);  // borrowed
236         if (ts_dict == NULL) {
237             goto not_found;
238         }
239 
240         rl = _PyDict_GetItemIdWithError(
241             ts_dict, &PyId___asyncio_running_event_loop__);  // borrowed
242         if (rl == NULL) {
243             if (PyErr_Occurred()) {
244                 goto error;
245             }
246             else {
247                 goto not_found;
248             }
249         }
250 
251         cached_running_holder = rl;  // borrowed
252         cached_running_holder_tsid = ts_id;
253     }
254 
255     assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type));
256     PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop;
257 
258     if (running_loop == Py_None) {
259         goto not_found;
260     }
261 
262 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
263     /* On Windows there is no getpid, but there is also no os.fork(),
264        so there is no need for this check.
265     */
266     if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) {
267         goto not_found;
268     }
269 #endif
270 
271     Py_INCREF(running_loop);
272     *loop = running_loop;
273     return 0;
274 
275 not_found:
276     *loop = NULL;
277     return 0;
278 
279 error:
280     *loop = NULL;
281     return -1;
282 }
283 
284 
285 static int
set_running_loop(PyObject * loop)286 set_running_loop(PyObject *loop)
287 {
288     PyObject *ts_dict = NULL;
289 
290     PyThreadState *tstate = PyThreadState_Get();
291     if (tstate != NULL) {
292         ts_dict = _PyThreadState_GetDict(tstate);  // borrowed
293     }
294 
295     if (ts_dict == NULL) {
296         PyErr_SetString(
297             PyExc_RuntimeError, "thread-local storage is not available");
298         return -1;
299     }
300 
301     PyRunningLoopHolder *rl = new_running_loop_holder(loop);
302     if (rl == NULL) {
303         return -1;
304     }
305 
306     if (_PyDict_SetItemId(
307             ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0)
308     {
309         Py_DECREF(rl);  // will cleanup loop & current_pid
310         return -1;
311     }
312     Py_DECREF(rl);
313 
314     cached_running_holder = (PyObject *)rl;
315     cached_running_holder_tsid = PyThreadState_GetID(tstate);
316 
317     return 0;
318 }
319 
320 
321 static PyObject *
get_event_loop(int stacklevel)322 get_event_loop(int stacklevel)
323 {
324     PyObject *loop;
325     PyObject *policy;
326 
327     if (get_running_loop(&loop)) {
328         return NULL;
329     }
330     if (loop != NULL) {
331         return loop;
332     }
333 
334     if (PyErr_WarnEx(PyExc_DeprecationWarning,
335                      "There is no current event loop",
336                      stacklevel))
337     {
338         return NULL;
339     }
340 
341     policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy);
342     if (policy == NULL) {
343         return NULL;
344     }
345 
346     loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop);
347     Py_DECREF(policy);
348     return loop;
349 }
350 
351 
352 static int
call_soon(PyObject * loop,PyObject * func,PyObject * arg,PyObject * ctx)353 call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx)
354 {
355     PyObject *handle;
356     PyObject *stack[3];
357     Py_ssize_t nargs;
358 
359     if (ctx == NULL) {
360         handle = _PyObject_CallMethodIdObjArgs(
361             loop, &PyId_call_soon, func, arg, NULL);
362     }
363     else {
364         /* Use FASTCALL to pass a keyword-only argument to call_soon */
365 
366         PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon);
367         if (callable == NULL) {
368             return -1;
369         }
370 
371         /* All refs in 'stack' are borrowed. */
372         nargs = 1;
373         stack[0] = func;
374         if (arg != NULL) {
375             stack[1] = arg;
376             nargs++;
377         }
378         stack[nargs] = (PyObject *)ctx;
379 
380         handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname);
381         Py_DECREF(callable);
382     }
383 
384     if (handle == NULL) {
385         return -1;
386     }
387     Py_DECREF(handle);
388     return 0;
389 }
390 
391 
392 static inline int
future_is_alive(FutureObj * fut)393 future_is_alive(FutureObj *fut)
394 {
395     return fut->fut_loop != NULL;
396 }
397 
398 
399 static inline int
future_ensure_alive(FutureObj * fut)400 future_ensure_alive(FutureObj *fut)
401 {
402     if (!future_is_alive(fut)) {
403         PyErr_SetString(PyExc_RuntimeError,
404                         "Future object is not initialized.");
405         return -1;
406     }
407     return 0;
408 }
409 
410 
411 #define ENSURE_FUTURE_ALIVE(fut)                                \
412     do {                                                        \
413         assert(Future_Check(fut) || Task_Check(fut));           \
414         if (future_ensure_alive((FutureObj*)fut)) {             \
415             return NULL;                                        \
416         }                                                       \
417     } while(0);
418 
419 
420 static int
future_schedule_callbacks(FutureObj * fut)421 future_schedule_callbacks(FutureObj *fut)
422 {
423     Py_ssize_t len;
424     Py_ssize_t i;
425 
426     if (fut->fut_callback0 != NULL) {
427         /* There's a 1st callback */
428 
429         int ret = call_soon(
430             fut->fut_loop, fut->fut_callback0,
431             (PyObject *)fut, fut->fut_context0);
432 
433         Py_CLEAR(fut->fut_callback0);
434         Py_CLEAR(fut->fut_context0);
435         if (ret) {
436             /* If an error occurs in pure-Python implementation,
437                all callbacks are cleared. */
438             Py_CLEAR(fut->fut_callbacks);
439             return ret;
440         }
441 
442         /* we called the first callback, now try calling
443            callbacks from the 'fut_callbacks' list. */
444     }
445 
446     if (fut->fut_callbacks == NULL) {
447         /* No more callbacks, return. */
448         return 0;
449     }
450 
451     len = PyList_GET_SIZE(fut->fut_callbacks);
452     if (len == 0) {
453         /* The list of callbacks was empty; clear it and return. */
454         Py_CLEAR(fut->fut_callbacks);
455         return 0;
456     }
457 
458     for (i = 0; i < len; i++) {
459         PyObject *cb_tup = PyList_GET_ITEM(fut->fut_callbacks, i);
460         PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0);
461         PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1);
462 
463         if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) {
464             /* If an error occurs in pure-Python implementation,
465                all callbacks are cleared. */
466             Py_CLEAR(fut->fut_callbacks);
467             return -1;
468         }
469     }
470 
471     Py_CLEAR(fut->fut_callbacks);
472     return 0;
473 }
474 
475 
476 static int
future_init(FutureObj * fut,PyObject * loop)477 future_init(FutureObj *fut, PyObject *loop)
478 {
479     PyObject *res;
480     int is_true;
481     _Py_IDENTIFIER(get_debug);
482 
483     // Same to FutureObj_clear() but not clearing fut->dict
484     Py_CLEAR(fut->fut_loop);
485     Py_CLEAR(fut->fut_callback0);
486     Py_CLEAR(fut->fut_context0);
487     Py_CLEAR(fut->fut_callbacks);
488     Py_CLEAR(fut->fut_result);
489     Py_CLEAR(fut->fut_exception);
490     Py_CLEAR(fut->fut_source_tb);
491     Py_CLEAR(fut->fut_cancel_msg);
492     _PyErr_ClearExcState(&fut->fut_cancelled_exc_state);
493 
494     fut->fut_state = STATE_PENDING;
495     fut->fut_log_tb = 0;
496     fut->fut_blocking = 0;
497 
498     if (loop == Py_None) {
499         loop = get_event_loop(1);
500         if (loop == NULL) {
501             return -1;
502         }
503     }
504     else {
505         Py_INCREF(loop);
506     }
507     fut->fut_loop = loop;
508 
509     res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug);
510     if (res == NULL) {
511         return -1;
512     }
513     is_true = PyObject_IsTrue(res);
514     Py_DECREF(res);
515     if (is_true < 0) {
516         return -1;
517     }
518     if (is_true && !_Py_IsFinalizing()) {
519         /* Only try to capture the traceback if the interpreter is not being
520            finalized.  The original motivation to add a `_Py_IsFinalizing()`
521            call was to prevent SIGSEGV when a Future is created in a __del__
522            method, which is called during the interpreter shutdown and the
523            traceback module is already unloaded.
524         */
525         fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack);
526         if (fut->fut_source_tb == NULL) {
527             return -1;
528         }
529     }
530 
531     return 0;
532 }
533 
534 static PyObject *
future_set_result(FutureObj * fut,PyObject * res)535 future_set_result(FutureObj *fut, PyObject *res)
536 {
537     if (future_ensure_alive(fut)) {
538         return NULL;
539     }
540 
541     if (fut->fut_state != STATE_PENDING) {
542         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
543         return NULL;
544     }
545 
546     assert(!fut->fut_result);
547     Py_INCREF(res);
548     fut->fut_result = res;
549     fut->fut_state = STATE_FINISHED;
550 
551     if (future_schedule_callbacks(fut) == -1) {
552         return NULL;
553     }
554     Py_RETURN_NONE;
555 }
556 
557 static PyObject *
future_set_exception(FutureObj * fut,PyObject * exc)558 future_set_exception(FutureObj *fut, PyObject *exc)
559 {
560     PyObject *exc_val = NULL;
561 
562     if (fut->fut_state != STATE_PENDING) {
563         PyErr_SetString(asyncio_InvalidStateError, "invalid state");
564         return NULL;
565     }
566 
567     if (PyExceptionClass_Check(exc)) {
568         exc_val = PyObject_CallNoArgs(exc);
569         if (exc_val == NULL) {
570             return NULL;
571         }
572         if (fut->fut_state != STATE_PENDING) {
573             Py_DECREF(exc_val);
574             PyErr_SetString(asyncio_InvalidStateError, "invalid state");
575             return NULL;
576         }
577     }
578     else {
579         exc_val = exc;
580         Py_INCREF(exc_val);
581     }
582     if (!PyExceptionInstance_Check(exc_val)) {
583         Py_DECREF(exc_val);
584         PyErr_SetString(PyExc_TypeError, "invalid exception object");
585         return NULL;
586     }
587     if (Py_IS_TYPE(exc_val, (PyTypeObject *)PyExc_StopIteration)) {
588         Py_DECREF(exc_val);
589         PyErr_SetString(PyExc_TypeError,
590                         "StopIteration interacts badly with generators "
591                         "and cannot be raised into a Future");
592         return NULL;
593     }
594 
595     assert(!fut->fut_exception);
596     fut->fut_exception = exc_val;
597     fut->fut_state = STATE_FINISHED;
598 
599     if (future_schedule_callbacks(fut) == -1) {
600         return NULL;
601     }
602 
603     fut->fut_log_tb = 1;
604     Py_RETURN_NONE;
605 }
606 
607 static PyObject *
create_cancelled_error(PyObject * msg)608 create_cancelled_error(PyObject *msg)
609 {
610     PyObject *exc;
611     if (msg == NULL || msg == Py_None) {
612         exc = PyObject_CallNoArgs(asyncio_CancelledError);
613     } else {
614         exc = PyObject_CallOneArg(asyncio_CancelledError, msg);
615     }
616     return exc;
617 }
618 
619 static void
future_set_cancelled_error(FutureObj * fut)620 future_set_cancelled_error(FutureObj *fut)
621 {
622     PyObject *exc = create_cancelled_error(fut->fut_cancel_msg);
623     PyErr_SetObject(asyncio_CancelledError, exc);
624     Py_DECREF(exc);
625 
626     _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state);
627 }
628 
629 static int
future_get_result(FutureObj * fut,PyObject ** result)630 future_get_result(FutureObj *fut, PyObject **result)
631 {
632     if (fut->fut_state == STATE_CANCELLED) {
633         future_set_cancelled_error(fut);
634         return -1;
635     }
636 
637     if (fut->fut_state != STATE_FINISHED) {
638         PyErr_SetString(asyncio_InvalidStateError, "Result is not set.");
639         return -1;
640     }
641 
642     fut->fut_log_tb = 0;
643     if (fut->fut_exception != NULL) {
644         Py_INCREF(fut->fut_exception);
645         *result = fut->fut_exception;
646         return 1;
647     }
648 
649     Py_INCREF(fut->fut_result);
650     *result = fut->fut_result;
651     return 0;
652 }
653 
654 static PyObject *
future_add_done_callback(FutureObj * fut,PyObject * arg,PyObject * ctx)655 future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx)
656 {
657     if (!future_is_alive(fut)) {
658         PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object");
659         return NULL;
660     }
661 
662     if (fut->fut_state != STATE_PENDING) {
663         /* The future is done/cancelled, so schedule the callback
664            right away. */
665         if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) {
666             return NULL;
667         }
668     }
669     else {
670         /* The future is pending, add a callback.
671 
672            Callbacks in the future object are stored as follows:
673 
674               callback0 -- a pointer to the first callback
675               callbacks -- a list of 2nd, 3rd, ... callbacks
676 
677            Invariants:
678 
679             * callbacks != NULL:
680                 There are some callbacks in in the list.  Just
681                 add the new callback to it.
682 
683             * callbacks == NULL and callback0 == NULL:
684                 This is the first callback.  Set it to callback0.
685 
686             * callbacks == NULL and callback0 != NULL:
687                 This is a second callback.  Initialize callbacks
688                 with a new list and add the new callback to it.
689         */
690 
691         if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) {
692             Py_INCREF(arg);
693             fut->fut_callback0 = arg;
694             Py_INCREF(ctx);
695             fut->fut_context0 = ctx;
696         }
697         else {
698             PyObject *tup = PyTuple_New(2);
699             if (tup == NULL) {
700                 return NULL;
701             }
702             Py_INCREF(arg);
703             PyTuple_SET_ITEM(tup, 0, arg);
704             Py_INCREF(ctx);
705             PyTuple_SET_ITEM(tup, 1, (PyObject *)ctx);
706 
707             if (fut->fut_callbacks != NULL) {
708                 int err = PyList_Append(fut->fut_callbacks, tup);
709                 if (err) {
710                     Py_DECREF(tup);
711                     return NULL;
712                 }
713                 Py_DECREF(tup);
714             }
715             else {
716                 fut->fut_callbacks = PyList_New(1);
717                 if (fut->fut_callbacks == NULL) {
718                     Py_DECREF(tup);
719                     return NULL;
720                 }
721 
722                 PyList_SET_ITEM(fut->fut_callbacks, 0, tup);  /* borrow */
723             }
724         }
725     }
726 
727     Py_RETURN_NONE;
728 }
729 
730 static PyObject *
future_cancel(FutureObj * fut,PyObject * msg)731 future_cancel(FutureObj *fut, PyObject *msg)
732 {
733     fut->fut_log_tb = 0;
734 
735     if (fut->fut_state != STATE_PENDING) {
736         Py_RETURN_FALSE;
737     }
738     fut->fut_state = STATE_CANCELLED;
739 
740     Py_XINCREF(msg);
741     Py_XSETREF(fut->fut_cancel_msg, msg);
742 
743     if (future_schedule_callbacks(fut) == -1) {
744         return NULL;
745     }
746 
747     Py_RETURN_TRUE;
748 }
749 
750 /*[clinic input]
751 _asyncio.Future.__init__
752 
753     *
754     loop: object = None
755 
756 This class is *almost* compatible with concurrent.futures.Future.
757 
758     Differences:
759 
760     - result() and exception() do not take a timeout argument and
761       raise an exception when the future isn't done yet.
762 
763     - Callbacks registered with add_done_callback() are always called
764       via the event loop's call_soon_threadsafe().
765 
766     - This class is not compatible with the wait() and as_completed()
767       methods in the concurrent.futures package.
768 [clinic start generated code]*/
769 
770 static int
_asyncio_Future___init___impl(FutureObj * self,PyObject * loop)771 _asyncio_Future___init___impl(FutureObj *self, PyObject *loop)
772 /*[clinic end generated code: output=9ed75799eaccb5d6 input=89af317082bc0bf8]*/
773 
774 {
775     return future_init(self, loop);
776 }
777 
778 static int
FutureObj_clear(FutureObj * fut)779 FutureObj_clear(FutureObj *fut)
780 {
781     Py_CLEAR(fut->fut_loop);
782     Py_CLEAR(fut->fut_callback0);
783     Py_CLEAR(fut->fut_context0);
784     Py_CLEAR(fut->fut_callbacks);
785     Py_CLEAR(fut->fut_result);
786     Py_CLEAR(fut->fut_exception);
787     Py_CLEAR(fut->fut_source_tb);
788     Py_CLEAR(fut->fut_cancel_msg);
789     _PyErr_ClearExcState(&fut->fut_cancelled_exc_state);
790     Py_CLEAR(fut->dict);
791     return 0;
792 }
793 
794 static int
FutureObj_traverse(FutureObj * fut,visitproc visit,void * arg)795 FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg)
796 {
797     Py_VISIT(fut->fut_loop);
798     Py_VISIT(fut->fut_callback0);
799     Py_VISIT(fut->fut_context0);
800     Py_VISIT(fut->fut_callbacks);
801     Py_VISIT(fut->fut_result);
802     Py_VISIT(fut->fut_exception);
803     Py_VISIT(fut->fut_source_tb);
804     Py_VISIT(fut->fut_cancel_msg);
805     Py_VISIT(fut->dict);
806 
807     _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state;
808     Py_VISIT(exc_state->exc_type);
809     Py_VISIT(exc_state->exc_value);
810     Py_VISIT(exc_state->exc_traceback);
811 
812     return 0;
813 }
814 
815 /*[clinic input]
816 _asyncio.Future.result
817 
818 Return the result this future represents.
819 
820 If the future has been cancelled, raises CancelledError.  If the
821 future's result isn't yet available, raises InvalidStateError.  If
822 the future is done and has an exception set, this exception is raised.
823 [clinic start generated code]*/
824 
825 static PyObject *
_asyncio_Future_result_impl(FutureObj * self)826 _asyncio_Future_result_impl(FutureObj *self)
827 /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/
828 {
829     PyObject *result;
830 
831     if (!future_is_alive(self)) {
832         PyErr_SetString(asyncio_InvalidStateError,
833                         "Future object is not initialized.");
834         return NULL;
835     }
836 
837     int res = future_get_result(self, &result);
838 
839     if (res == -1) {
840         return NULL;
841     }
842 
843     if (res == 0) {
844         return result;
845     }
846 
847     assert(res == 1);
848 
849     PyErr_SetObject(PyExceptionInstance_Class(result), result);
850     Py_DECREF(result);
851     return NULL;
852 }
853 
854 /*[clinic input]
855 _asyncio.Future.exception
856 
857 Return the exception that was set on this future.
858 
859 The exception (or None if no exception was set) is returned only if
860 the future is done.  If the future has been cancelled, raises
861 CancelledError.  If the future isn't done yet, raises
862 InvalidStateError.
863 [clinic start generated code]*/
864 
865 static PyObject *
_asyncio_Future_exception_impl(FutureObj * self)866 _asyncio_Future_exception_impl(FutureObj *self)
867 /*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/
868 {
869     if (!future_is_alive(self)) {
870         PyErr_SetString(asyncio_InvalidStateError,
871                         "Future object is not initialized.");
872         return NULL;
873     }
874 
875     if (self->fut_state == STATE_CANCELLED) {
876         future_set_cancelled_error(self);
877         return NULL;
878     }
879 
880     if (self->fut_state != STATE_FINISHED) {
881         PyErr_SetString(asyncio_InvalidStateError, "Exception is not set.");
882         return NULL;
883     }
884 
885     if (self->fut_exception != NULL) {
886         self->fut_log_tb = 0;
887         Py_INCREF(self->fut_exception);
888         return self->fut_exception;
889     }
890 
891     Py_RETURN_NONE;
892 }
893 
894 /*[clinic input]
895 _asyncio.Future.set_result
896 
897     result: object
898     /
899 
900 Mark the future done and set its result.
901 
902 If the future is already done when this method is called, raises
903 InvalidStateError.
904 [clinic start generated code]*/
905 
906 static PyObject *
_asyncio_Future_set_result(FutureObj * self,PyObject * result)907 _asyncio_Future_set_result(FutureObj *self, PyObject *result)
908 /*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/
909 {
910     ENSURE_FUTURE_ALIVE(self)
911     return future_set_result(self, result);
912 }
913 
914 /*[clinic input]
915 _asyncio.Future.set_exception
916 
917     exception: object
918     /
919 
920 Mark the future done and set an exception.
921 
922 If the future is already done when this method is called, raises
923 InvalidStateError.
924 [clinic start generated code]*/
925 
926 static PyObject *
_asyncio_Future_set_exception(FutureObj * self,PyObject * exception)927 _asyncio_Future_set_exception(FutureObj *self, PyObject *exception)
928 /*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/
929 {
930     ENSURE_FUTURE_ALIVE(self)
931     return future_set_exception(self, exception);
932 }
933 
934 /*[clinic input]
935 _asyncio.Future.add_done_callback
936 
937     fn: object
938     /
939     *
940     context: object = NULL
941 
942 Add a callback to be run when the future becomes done.
943 
944 The callback is called with a single argument - the future object. If
945 the future is already done when this is called, the callback is
946 scheduled with call_soon.
947 [clinic start generated code]*/
948 
949 static PyObject *
_asyncio_Future_add_done_callback_impl(FutureObj * self,PyObject * fn,PyObject * context)950 _asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn,
951                                        PyObject *context)
952 /*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/
953 {
954     if (context == NULL) {
955         context = PyContext_CopyCurrent();
956         if (context == NULL) {
957             return NULL;
958         }
959         PyObject *res = future_add_done_callback(self, fn, context);
960         Py_DECREF(context);
961         return res;
962     }
963     return future_add_done_callback(self, fn, context);
964 }
965 
966 /*[clinic input]
967 _asyncio.Future.remove_done_callback
968 
969     fn: object
970     /
971 
972 Remove all instances of a callback from the "call when done" list.
973 
974 Returns the number of callbacks removed.
975 [clinic start generated code]*/
976 
977 static PyObject *
_asyncio_Future_remove_done_callback(FutureObj * self,PyObject * fn)978 _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn)
979 /*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/
980 {
981     PyObject *newlist;
982     Py_ssize_t len, i, j=0;
983     Py_ssize_t cleared_callback0 = 0;
984 
985     ENSURE_FUTURE_ALIVE(self)
986 
987     if (self->fut_callback0 != NULL) {
988         int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ);
989         if (cmp == -1) {
990             return NULL;
991         }
992         if (cmp == 1) {
993             /* callback0 == fn */
994             Py_CLEAR(self->fut_callback0);
995             Py_CLEAR(self->fut_context0);
996             cleared_callback0 = 1;
997         }
998     }
999 
1000     if (self->fut_callbacks == NULL) {
1001         return PyLong_FromSsize_t(cleared_callback0);
1002     }
1003 
1004     len = PyList_GET_SIZE(self->fut_callbacks);
1005     if (len == 0) {
1006         Py_CLEAR(self->fut_callbacks);
1007         return PyLong_FromSsize_t(cleared_callback0);
1008     }
1009 
1010     if (len == 1) {
1011         PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0);
1012         int cmp = PyObject_RichCompareBool(
1013             PyTuple_GET_ITEM(cb_tup, 0), fn, Py_EQ);
1014         if (cmp == -1) {
1015             return NULL;
1016         }
1017         if (cmp == 1) {
1018             /* callbacks[0] == fn */
1019             Py_CLEAR(self->fut_callbacks);
1020             return PyLong_FromSsize_t(1 + cleared_callback0);
1021         }
1022         /* callbacks[0] != fn and len(callbacks) == 1 */
1023         return PyLong_FromSsize_t(cleared_callback0);
1024     }
1025 
1026     newlist = PyList_New(len);
1027     if (newlist == NULL) {
1028         return NULL;
1029     }
1030 
1031     for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) {
1032         int ret;
1033         PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i);
1034         Py_INCREF(item);
1035         ret = PyObject_RichCompareBool(PyTuple_GET_ITEM(item, 0), fn, Py_EQ);
1036         if (ret == 0) {
1037             if (j < len) {
1038                 PyList_SET_ITEM(newlist, j, item);
1039                 j++;
1040                 continue;
1041             }
1042             ret = PyList_Append(newlist, item);
1043         }
1044         Py_DECREF(item);
1045         if (ret < 0) {
1046             goto fail;
1047         }
1048     }
1049 
1050     if (j == 0) {
1051         Py_CLEAR(self->fut_callbacks);
1052         Py_DECREF(newlist);
1053         return PyLong_FromSsize_t(len + cleared_callback0);
1054     }
1055 
1056     if (j < len) {
1057         Py_SET_SIZE(newlist, j);
1058     }
1059     j = PyList_GET_SIZE(newlist);
1060     len = PyList_GET_SIZE(self->fut_callbacks);
1061     if (j != len) {
1062         if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) {
1063             goto fail;
1064         }
1065     }
1066     Py_DECREF(newlist);
1067     return PyLong_FromSsize_t(len - j + cleared_callback0);
1068 
1069 fail:
1070     Py_DECREF(newlist);
1071     return NULL;
1072 }
1073 
1074 /*[clinic input]
1075 _asyncio.Future.cancel
1076 
1077     msg: object = None
1078 
1079 Cancel the future and schedule callbacks.
1080 
1081 If the future is already done or cancelled, return False.  Otherwise,
1082 change the future's state to cancelled, schedule the callbacks and
1083 return True.
1084 [clinic start generated code]*/
1085 
1086 static PyObject *
_asyncio_Future_cancel_impl(FutureObj * self,PyObject * msg)1087 _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg)
1088 /*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/
1089 {
1090     ENSURE_FUTURE_ALIVE(self)
1091     return future_cancel(self, msg);
1092 }
1093 
1094 /*[clinic input]
1095 _asyncio.Future.cancelled
1096 
1097 Return True if the future was cancelled.
1098 [clinic start generated code]*/
1099 
1100 static PyObject *
_asyncio_Future_cancelled_impl(FutureObj * self)1101 _asyncio_Future_cancelled_impl(FutureObj *self)
1102 /*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/
1103 {
1104     if (future_is_alive(self) && self->fut_state == STATE_CANCELLED) {
1105         Py_RETURN_TRUE;
1106     }
1107     else {
1108         Py_RETURN_FALSE;
1109     }
1110 }
1111 
1112 /*[clinic input]
1113 _asyncio.Future.done
1114 
1115 Return True if the future is done.
1116 
1117 Done means either that a result / exception are available, or that the
1118 future was cancelled.
1119 [clinic start generated code]*/
1120 
1121 static PyObject *
_asyncio_Future_done_impl(FutureObj * self)1122 _asyncio_Future_done_impl(FutureObj *self)
1123 /*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/
1124 {
1125     if (!future_is_alive(self) || self->fut_state == STATE_PENDING) {
1126         Py_RETURN_FALSE;
1127     }
1128     else {
1129         Py_RETURN_TRUE;
1130     }
1131 }
1132 
1133 /*[clinic input]
1134 _asyncio.Future.get_loop
1135 
1136 Return the event loop the Future is bound to.
1137 [clinic start generated code]*/
1138 
1139 static PyObject *
_asyncio_Future_get_loop_impl(FutureObj * self)1140 _asyncio_Future_get_loop_impl(FutureObj *self)
1141 /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/
1142 {
1143     ENSURE_FUTURE_ALIVE(self)
1144     Py_INCREF(self->fut_loop);
1145     return self->fut_loop;
1146 }
1147 
1148 static PyObject *
FutureObj_get_blocking(FutureObj * fut,void * Py_UNUSED (ignored))1149 FutureObj_get_blocking(FutureObj *fut, void *Py_UNUSED(ignored))
1150 {
1151     if (future_is_alive(fut) && fut->fut_blocking) {
1152         Py_RETURN_TRUE;
1153     }
1154     else {
1155         Py_RETURN_FALSE;
1156     }
1157 }
1158 
1159 static int
FutureObj_set_blocking(FutureObj * fut,PyObject * val,void * Py_UNUSED (ignored))1160 FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
1161 {
1162     if (future_ensure_alive(fut)) {
1163         return -1;
1164     }
1165     if (val == NULL) {
1166         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1167         return -1;
1168     }
1169 
1170     int is_true = PyObject_IsTrue(val);
1171     if (is_true < 0) {
1172         return -1;
1173     }
1174     fut->fut_blocking = is_true;
1175     return 0;
1176 }
1177 
1178 static PyObject *
FutureObj_get_log_traceback(FutureObj * fut,void * Py_UNUSED (ignored))1179 FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
1180 {
1181     ENSURE_FUTURE_ALIVE(fut)
1182     if (fut->fut_log_tb) {
1183         Py_RETURN_TRUE;
1184     }
1185     else {
1186         Py_RETURN_FALSE;
1187     }
1188 }
1189 
1190 static int
FutureObj_set_log_traceback(FutureObj * fut,PyObject * val,void * Py_UNUSED (ignored))1191 FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored))
1192 {
1193     if (val == NULL) {
1194         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1195         return -1;
1196     }
1197     int is_true = PyObject_IsTrue(val);
1198     if (is_true < 0) {
1199         return -1;
1200     }
1201     if (is_true) {
1202         PyErr_SetString(PyExc_ValueError,
1203                         "_log_traceback can only be set to False");
1204         return -1;
1205     }
1206     fut->fut_log_tb = is_true;
1207     return 0;
1208 }
1209 
1210 static PyObject *
FutureObj_get_loop(FutureObj * fut,void * Py_UNUSED (ignored))1211 FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored))
1212 {
1213     if (!future_is_alive(fut)) {
1214         Py_RETURN_NONE;
1215     }
1216     Py_INCREF(fut->fut_loop);
1217     return fut->fut_loop;
1218 }
1219 
1220 static PyObject *
FutureObj_get_callbacks(FutureObj * fut,void * Py_UNUSED (ignored))1221 FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored))
1222 {
1223     Py_ssize_t i;
1224 
1225     ENSURE_FUTURE_ALIVE(fut)
1226 
1227     if (fut->fut_callback0 == NULL) {
1228         if (fut->fut_callbacks == NULL) {
1229             Py_RETURN_NONE;
1230         }
1231 
1232         Py_INCREF(fut->fut_callbacks);
1233         return fut->fut_callbacks;
1234     }
1235 
1236     Py_ssize_t len = 1;
1237     if (fut->fut_callbacks != NULL) {
1238         len += PyList_GET_SIZE(fut->fut_callbacks);
1239     }
1240 
1241 
1242     PyObject *new_list = PyList_New(len);
1243     if (new_list == NULL) {
1244         return NULL;
1245     }
1246 
1247     PyObject *tup0 = PyTuple_New(2);
1248     if (tup0 == NULL) {
1249         Py_DECREF(new_list);
1250         return NULL;
1251     }
1252 
1253     Py_INCREF(fut->fut_callback0);
1254     PyTuple_SET_ITEM(tup0, 0, fut->fut_callback0);
1255     assert(fut->fut_context0 != NULL);
1256     Py_INCREF(fut->fut_context0);
1257     PyTuple_SET_ITEM(tup0, 1, (PyObject *)fut->fut_context0);
1258 
1259     PyList_SET_ITEM(new_list, 0, tup0);
1260 
1261     if (fut->fut_callbacks != NULL) {
1262         for (i = 0; i < PyList_GET_SIZE(fut->fut_callbacks); i++) {
1263             PyObject *cb = PyList_GET_ITEM(fut->fut_callbacks, i);
1264             Py_INCREF(cb);
1265             PyList_SET_ITEM(new_list, i + 1, cb);
1266         }
1267     }
1268 
1269     return new_list;
1270 }
1271 
1272 static PyObject *
FutureObj_get_result(FutureObj * fut,void * Py_UNUSED (ignored))1273 FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored))
1274 {
1275     ENSURE_FUTURE_ALIVE(fut)
1276     if (fut->fut_result == NULL) {
1277         Py_RETURN_NONE;
1278     }
1279     Py_INCREF(fut->fut_result);
1280     return fut->fut_result;
1281 }
1282 
1283 static PyObject *
FutureObj_get_exception(FutureObj * fut,void * Py_UNUSED (ignored))1284 FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored))
1285 {
1286     ENSURE_FUTURE_ALIVE(fut)
1287     if (fut->fut_exception == NULL) {
1288         Py_RETURN_NONE;
1289     }
1290     Py_INCREF(fut->fut_exception);
1291     return fut->fut_exception;
1292 }
1293 
1294 static PyObject *
FutureObj_get_source_traceback(FutureObj * fut,void * Py_UNUSED (ignored))1295 FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored))
1296 {
1297     if (!future_is_alive(fut) || fut->fut_source_tb == NULL) {
1298         Py_RETURN_NONE;
1299     }
1300     Py_INCREF(fut->fut_source_tb);
1301     return fut->fut_source_tb;
1302 }
1303 
1304 static PyObject *
FutureObj_get_cancel_message(FutureObj * fut,void * Py_UNUSED (ignored))1305 FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored))
1306 {
1307     if (fut->fut_cancel_msg == NULL) {
1308         Py_RETURN_NONE;
1309     }
1310     Py_INCREF(fut->fut_cancel_msg);
1311     return fut->fut_cancel_msg;
1312 }
1313 
1314 static int
FutureObj_set_cancel_message(FutureObj * fut,PyObject * msg,void * Py_UNUSED (ignored))1315 FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg,
1316                              void *Py_UNUSED(ignored))
1317 {
1318     if (msg == NULL) {
1319         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1320         return -1;
1321     }
1322     Py_INCREF(msg);
1323     Py_XSETREF(fut->fut_cancel_msg, msg);
1324     return 0;
1325 }
1326 
1327 static PyObject *
FutureObj_get_state(FutureObj * fut,void * Py_UNUSED (ignored))1328 FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored))
1329 {
1330     _Py_IDENTIFIER(PENDING);
1331     _Py_IDENTIFIER(CANCELLED);
1332     _Py_IDENTIFIER(FINISHED);
1333     PyObject *ret = NULL;
1334 
1335     ENSURE_FUTURE_ALIVE(fut)
1336 
1337     switch (fut->fut_state) {
1338     case STATE_PENDING:
1339         ret = _PyUnicode_FromId(&PyId_PENDING);
1340         break;
1341     case STATE_CANCELLED:
1342         ret = _PyUnicode_FromId(&PyId_CANCELLED);
1343         break;
1344     case STATE_FINISHED:
1345         ret = _PyUnicode_FromId(&PyId_FINISHED);
1346         break;
1347     default:
1348         assert (0);
1349     }
1350     Py_XINCREF(ret);
1351     return ret;
1352 }
1353 
1354 /*[clinic input]
1355 _asyncio.Future._make_cancelled_error
1356 
1357 Create the CancelledError to raise if the Future is cancelled.
1358 
1359 This should only be called once when handling a cancellation since
1360 it erases the context exception value.
1361 [clinic start generated code]*/
1362 
1363 static PyObject *
_asyncio_Future__make_cancelled_error_impl(FutureObj * self)1364 _asyncio_Future__make_cancelled_error_impl(FutureObj *self)
1365 /*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/
1366 {
1367     PyObject *exc = create_cancelled_error(self->fut_cancel_msg);
1368     _PyErr_StackItem *exc_state = &self->fut_cancelled_exc_state;
1369     /* Transfer ownership of exc_value from exc_state to exc since we are
1370        done with it. */
1371     PyException_SetContext(exc, exc_state->exc_value);
1372     exc_state->exc_value = NULL;
1373 
1374     return exc;
1375 }
1376 
1377 /*[clinic input]
1378 _asyncio.Future._repr_info
1379 [clinic start generated code]*/
1380 
1381 static PyObject *
_asyncio_Future__repr_info_impl(FutureObj * self)1382 _asyncio_Future__repr_info_impl(FutureObj *self)
1383 /*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/
1384 {
1385     return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self);
1386 }
1387 
1388 static PyObject *
FutureObj_repr(FutureObj * fut)1389 FutureObj_repr(FutureObj *fut)
1390 {
1391     _Py_IDENTIFIER(_repr_info);
1392 
1393     ENSURE_FUTURE_ALIVE(fut)
1394 
1395     PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut,
1396                                                    &PyId__repr_info);
1397     if (rinfo == NULL) {
1398         return NULL;
1399     }
1400 
1401     PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo);
1402     Py_DECREF(rinfo);
1403     if (rinfo_s == NULL) {
1404         return NULL;
1405     }
1406 
1407     PyObject *rstr = PyUnicode_FromFormat("<%s %U>",
1408                                           _PyType_Name(Py_TYPE(fut)), rinfo_s);
1409     Py_DECREF(rinfo_s);
1410     return rstr;
1411 }
1412 
1413 static void
FutureObj_finalize(FutureObj * fut)1414 FutureObj_finalize(FutureObj *fut)
1415 {
1416     _Py_IDENTIFIER(call_exception_handler);
1417     _Py_IDENTIFIER(message);
1418     _Py_IDENTIFIER(exception);
1419     _Py_IDENTIFIER(future);
1420     _Py_IDENTIFIER(source_traceback);
1421 
1422     PyObject *error_type, *error_value, *error_traceback;
1423     PyObject *context;
1424     PyObject *message = NULL;
1425     PyObject *func;
1426 
1427     if (!fut->fut_log_tb) {
1428         return;
1429     }
1430     assert(fut->fut_exception != NULL);
1431     fut->fut_log_tb = 0;
1432 
1433     /* Save the current exception, if any. */
1434     PyErr_Fetch(&error_type, &error_value, &error_traceback);
1435 
1436     context = PyDict_New();
1437     if (context == NULL) {
1438         goto finally;
1439     }
1440 
1441     message = PyUnicode_FromFormat(
1442         "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut)));
1443     if (message == NULL) {
1444         goto finally;
1445     }
1446 
1447     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
1448         _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 ||
1449         _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) {
1450         goto finally;
1451     }
1452     if (fut->fut_source_tb != NULL) {
1453         if (_PyDict_SetItemId(context, &PyId_source_traceback,
1454                               fut->fut_source_tb) < 0) {
1455             goto finally;
1456         }
1457     }
1458 
1459     func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler);
1460     if (func != NULL) {
1461         PyObject *res = PyObject_CallOneArg(func, context);
1462         if (res == NULL) {
1463             PyErr_WriteUnraisable(func);
1464         }
1465         else {
1466             Py_DECREF(res);
1467         }
1468         Py_DECREF(func);
1469     }
1470 
1471 finally:
1472     Py_XDECREF(context);
1473     Py_XDECREF(message);
1474 
1475     /* Restore the saved exception. */
1476     PyErr_Restore(error_type, error_value, error_traceback);
1477 }
1478 
1479 static PyObject *
future_cls_getitem(PyObject * cls,PyObject * type)1480 future_cls_getitem(PyObject *cls, PyObject *type)
1481 {
1482     Py_INCREF(cls);
1483     return cls;
1484 }
1485 
1486 static PyAsyncMethods FutureType_as_async = {
1487     (unaryfunc)future_new_iter,         /* am_await */
1488     0,                                  /* am_aiter */
1489     0,                                  /* am_anext */
1490     0,                                  /* am_send  */
1491 };
1492 
1493 static PyMethodDef FutureType_methods[] = {
1494     _ASYNCIO_FUTURE_RESULT_METHODDEF
1495     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
1496     _ASYNCIO_FUTURE_SET_RESULT_METHODDEF
1497     _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF
1498     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
1499     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
1500     _ASYNCIO_FUTURE_CANCEL_METHODDEF
1501     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
1502     _ASYNCIO_FUTURE_DONE_METHODDEF
1503     _ASYNCIO_FUTURE_GET_LOOP_METHODDEF
1504     _ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF
1505     _ASYNCIO_FUTURE__REPR_INFO_METHODDEF
1506     {"__class_getitem__", future_cls_getitem, METH_O|METH_CLASS, NULL},
1507     {NULL, NULL}        /* Sentinel */
1508 };
1509 
1510 #define FUTURE_COMMON_GETSETLIST                                              \
1511     {"_state", (getter)FutureObj_get_state, NULL, NULL},                      \
1512     {"_asyncio_future_blocking", (getter)FutureObj_get_blocking,              \
1513                                  (setter)FutureObj_set_blocking, NULL},       \
1514     {"_loop", (getter)FutureObj_get_loop, NULL, NULL},                        \
1515     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \
1516     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \
1517     {"_exception", (getter)FutureObj_get_exception, NULL, NULL},              \
1518     {"_log_traceback", (getter)FutureObj_get_log_traceback,                   \
1519                        (setter)FutureObj_set_log_traceback, NULL},            \
1520     {"_source_traceback", (getter)FutureObj_get_source_traceback,             \
1521                           NULL, NULL},                                        \
1522     {"_cancel_message", (getter)FutureObj_get_cancel_message,                 \
1523                         (setter)FutureObj_set_cancel_message, NULL},
1524 
1525 static PyGetSetDef FutureType_getsetlist[] = {
1526     FUTURE_COMMON_GETSETLIST
1527     {NULL} /* Sentinel */
1528 };
1529 
1530 static void FutureObj_dealloc(PyObject *self);
1531 
1532 static PyTypeObject FutureType = {
1533     PyVarObject_HEAD_INIT(NULL, 0)
1534     "_asyncio.Future",
1535     sizeof(FutureObj),                       /* tp_basicsize */
1536     .tp_dealloc = FutureObj_dealloc,
1537     .tp_as_async = &FutureType_as_async,
1538     .tp_repr = (reprfunc)FutureObj_repr,
1539     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
1540     .tp_doc = _asyncio_Future___init____doc__,
1541     .tp_traverse = (traverseproc)FutureObj_traverse,
1542     .tp_clear = (inquiry)FutureObj_clear,
1543     .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist),
1544     .tp_iter = (getiterfunc)future_new_iter,
1545     .tp_methods = FutureType_methods,
1546     .tp_getset = FutureType_getsetlist,
1547     .tp_dictoffset = offsetof(FutureObj, dict),
1548     .tp_init = (initproc)_asyncio_Future___init__,
1549     .tp_new = PyType_GenericNew,
1550     .tp_finalize = (destructor)FutureObj_finalize,
1551 };
1552 
1553 static void
FutureObj_dealloc(PyObject * self)1554 FutureObj_dealloc(PyObject *self)
1555 {
1556     FutureObj *fut = (FutureObj *)self;
1557 
1558     if (Future_CheckExact(fut)) {
1559         /* When fut is subclass of Future, finalizer is called from
1560          * subtype_dealloc.
1561          */
1562         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
1563             // resurrected.
1564             return;
1565         }
1566     }
1567 
1568     PyObject_GC_UnTrack(self);
1569 
1570     if (fut->fut_weakreflist != NULL) {
1571         PyObject_ClearWeakRefs(self);
1572     }
1573 
1574     (void)FutureObj_clear(fut);
1575     Py_TYPE(fut)->tp_free(fut);
1576 }
1577 
1578 
1579 /*********************** Future Iterator **************************/
1580 
1581 typedef struct {
1582     PyObject_HEAD
1583     FutureObj *future;
1584 } futureiterobject;
1585 
1586 
1587 #define FI_FREELIST_MAXLEN 255
1588 static futureiterobject *fi_freelist = NULL;
1589 static Py_ssize_t fi_freelist_len = 0;
1590 
1591 
1592 static void
FutureIter_dealloc(futureiterobject * it)1593 FutureIter_dealloc(futureiterobject *it)
1594 {
1595     PyObject_GC_UnTrack(it);
1596     Py_CLEAR(it->future);
1597 
1598     if (fi_freelist_len < FI_FREELIST_MAXLEN) {
1599         fi_freelist_len++;
1600         it->future = (FutureObj*) fi_freelist;
1601         fi_freelist = it;
1602     }
1603     else {
1604         PyObject_GC_Del(it);
1605     }
1606 }
1607 
1608 static PySendResult
FutureIter_am_send(futureiterobject * it,PyObject * Py_UNUSED (arg),PyObject ** result)1609 FutureIter_am_send(futureiterobject *it,
1610                    PyObject *Py_UNUSED(arg),
1611                    PyObject **result)
1612 {
1613     /* arg is unused, see the comment on FutureIter_send for clarification */
1614 
1615     PyObject *res;
1616     FutureObj *fut = it->future;
1617 
1618     *result = NULL;
1619     if (fut == NULL) {
1620         return PYGEN_ERROR;
1621     }
1622 
1623     if (fut->fut_state == STATE_PENDING) {
1624         if (!fut->fut_blocking) {
1625             fut->fut_blocking = 1;
1626             Py_INCREF(fut);
1627             *result = (PyObject *)fut;
1628             return PYGEN_NEXT;
1629         }
1630         PyErr_SetString(PyExc_RuntimeError,
1631                         "await wasn't used with future");
1632         return PYGEN_ERROR;
1633     }
1634 
1635     it->future = NULL;
1636     res = _asyncio_Future_result_impl(fut);
1637     if (res != NULL) {
1638         Py_DECREF(fut);
1639         *result = res;
1640         return PYGEN_RETURN;
1641     }
1642 
1643     Py_DECREF(fut);
1644     return PYGEN_ERROR;
1645 }
1646 
1647 static PyObject *
FutureIter_iternext(futureiterobject * it)1648 FutureIter_iternext(futureiterobject *it)
1649 {
1650     PyObject *result;
1651     switch (FutureIter_am_send(it, Py_None, &result)) {
1652         case PYGEN_RETURN:
1653             (void)_PyGen_SetStopIterationValue(result);
1654             Py_DECREF(result);
1655             return NULL;
1656         case PYGEN_NEXT:
1657             return result;
1658         case PYGEN_ERROR:
1659             return NULL;
1660         default:
1661             Py_UNREACHABLE();
1662     }
1663 }
1664 
1665 static PyObject *
FutureIter_send(futureiterobject * self,PyObject * unused)1666 FutureIter_send(futureiterobject *self, PyObject *unused)
1667 {
1668     /* Future.__iter__ doesn't care about values that are pushed to the
1669      * generator, it just returns self.result().
1670      */
1671     return FutureIter_iternext(self);
1672 }
1673 
1674 static PyObject *
FutureIter_throw(futureiterobject * self,PyObject * args)1675 FutureIter_throw(futureiterobject *self, PyObject *args)
1676 {
1677     PyObject *type, *val = NULL, *tb = NULL;
1678     if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb))
1679         return NULL;
1680 
1681     if (val == Py_None) {
1682         val = NULL;
1683     }
1684     if (tb == Py_None) {
1685         tb = NULL;
1686     } else if (tb != NULL && !PyTraceBack_Check(tb)) {
1687         PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback");
1688         return NULL;
1689     }
1690 
1691     Py_INCREF(type);
1692     Py_XINCREF(val);
1693     Py_XINCREF(tb);
1694 
1695     if (PyExceptionClass_Check(type)) {
1696         PyErr_NormalizeException(&type, &val, &tb);
1697         /* No need to call PyException_SetTraceback since we'll be calling
1698            PyErr_Restore for `type`, `val`, and `tb`. */
1699     } else if (PyExceptionInstance_Check(type)) {
1700         if (val) {
1701             PyErr_SetString(PyExc_TypeError,
1702                             "instance exception may not have a separate value");
1703             goto fail;
1704         }
1705         val = type;
1706         type = PyExceptionInstance_Class(type);
1707         Py_INCREF(type);
1708         if (tb == NULL)
1709             tb = PyException_GetTraceback(val);
1710     } else {
1711         PyErr_SetString(PyExc_TypeError,
1712                         "exceptions must be classes deriving BaseException or "
1713                         "instances of such a class");
1714         goto fail;
1715     }
1716 
1717     Py_CLEAR(self->future);
1718 
1719     PyErr_Restore(type, val, tb);
1720 
1721     return NULL;
1722 
1723   fail:
1724     Py_DECREF(type);
1725     Py_XDECREF(val);
1726     Py_XDECREF(tb);
1727     return NULL;
1728 }
1729 
1730 static PyObject *
FutureIter_close(futureiterobject * self,PyObject * arg)1731 FutureIter_close(futureiterobject *self, PyObject *arg)
1732 {
1733     Py_CLEAR(self->future);
1734     Py_RETURN_NONE;
1735 }
1736 
1737 static int
FutureIter_traverse(futureiterobject * it,visitproc visit,void * arg)1738 FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg)
1739 {
1740     Py_VISIT(it->future);
1741     return 0;
1742 }
1743 
1744 static PyMethodDef FutureIter_methods[] = {
1745     {"send",  (PyCFunction)FutureIter_send, METH_O, NULL},
1746     {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL},
1747     {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL},
1748     {NULL, NULL}        /* Sentinel */
1749 };
1750 
1751 static PyAsyncMethods FutureIterType_as_async = {
1752     0,                                  /* am_await */
1753     0,                                  /* am_aiter */
1754     0,                                  /* am_anext */
1755     (sendfunc)FutureIter_am_send,       /* am_send  */
1756 };
1757 
1758 
1759 static PyTypeObject FutureIterType = {
1760     PyVarObject_HEAD_INIT(NULL, 0)
1761     "_asyncio.FutureIter",
1762     .tp_basicsize = sizeof(futureiterobject),
1763     .tp_itemsize = 0,
1764     .tp_dealloc = (destructor)FutureIter_dealloc,
1765     .tp_as_async = &FutureIterType_as_async,
1766     .tp_getattro = PyObject_GenericGetAttr,
1767     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1768     .tp_traverse = (traverseproc)FutureIter_traverse,
1769     .tp_iter = PyObject_SelfIter,
1770     .tp_iternext = (iternextfunc)FutureIter_iternext,
1771     .tp_methods = FutureIter_methods,
1772 };
1773 
1774 static PyObject *
future_new_iter(PyObject * fut)1775 future_new_iter(PyObject *fut)
1776 {
1777     futureiterobject *it;
1778 
1779     if (!PyObject_TypeCheck(fut, &FutureType)) {
1780         PyErr_BadInternalCall();
1781         return NULL;
1782     }
1783 
1784     ENSURE_FUTURE_ALIVE(fut)
1785 
1786     if (fi_freelist_len) {
1787         fi_freelist_len--;
1788         it = fi_freelist;
1789         fi_freelist = (futureiterobject*) it->future;
1790         it->future = NULL;
1791         _Py_NewReference((PyObject*) it);
1792     }
1793     else {
1794         it = PyObject_GC_New(futureiterobject, &FutureIterType);
1795         if (it == NULL) {
1796             return NULL;
1797         }
1798     }
1799 
1800     Py_INCREF(fut);
1801     it->future = (FutureObj*)fut;
1802     PyObject_GC_Track(it);
1803     return (PyObject*)it;
1804 }
1805 
1806 
1807 /*********************** Task **************************/
1808 
1809 
1810 /*[clinic input]
1811 class _asyncio.Task "TaskObj *" "&Task_Type"
1812 [clinic start generated code]*/
1813 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/
1814 
1815 static int task_call_step_soon(TaskObj *, PyObject *);
1816 static PyObject * task_wakeup(TaskObj *, PyObject *);
1817 static PyObject * task_step(TaskObj *, PyObject *);
1818 
1819 /* ----- Task._step wrapper */
1820 
1821 static int
TaskStepMethWrapper_clear(TaskStepMethWrapper * o)1822 TaskStepMethWrapper_clear(TaskStepMethWrapper *o)
1823 {
1824     Py_CLEAR(o->sw_task);
1825     Py_CLEAR(o->sw_arg);
1826     return 0;
1827 }
1828 
1829 static void
TaskStepMethWrapper_dealloc(TaskStepMethWrapper * o)1830 TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o)
1831 {
1832     PyObject_GC_UnTrack(o);
1833     (void)TaskStepMethWrapper_clear(o);
1834     Py_TYPE(o)->tp_free(o);
1835 }
1836 
1837 static PyObject *
TaskStepMethWrapper_call(TaskStepMethWrapper * o,PyObject * args,PyObject * kwds)1838 TaskStepMethWrapper_call(TaskStepMethWrapper *o,
1839                          PyObject *args, PyObject *kwds)
1840 {
1841     if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
1842         PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments");
1843         return NULL;
1844     }
1845     if (args != NULL && PyTuple_GET_SIZE(args) != 0) {
1846         PyErr_SetString(PyExc_TypeError, "function takes no positional arguments");
1847         return NULL;
1848     }
1849     return task_step(o->sw_task, o->sw_arg);
1850 }
1851 
1852 static int
TaskStepMethWrapper_traverse(TaskStepMethWrapper * o,visitproc visit,void * arg)1853 TaskStepMethWrapper_traverse(TaskStepMethWrapper *o,
1854                              visitproc visit, void *arg)
1855 {
1856     Py_VISIT(o->sw_task);
1857     Py_VISIT(o->sw_arg);
1858     return 0;
1859 }
1860 
1861 static PyObject *
TaskStepMethWrapper_get___self__(TaskStepMethWrapper * o,void * Py_UNUSED (ignored))1862 TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored))
1863 {
1864     if (o->sw_task) {
1865         Py_INCREF(o->sw_task);
1866         return (PyObject*)o->sw_task;
1867     }
1868     Py_RETURN_NONE;
1869 }
1870 
1871 static PyGetSetDef TaskStepMethWrapper_getsetlist[] = {
1872     {"__self__", (getter)TaskStepMethWrapper_get___self__, NULL, NULL},
1873     {NULL} /* Sentinel */
1874 };
1875 
1876 static PyTypeObject TaskStepMethWrapper_Type = {
1877     PyVarObject_HEAD_INIT(NULL, 0)
1878     "TaskStepMethWrapper",
1879     .tp_basicsize = sizeof(TaskStepMethWrapper),
1880     .tp_itemsize = 0,
1881     .tp_getset = TaskStepMethWrapper_getsetlist,
1882     .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc,
1883     .tp_call = (ternaryfunc)TaskStepMethWrapper_call,
1884     .tp_getattro = PyObject_GenericGetAttr,
1885     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1886     .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse,
1887     .tp_clear = (inquiry)TaskStepMethWrapper_clear,
1888 };
1889 
1890 static PyObject *
TaskStepMethWrapper_new(TaskObj * task,PyObject * arg)1891 TaskStepMethWrapper_new(TaskObj *task, PyObject *arg)
1892 {
1893     TaskStepMethWrapper *o;
1894     o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type);
1895     if (o == NULL) {
1896         return NULL;
1897     }
1898 
1899     Py_INCREF(task);
1900     o->sw_task = task;
1901 
1902     Py_XINCREF(arg);
1903     o->sw_arg = arg;
1904 
1905     PyObject_GC_Track(o);
1906     return (PyObject*) o;
1907 }
1908 
1909 /* ----- Task._wakeup implementation */
1910 
1911 static  PyMethodDef TaskWakeupDef = {
1912     "task_wakeup",
1913     (PyCFunction)task_wakeup,
1914     METH_O,
1915     NULL
1916 };
1917 
1918 /* ----- Task introspection helpers */
1919 
1920 static int
register_task(PyObject * task)1921 register_task(PyObject *task)
1922 {
1923     _Py_IDENTIFIER(add);
1924 
1925     PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks,
1926                                                  &PyId_add, task);
1927     if (res == NULL) {
1928         return -1;
1929     }
1930     Py_DECREF(res);
1931     return 0;
1932 }
1933 
1934 
1935 static int
unregister_task(PyObject * task)1936 unregister_task(PyObject *task)
1937 {
1938     _Py_IDENTIFIER(discard);
1939 
1940     PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks,
1941                                                  &PyId_discard, task);
1942     if (res == NULL) {
1943         return -1;
1944     }
1945     Py_DECREF(res);
1946     return 0;
1947 }
1948 
1949 
1950 static int
enter_task(PyObject * loop,PyObject * task)1951 enter_task(PyObject *loop, PyObject *task)
1952 {
1953     PyObject *item;
1954     Py_hash_t hash;
1955     hash = PyObject_Hash(loop);
1956     if (hash == -1) {
1957         return -1;
1958     }
1959     item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash);
1960     if (item != NULL) {
1961         Py_INCREF(item);
1962         PyErr_Format(
1963             PyExc_RuntimeError,
1964             "Cannot enter into task %R while another " \
1965             "task %R is being executed.",
1966             task, item, NULL);
1967         Py_DECREF(item);
1968         return -1;
1969     }
1970     if (PyErr_Occurred()) {
1971         return -1;
1972     }
1973     return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash);
1974 }
1975 
1976 
1977 static int
leave_task(PyObject * loop,PyObject * task)1978 leave_task(PyObject *loop, PyObject *task)
1979 /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/
1980 {
1981     PyObject *item;
1982     Py_hash_t hash;
1983     hash = PyObject_Hash(loop);
1984     if (hash == -1) {
1985         return -1;
1986     }
1987     item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash);
1988     if (item != task) {
1989         if (item == NULL) {
1990             /* Not entered, replace with None */
1991             item = Py_None;
1992         }
1993         PyErr_Format(
1994             PyExc_RuntimeError,
1995             "Leaving task %R does not match the current task %R.",
1996             task, item, NULL);
1997         return -1;
1998     }
1999     return _PyDict_DelItem_KnownHash(current_tasks, loop, hash);
2000 }
2001 
2002 /* ----- Task */
2003 
2004 /*[clinic input]
2005 _asyncio.Task.__init__
2006 
2007     coro: object
2008     *
2009     loop: object = None
2010     name: object = None
2011 
2012 A coroutine wrapped in a Future.
2013 [clinic start generated code]*/
2014 
2015 static int
_asyncio_Task___init___impl(TaskObj * self,PyObject * coro,PyObject * loop,PyObject * name)2016 _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
2017                             PyObject *name)
2018 /*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/
2019 {
2020     if (future_init((FutureObj*)self, loop)) {
2021         return -1;
2022     }
2023 
2024     int is_coro = is_coroutine(coro);
2025     if (is_coro == -1) {
2026         return -1;
2027     }
2028     if (is_coro == 0) {
2029         self->task_log_destroy_pending = 0;
2030         PyErr_Format(PyExc_TypeError,
2031                      "a coroutine was expected, got %R",
2032                      coro, NULL);
2033         return -1;
2034     }
2035 
2036     Py_XSETREF(self->task_context, PyContext_CopyCurrent());
2037     if (self->task_context == NULL) {
2038         return -1;
2039     }
2040 
2041     Py_CLEAR(self->task_fut_waiter);
2042     self->task_must_cancel = 0;
2043     self->task_log_destroy_pending = 1;
2044     Py_INCREF(coro);
2045     Py_XSETREF(self->task_coro, coro);
2046 
2047     if (name == Py_None) {
2048         name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter);
2049     } else if (!PyUnicode_CheckExact(name)) {
2050         name = PyObject_Str(name);
2051     } else {
2052         Py_INCREF(name);
2053     }
2054     Py_XSETREF(self->task_name, name);
2055     if (self->task_name == NULL) {
2056         return -1;
2057     }
2058 
2059     if (task_call_step_soon(self, NULL)) {
2060         return -1;
2061     }
2062     return register_task((PyObject*)self);
2063 }
2064 
2065 static int
TaskObj_clear(TaskObj * task)2066 TaskObj_clear(TaskObj *task)
2067 {
2068     (void)FutureObj_clear((FutureObj*) task);
2069     Py_CLEAR(task->task_context);
2070     Py_CLEAR(task->task_coro);
2071     Py_CLEAR(task->task_name);
2072     Py_CLEAR(task->task_fut_waiter);
2073     return 0;
2074 }
2075 
2076 static int
TaskObj_traverse(TaskObj * task,visitproc visit,void * arg)2077 TaskObj_traverse(TaskObj *task, visitproc visit, void *arg)
2078 {
2079     Py_VISIT(task->task_context);
2080     Py_VISIT(task->task_coro);
2081     Py_VISIT(task->task_name);
2082     Py_VISIT(task->task_fut_waiter);
2083     (void)FutureObj_traverse((FutureObj*) task, visit, arg);
2084     return 0;
2085 }
2086 
2087 static PyObject *
TaskObj_get_log_destroy_pending(TaskObj * task,void * Py_UNUSED (ignored))2088 TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored))
2089 {
2090     if (task->task_log_destroy_pending) {
2091         Py_RETURN_TRUE;
2092     }
2093     else {
2094         Py_RETURN_FALSE;
2095     }
2096 }
2097 
2098 static int
TaskObj_set_log_destroy_pending(TaskObj * task,PyObject * val,void * Py_UNUSED (ignored))2099 TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored))
2100 {
2101     if (val == NULL) {
2102         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
2103         return -1;
2104     }
2105     int is_true = PyObject_IsTrue(val);
2106     if (is_true < 0) {
2107         return -1;
2108     }
2109     task->task_log_destroy_pending = is_true;
2110     return 0;
2111 }
2112 
2113 static PyObject *
TaskObj_get_must_cancel(TaskObj * task,void * Py_UNUSED (ignored))2114 TaskObj_get_must_cancel(TaskObj *task, void *Py_UNUSED(ignored))
2115 {
2116     if (task->task_must_cancel) {
2117         Py_RETURN_TRUE;
2118     }
2119     else {
2120         Py_RETURN_FALSE;
2121     }
2122 }
2123 
2124 static PyObject *
TaskObj_get_coro(TaskObj * task,void * Py_UNUSED (ignored))2125 TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored))
2126 {
2127     if (task->task_coro) {
2128         Py_INCREF(task->task_coro);
2129         return task->task_coro;
2130     }
2131 
2132     Py_RETURN_NONE;
2133 }
2134 
2135 static PyObject *
TaskObj_get_fut_waiter(TaskObj * task,void * Py_UNUSED (ignored))2136 TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored))
2137 {
2138     if (task->task_fut_waiter) {
2139         Py_INCREF(task->task_fut_waiter);
2140         return task->task_fut_waiter;
2141     }
2142 
2143     Py_RETURN_NONE;
2144 }
2145 
2146 /*[clinic input]
2147 _asyncio.Task._make_cancelled_error
2148 
2149 Create the CancelledError to raise if the Task is cancelled.
2150 
2151 This should only be called once when handling a cancellation since
2152 it erases the context exception value.
2153 [clinic start generated code]*/
2154 
2155 static PyObject *
_asyncio_Task__make_cancelled_error_impl(TaskObj * self)2156 _asyncio_Task__make_cancelled_error_impl(TaskObj *self)
2157 /*[clinic end generated code: output=55a819e8b4276fab input=52c0e32de8e2f840]*/
2158 {
2159     FutureObj *fut = (FutureObj*)self;
2160     return _asyncio_Future__make_cancelled_error_impl(fut);
2161 }
2162 
2163 
2164 /*[clinic input]
2165 _asyncio.Task._repr_info
2166 [clinic start generated code]*/
2167 
2168 static PyObject *
_asyncio_Task__repr_info_impl(TaskObj * self)2169 _asyncio_Task__repr_info_impl(TaskObj *self)
2170 /*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/
2171 {
2172     return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self);
2173 }
2174 
2175 /*[clinic input]
2176 _asyncio.Task.cancel
2177 
2178     msg: object = None
2179 
2180 Request that this task cancel itself.
2181 
2182 This arranges for a CancelledError to be thrown into the
2183 wrapped coroutine on the next cycle through the event loop.
2184 The coroutine then has a chance to clean up or even deny
2185 the request using try/except/finally.
2186 
2187 Unlike Future.cancel, this does not guarantee that the
2188 task will be cancelled: the exception might be caught and
2189 acted upon, delaying cancellation of the task or preventing
2190 cancellation completely.  The task may also return a value or
2191 raise a different exception.
2192 
2193 Immediately after this method is called, Task.cancelled() will
2194 not return True (unless the task was already cancelled).  A
2195 task will be marked as cancelled when the wrapped coroutine
2196 terminates with a CancelledError exception (even if cancel()
2197 was not called).
2198 [clinic start generated code]*/
2199 
2200 static PyObject *
_asyncio_Task_cancel_impl(TaskObj * self,PyObject * msg)2201 _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
2202 /*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00]*/
2203 {
2204     self->task_log_tb = 0;
2205 
2206     if (self->task_state != STATE_PENDING) {
2207         Py_RETURN_FALSE;
2208     }
2209 
2210     if (self->task_fut_waiter) {
2211         PyObject *res;
2212         int is_true;
2213 
2214         res = _PyObject_CallMethodIdOneArg(self->task_fut_waiter,
2215                                            &PyId_cancel, msg);
2216         if (res == NULL) {
2217             return NULL;
2218         }
2219 
2220         is_true = PyObject_IsTrue(res);
2221         Py_DECREF(res);
2222         if (is_true < 0) {
2223             return NULL;
2224         }
2225 
2226         if (is_true) {
2227             Py_RETURN_TRUE;
2228         }
2229     }
2230 
2231     self->task_must_cancel = 1;
2232     Py_XINCREF(msg);
2233     Py_XSETREF(self->task_cancel_msg, msg);
2234     Py_RETURN_TRUE;
2235 }
2236 
2237 /*[clinic input]
2238 _asyncio.Task.get_stack
2239 
2240     *
2241     limit: object = None
2242 
2243 Return the list of stack frames for this task's coroutine.
2244 
2245 If the coroutine is not done, this returns the stack where it is
2246 suspended.  If the coroutine has completed successfully or was
2247 cancelled, this returns an empty list.  If the coroutine was
2248 terminated by an exception, this returns the list of traceback
2249 frames.
2250 
2251 The frames are always ordered from oldest to newest.
2252 
2253 The optional limit gives the maximum number of frames to
2254 return; by default all available frames are returned.  Its
2255 meaning differs depending on whether a stack or a traceback is
2256 returned: the newest frames of a stack are returned, but the
2257 oldest frames of a traceback are returned.  (This matches the
2258 behavior of the traceback module.)
2259 
2260 For reasons beyond our control, only one stack frame is
2261 returned for a suspended coroutine.
2262 [clinic start generated code]*/
2263 
2264 static PyObject *
_asyncio_Task_get_stack_impl(TaskObj * self,PyObject * limit)2265 _asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit)
2266 /*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/
2267 {
2268     return PyObject_CallFunctionObjArgs(
2269         asyncio_task_get_stack_func, self, limit, NULL);
2270 }
2271 
2272 /*[clinic input]
2273 _asyncio.Task.print_stack
2274 
2275     *
2276     limit: object = None
2277     file: object = None
2278 
2279 Print the stack or traceback for this task's coroutine.
2280 
2281 This produces output similar to that of the traceback module,
2282 for the frames retrieved by get_stack().  The limit argument
2283 is passed to get_stack().  The file argument is an I/O stream
2284 to which the output is written; by default output is written
2285 to sys.stderr.
2286 [clinic start generated code]*/
2287 
2288 static PyObject *
_asyncio_Task_print_stack_impl(TaskObj * self,PyObject * limit,PyObject * file)2289 _asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit,
2290                                PyObject *file)
2291 /*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/
2292 {
2293     return PyObject_CallFunctionObjArgs(
2294         asyncio_task_print_stack_func, self, limit, file, NULL);
2295 }
2296 
2297 /*[clinic input]
2298 _asyncio.Task.set_result
2299 
2300     result: object
2301     /
2302 [clinic start generated code]*/
2303 
2304 static PyObject *
_asyncio_Task_set_result(TaskObj * self,PyObject * result)2305 _asyncio_Task_set_result(TaskObj *self, PyObject *result)
2306 /*[clinic end generated code: output=1dcae308bfcba318 input=9d1a00c07be41bab]*/
2307 {
2308     PyErr_SetString(PyExc_RuntimeError,
2309                     "Task does not support set_result operation");
2310     return NULL;
2311 }
2312 
2313 /*[clinic input]
2314 _asyncio.Task.set_exception
2315 
2316     exception: object
2317     /
2318 [clinic start generated code]*/
2319 
2320 static PyObject *
_asyncio_Task_set_exception(TaskObj * self,PyObject * exception)2321 _asyncio_Task_set_exception(TaskObj *self, PyObject *exception)
2322 /*[clinic end generated code: output=bc377fc28067303d input=9a8f65c83dcf893a]*/
2323 {
2324     PyErr_SetString(PyExc_RuntimeError,
2325                     "Task does not support set_exception operation");
2326     return NULL;
2327 }
2328 
2329 /*[clinic input]
2330 _asyncio.Task.get_coro
2331 [clinic start generated code]*/
2332 
2333 static PyObject *
_asyncio_Task_get_coro_impl(TaskObj * self)2334 _asyncio_Task_get_coro_impl(TaskObj *self)
2335 /*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/
2336 {
2337     Py_INCREF(self->task_coro);
2338     return self->task_coro;
2339 }
2340 
2341 /*[clinic input]
2342 _asyncio.Task.get_name
2343 [clinic start generated code]*/
2344 
2345 static PyObject *
_asyncio_Task_get_name_impl(TaskObj * self)2346 _asyncio_Task_get_name_impl(TaskObj *self)
2347 /*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/
2348 {
2349     if (self->task_name) {
2350         Py_INCREF(self->task_name);
2351         return self->task_name;
2352     }
2353 
2354     Py_RETURN_NONE;
2355 }
2356 
2357 /*[clinic input]
2358 _asyncio.Task.set_name
2359 
2360     value: object
2361     /
2362 [clinic start generated code]*/
2363 
2364 static PyObject *
_asyncio_Task_set_name(TaskObj * self,PyObject * value)2365 _asyncio_Task_set_name(TaskObj *self, PyObject *value)
2366 /*[clinic end generated code: output=138a8d51e32057d6 input=a8359b6e65f8fd31]*/
2367 {
2368     if (!PyUnicode_CheckExact(value)) {
2369         value = PyObject_Str(value);
2370         if (value == NULL) {
2371             return NULL;
2372         }
2373     } else {
2374         Py_INCREF(value);
2375     }
2376 
2377     Py_XSETREF(self->task_name, value);
2378     Py_RETURN_NONE;
2379 }
2380 
2381 static void
TaskObj_finalize(TaskObj * task)2382 TaskObj_finalize(TaskObj *task)
2383 {
2384     _Py_IDENTIFIER(call_exception_handler);
2385     _Py_IDENTIFIER(task);
2386     _Py_IDENTIFIER(message);
2387     _Py_IDENTIFIER(source_traceback);
2388 
2389     PyObject *context;
2390     PyObject *message = NULL;
2391     PyObject *func;
2392     PyObject *error_type, *error_value, *error_traceback;
2393 
2394     if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
2395         goto done;
2396     }
2397 
2398     /* Save the current exception, if any. */
2399     PyErr_Fetch(&error_type, &error_value, &error_traceback);
2400 
2401     context = PyDict_New();
2402     if (context == NULL) {
2403         goto finally;
2404     }
2405 
2406     message = PyUnicode_FromString("Task was destroyed but it is pending!");
2407     if (message == NULL) {
2408         goto finally;
2409     }
2410 
2411     if (_PyDict_SetItemId(context, &PyId_message, message) < 0 ||
2412         _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0)
2413     {
2414         goto finally;
2415     }
2416 
2417     if (task->task_source_tb != NULL) {
2418         if (_PyDict_SetItemId(context, &PyId_source_traceback,
2419                               task->task_source_tb) < 0)
2420         {
2421             goto finally;
2422         }
2423     }
2424 
2425     func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler);
2426     if (func != NULL) {
2427         PyObject *res = PyObject_CallOneArg(func, context);
2428         if (res == NULL) {
2429             PyErr_WriteUnraisable(func);
2430         }
2431         else {
2432             Py_DECREF(res);
2433         }
2434         Py_DECREF(func);
2435     }
2436 
2437 finally:
2438     Py_XDECREF(context);
2439     Py_XDECREF(message);
2440 
2441     /* Restore the saved exception. */
2442     PyErr_Restore(error_type, error_value, error_traceback);
2443 
2444 done:
2445     FutureObj_finalize((FutureObj*)task);
2446 }
2447 
2448 static PyObject *
task_cls_getitem(PyObject * cls,PyObject * type)2449 task_cls_getitem(PyObject *cls, PyObject *type)
2450 {
2451     Py_INCREF(cls);
2452     return cls;
2453 }
2454 
2455 static void TaskObj_dealloc(PyObject *);  /* Needs Task_CheckExact */
2456 
2457 static PyMethodDef TaskType_methods[] = {
2458     _ASYNCIO_FUTURE_RESULT_METHODDEF
2459     _ASYNCIO_FUTURE_EXCEPTION_METHODDEF
2460     _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF
2461     _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF
2462     _ASYNCIO_FUTURE_CANCELLED_METHODDEF
2463     _ASYNCIO_FUTURE_DONE_METHODDEF
2464     _ASYNCIO_TASK_SET_RESULT_METHODDEF
2465     _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF
2466     _ASYNCIO_TASK_CANCEL_METHODDEF
2467     _ASYNCIO_TASK_GET_STACK_METHODDEF
2468     _ASYNCIO_TASK_PRINT_STACK_METHODDEF
2469     _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF
2470     _ASYNCIO_TASK__REPR_INFO_METHODDEF
2471     _ASYNCIO_TASK_GET_NAME_METHODDEF
2472     _ASYNCIO_TASK_SET_NAME_METHODDEF
2473     _ASYNCIO_TASK_GET_CORO_METHODDEF
2474     {"__class_getitem__", task_cls_getitem, METH_O|METH_CLASS, NULL},
2475     {NULL, NULL}        /* Sentinel */
2476 };
2477 
2478 static PyGetSetDef TaskType_getsetlist[] = {
2479     FUTURE_COMMON_GETSETLIST
2480     {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending,
2481                              (setter)TaskObj_set_log_destroy_pending, NULL},
2482     {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL},
2483     {"_coro", (getter)TaskObj_get_coro, NULL, NULL},
2484     {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL},
2485     {NULL} /* Sentinel */
2486 };
2487 
2488 static PyTypeObject TaskType = {
2489     PyVarObject_HEAD_INIT(NULL, 0)
2490     "_asyncio.Task",
2491     sizeof(TaskObj),                       /* tp_basicsize */
2492     .tp_base = &FutureType,
2493     .tp_dealloc = TaskObj_dealloc,
2494     .tp_as_async = &FutureType_as_async,
2495     .tp_repr = (reprfunc)FutureObj_repr,
2496     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
2497     .tp_doc = _asyncio_Task___init____doc__,
2498     .tp_traverse = (traverseproc)TaskObj_traverse,
2499     .tp_clear = (inquiry)TaskObj_clear,
2500     .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist),
2501     .tp_iter = (getiterfunc)future_new_iter,
2502     .tp_methods = TaskType_methods,
2503     .tp_getset = TaskType_getsetlist,
2504     .tp_dictoffset = offsetof(TaskObj, dict),
2505     .tp_init = (initproc)_asyncio_Task___init__,
2506     .tp_new = PyType_GenericNew,
2507     .tp_finalize = (destructor)TaskObj_finalize,
2508 };
2509 
2510 static void
TaskObj_dealloc(PyObject * self)2511 TaskObj_dealloc(PyObject *self)
2512 {
2513     TaskObj *task = (TaskObj *)self;
2514 
2515     if (Task_CheckExact(self)) {
2516         /* When fut is subclass of Task, finalizer is called from
2517          * subtype_dealloc.
2518          */
2519         if (PyObject_CallFinalizerFromDealloc(self) < 0) {
2520             // resurrected.
2521             return;
2522         }
2523     }
2524 
2525     PyObject_GC_UnTrack(self);
2526 
2527     if (task->task_weakreflist != NULL) {
2528         PyObject_ClearWeakRefs(self);
2529     }
2530 
2531     (void)TaskObj_clear(task);
2532     Py_TYPE(task)->tp_free(task);
2533 }
2534 
2535 static int
task_call_step_soon(TaskObj * task,PyObject * arg)2536 task_call_step_soon(TaskObj *task, PyObject *arg)
2537 {
2538     PyObject *cb = TaskStepMethWrapper_new(task, arg);
2539     if (cb == NULL) {
2540         return -1;
2541     }
2542 
2543     int ret = call_soon(task->task_loop, cb, NULL, task->task_context);
2544     Py_DECREF(cb);
2545     return ret;
2546 }
2547 
2548 static PyObject *
task_set_error_soon(TaskObj * task,PyObject * et,const char * format,...)2549 task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...)
2550 {
2551     PyObject* msg;
2552 
2553     va_list vargs;
2554 #ifdef HAVE_STDARG_PROTOTYPES
2555     va_start(vargs, format);
2556 #else
2557     va_start(vargs);
2558 #endif
2559     msg = PyUnicode_FromFormatV(format, vargs);
2560     va_end(vargs);
2561 
2562     if (msg == NULL) {
2563         return NULL;
2564     }
2565 
2566     PyObject *e = PyObject_CallOneArg(et, msg);
2567     Py_DECREF(msg);
2568     if (e == NULL) {
2569         return NULL;
2570     }
2571 
2572     if (task_call_step_soon(task, e) == -1) {
2573         Py_DECREF(e);
2574         return NULL;
2575     }
2576 
2577     Py_DECREF(e);
2578     Py_RETURN_NONE;
2579 }
2580 
2581 static inline int
gen_status_from_result(PyObject ** result)2582 gen_status_from_result(PyObject **result)
2583 {
2584     if (*result != NULL) {
2585         return PYGEN_NEXT;
2586     }
2587     if (_PyGen_FetchStopIterationValue(result) == 0) {
2588         return PYGEN_RETURN;
2589     }
2590 
2591     assert(PyErr_Occurred());
2592     return PYGEN_ERROR;
2593 }
2594 
2595 static PyObject *
task_step_impl(TaskObj * task,PyObject * exc)2596 task_step_impl(TaskObj *task, PyObject *exc)
2597 {
2598     int res;
2599     int clear_exc = 0;
2600     PyObject *result = NULL;
2601     PyObject *coro;
2602     PyObject *o;
2603 
2604     if (task->task_state != STATE_PENDING) {
2605         PyErr_Format(asyncio_InvalidStateError,
2606                      "_step(): already done: %R %R",
2607                      task,
2608                      exc ? exc : Py_None);
2609         goto fail;
2610     }
2611 
2612     if (task->task_must_cancel) {
2613         assert(exc != Py_None);
2614 
2615         if (exc) {
2616             /* Check if exc is a CancelledError */
2617             res = PyObject_IsInstance(exc, asyncio_CancelledError);
2618             if (res == -1) {
2619                 /* An error occurred, abort */
2620                 goto fail;
2621             }
2622             if (res == 0) {
2623                 /* exc is not CancelledError; reset it to NULL */
2624                 exc = NULL;
2625             }
2626         }
2627 
2628         if (!exc) {
2629             /* exc was not a CancelledError */
2630             exc = create_cancelled_error(task->task_cancel_msg);
2631 
2632             if (!exc) {
2633                 goto fail;
2634             }
2635             clear_exc = 1;
2636         }
2637 
2638         task->task_must_cancel = 0;
2639     }
2640 
2641     Py_CLEAR(task->task_fut_waiter);
2642 
2643     coro = task->task_coro;
2644     if (coro == NULL) {
2645         PyErr_SetString(PyExc_RuntimeError, "uninitialized Task object");
2646         if (clear_exc) {
2647             /* We created 'exc' during this call */
2648             Py_DECREF(exc);
2649         }
2650         return NULL;
2651     }
2652 
2653     int gen_status = PYGEN_ERROR;
2654     if (exc == NULL) {
2655         gen_status = PyIter_Send(coro, Py_None, &result);
2656     }
2657     else {
2658         result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc);
2659         gen_status = gen_status_from_result(&result);
2660         if (clear_exc) {
2661             /* We created 'exc' during this call */
2662             Py_DECREF(exc);
2663         }
2664     }
2665 
2666     if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) {
2667         PyObject *et, *ev, *tb;
2668 
2669         if (result != NULL) {
2670             /* The error is StopIteration and that means that
2671                the underlying coroutine has resolved */
2672 
2673             PyObject *res;
2674             if (task->task_must_cancel) {
2675                 // Task is cancelled right before coro stops.
2676                 task->task_must_cancel = 0;
2677                 res = future_cancel((FutureObj*)task, task->task_cancel_msg);
2678             }
2679             else {
2680                 res = future_set_result((FutureObj*)task, result);
2681             }
2682 
2683             Py_DECREF(result);
2684 
2685             if (res == NULL) {
2686                 return NULL;
2687             }
2688             Py_DECREF(res);
2689             Py_RETURN_NONE;
2690         }
2691 
2692         if (PyErr_ExceptionMatches(asyncio_CancelledError)) {
2693             /* CancelledError */
2694             PyErr_Fetch(&et, &ev, &tb);
2695 
2696             FutureObj *fut = (FutureObj*)task;
2697             _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state;
2698             exc_state->exc_type = et;
2699             exc_state->exc_value = ev;
2700             exc_state->exc_traceback = tb;
2701 
2702             return future_cancel(fut, NULL);
2703         }
2704 
2705         /* Some other exception; pop it and call Task.set_exception() */
2706         PyErr_Fetch(&et, &ev, &tb);
2707 
2708         assert(et);
2709         if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
2710             PyErr_NormalizeException(&et, &ev, &tb);
2711         }
2712         if (tb != NULL) {
2713             PyException_SetTraceback(ev, tb);
2714         }
2715         o = future_set_exception((FutureObj*)task, ev);
2716         if (!o) {
2717             /* An exception in Task.set_exception() */
2718             Py_DECREF(et);
2719             Py_XDECREF(tb);
2720             Py_XDECREF(ev);
2721             goto fail;
2722         }
2723         assert(o == Py_None);
2724         Py_DECREF(o);
2725 
2726         if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) ||
2727             PyErr_GivenExceptionMatches(et, PyExc_SystemExit))
2728         {
2729             /* We've got a KeyboardInterrupt or a SystemError; re-raise it */
2730             PyErr_Restore(et, ev, tb);
2731             goto fail;
2732         }
2733 
2734         Py_DECREF(et);
2735         Py_XDECREF(tb);
2736         Py_XDECREF(ev);
2737 
2738         Py_RETURN_NONE;
2739     }
2740 
2741     if (result == (PyObject*)task) {
2742         /* We have a task that wants to await on itself */
2743         goto self_await;
2744     }
2745 
2746     /* Check if `result` is FutureObj or TaskObj (and not a subclass) */
2747     if (Future_CheckExact(result) || Task_CheckExact(result)) {
2748         PyObject *wrapper;
2749         PyObject *res;
2750         FutureObj *fut = (FutureObj*)result;
2751 
2752         /* Check if `result` future is attached to a different loop */
2753         if (fut->fut_loop != task->task_loop) {
2754             goto different_loop;
2755         }
2756 
2757         if (!fut->fut_blocking) {
2758             goto yield_insteadof_yf;
2759         }
2760 
2761         fut->fut_blocking = 0;
2762 
2763         /* result.add_done_callback(task._wakeup) */
2764         wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task);
2765         if (wrapper == NULL) {
2766             goto fail;
2767         }
2768         res = future_add_done_callback(
2769             (FutureObj*)result, wrapper, task->task_context);
2770         Py_DECREF(wrapper);
2771         if (res == NULL) {
2772             goto fail;
2773         }
2774         Py_DECREF(res);
2775 
2776         /* task._fut_waiter = result */
2777         task->task_fut_waiter = result;  /* no incref is necessary */
2778 
2779         if (task->task_must_cancel) {
2780             PyObject *r;
2781             int is_true;
2782             r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel,
2783                                              task->task_cancel_msg);
2784             if (r == NULL) {
2785                 return NULL;
2786             }
2787             is_true = PyObject_IsTrue(r);
2788             Py_DECREF(r);
2789             if (is_true < 0) {
2790                 return NULL;
2791             }
2792             else if (is_true) {
2793                 task->task_must_cancel = 0;
2794             }
2795         }
2796 
2797         Py_RETURN_NONE;
2798     }
2799 
2800     /* Check if `result` is None */
2801     if (result == Py_None) {
2802         /* Bare yield relinquishes control for one event loop iteration. */
2803         if (task_call_step_soon(task, NULL)) {
2804             goto fail;
2805         }
2806         return result;
2807     }
2808 
2809     /* Check if `result` is a Future-compatible object */
2810     if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) {
2811         goto fail;
2812     }
2813     if (o != NULL && o != Py_None) {
2814         /* `result` is a Future-compatible object */
2815         PyObject *wrapper;
2816         PyObject *res;
2817 
2818         int blocking = PyObject_IsTrue(o);
2819         Py_DECREF(o);
2820         if (blocking < 0) {
2821             goto fail;
2822         }
2823 
2824         /* Check if `result` future is attached to a different loop */
2825         PyObject *oloop = get_future_loop(result);
2826         if (oloop == NULL) {
2827             goto fail;
2828         }
2829         if (oloop != task->task_loop) {
2830             Py_DECREF(oloop);
2831             goto different_loop;
2832         }
2833         Py_DECREF(oloop);
2834 
2835         if (!blocking) {
2836             goto yield_insteadof_yf;
2837         }
2838 
2839         /* result._asyncio_future_blocking = False */
2840         if (_PyObject_SetAttrId(
2841                 result, &PyId__asyncio_future_blocking, Py_False) == -1) {
2842             goto fail;
2843         }
2844 
2845         wrapper = PyCFunction_New(&TaskWakeupDef, (PyObject *)task);
2846         if (wrapper == NULL) {
2847             goto fail;
2848         }
2849 
2850         /* result.add_done_callback(task._wakeup) */
2851         PyObject *add_cb = _PyObject_GetAttrId(
2852             result, &PyId_add_done_callback);
2853         if (add_cb == NULL) {
2854             Py_DECREF(wrapper);
2855             goto fail;
2856         }
2857         PyObject *stack[2];
2858         stack[0] = wrapper;
2859         stack[1] = (PyObject *)task->task_context;
2860         res = PyObject_Vectorcall(add_cb, stack, 1, context_kwname);
2861         Py_DECREF(add_cb);
2862         Py_DECREF(wrapper);
2863         if (res == NULL) {
2864             goto fail;
2865         }
2866         Py_DECREF(res);
2867 
2868         /* task._fut_waiter = result */
2869         task->task_fut_waiter = result;  /* no incref is necessary */
2870 
2871         if (task->task_must_cancel) {
2872             PyObject *r;
2873             int is_true;
2874             r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel,
2875                                              task->task_cancel_msg);
2876             if (r == NULL) {
2877                 return NULL;
2878             }
2879             is_true = PyObject_IsTrue(r);
2880             Py_DECREF(r);
2881             if (is_true < 0) {
2882                 return NULL;
2883             }
2884             else if (is_true) {
2885                 task->task_must_cancel = 0;
2886             }
2887         }
2888 
2889         Py_RETURN_NONE;
2890     }
2891 
2892     Py_XDECREF(o);
2893     /* Check if `result` is a generator */
2894     res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type);
2895     if (res < 0) {
2896         goto fail;
2897     }
2898     if (res) {
2899         /* `result` is a generator */
2900         o = task_set_error_soon(
2901             task, PyExc_RuntimeError,
2902             "yield was used instead of yield from for "
2903             "generator in task %R with %R", task, result);
2904         Py_DECREF(result);
2905         return o;
2906     }
2907 
2908     /* The `result` is none of the above */
2909     o = task_set_error_soon(
2910         task, PyExc_RuntimeError, "Task got bad yield: %R", result);
2911     Py_DECREF(result);
2912     return o;
2913 
2914 self_await:
2915     o = task_set_error_soon(
2916         task, PyExc_RuntimeError,
2917         "Task cannot await on itself: %R", task);
2918     Py_DECREF(result);
2919     return o;
2920 
2921 yield_insteadof_yf:
2922     o = task_set_error_soon(
2923         task, PyExc_RuntimeError,
2924         "yield was used instead of yield from "
2925         "in task %R with %R",
2926         task, result);
2927     Py_DECREF(result);
2928     return o;
2929 
2930 different_loop:
2931     o = task_set_error_soon(
2932         task, PyExc_RuntimeError,
2933         "Task %R got Future %R attached to a different loop",
2934         task, result);
2935     Py_DECREF(result);
2936     return o;
2937 
2938 fail:
2939     Py_XDECREF(result);
2940     return NULL;
2941 }
2942 
2943 static PyObject *
task_step(TaskObj * task,PyObject * exc)2944 task_step(TaskObj *task, PyObject *exc)
2945 {
2946     PyObject *res;
2947 
2948     if (enter_task(task->task_loop, (PyObject*)task) < 0) {
2949         return NULL;
2950     }
2951 
2952     res = task_step_impl(task, exc);
2953 
2954     if (res == NULL) {
2955         PyObject *et, *ev, *tb;
2956         PyErr_Fetch(&et, &ev, &tb);
2957         leave_task(task->task_loop, (PyObject*)task);
2958         _PyErr_ChainExceptions(et, ev, tb);
2959         return NULL;
2960     }
2961     else {
2962         if (leave_task(task->task_loop, (PyObject*)task) < 0) {
2963             Py_DECREF(res);
2964             return NULL;
2965         }
2966         else {
2967             return res;
2968         }
2969     }
2970 }
2971 
2972 static PyObject *
task_wakeup(TaskObj * task,PyObject * o)2973 task_wakeup(TaskObj *task, PyObject *o)
2974 {
2975     PyObject *et, *ev, *tb;
2976     PyObject *result;
2977     assert(o);
2978 
2979     if (Future_CheckExact(o) || Task_CheckExact(o)) {
2980         PyObject *fut_result = NULL;
2981         int res = future_get_result((FutureObj*)o, &fut_result);
2982 
2983         switch(res) {
2984         case -1:
2985             assert(fut_result == NULL);
2986             break; /* exception raised */
2987         case 0:
2988             Py_DECREF(fut_result);
2989             return task_step(task, NULL);
2990         default:
2991             assert(res == 1);
2992             result = task_step(task, fut_result);
2993             Py_DECREF(fut_result);
2994             return result;
2995         }
2996     }
2997     else {
2998         PyObject *fut_result = PyObject_CallMethod(o, "result", NULL);
2999         if (fut_result != NULL) {
3000             Py_DECREF(fut_result);
3001             return task_step(task, NULL);
3002         }
3003         /* exception raised */
3004     }
3005 
3006     PyErr_Fetch(&et, &ev, &tb);
3007     if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
3008         PyErr_NormalizeException(&et, &ev, &tb);
3009     }
3010 
3011     result = task_step(task, ev);
3012 
3013     Py_DECREF(et);
3014     Py_XDECREF(tb);
3015     Py_XDECREF(ev);
3016 
3017     return result;
3018 }
3019 
3020 
3021 /*********************** Functions **************************/
3022 
3023 
3024 /*[clinic input]
3025 _asyncio._get_running_loop
3026 
3027 Return the running event loop or None.
3028 
3029 This is a low-level function intended to be used by event loops.
3030 This function is thread-specific.
3031 
3032 [clinic start generated code]*/
3033 
3034 static PyObject *
_asyncio__get_running_loop_impl(PyObject * module)3035 _asyncio__get_running_loop_impl(PyObject *module)
3036 /*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/
3037 {
3038     PyObject *loop;
3039     if (get_running_loop(&loop)) {
3040         return NULL;
3041     }
3042     if (loop == NULL) {
3043         /* There's no currently running event loop */
3044         Py_RETURN_NONE;
3045     }
3046     return loop;
3047 }
3048 
3049 /*[clinic input]
3050 _asyncio._set_running_loop
3051     loop: 'O'
3052     /
3053 
3054 Set the running event loop.
3055 
3056 This is a low-level function intended to be used by event loops.
3057 This function is thread-specific.
3058 [clinic start generated code]*/
3059 
3060 static PyObject *
_asyncio__set_running_loop(PyObject * module,PyObject * loop)3061 _asyncio__set_running_loop(PyObject *module, PyObject *loop)
3062 /*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/
3063 {
3064     if (set_running_loop(loop)) {
3065         return NULL;
3066     }
3067     Py_RETURN_NONE;
3068 }
3069 
3070 /*[clinic input]
3071 _asyncio.get_event_loop
3072 
3073 Return an asyncio event loop.
3074 
3075 When called from a coroutine or a callback (e.g. scheduled with
3076 call_soon or similar API), this function will always return the
3077 running event loop.
3078 
3079 If there is no running event loop set, the function will return
3080 the result of `get_event_loop_policy().get_event_loop()` call.
3081 [clinic start generated code]*/
3082 
3083 static PyObject *
_asyncio_get_event_loop_impl(PyObject * module)3084 _asyncio_get_event_loop_impl(PyObject *module)
3085 /*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
3086 {
3087     return get_event_loop(1);
3088 }
3089 
3090 /*[clinic input]
3091 _asyncio._get_event_loop
3092     stacklevel: int = 3
3093 [clinic start generated code]*/
3094 
3095 static PyObject *
_asyncio__get_event_loop_impl(PyObject * module,int stacklevel)3096 _asyncio__get_event_loop_impl(PyObject *module, int stacklevel)
3097 /*[clinic end generated code: output=9c1d6d3c802e67c9 input=d17aebbd686f711d]*/
3098 {
3099     return get_event_loop(stacklevel-1);
3100 }
3101 
3102 /*[clinic input]
3103 _asyncio.get_running_loop
3104 
3105 Return the running event loop.  Raise a RuntimeError if there is none.
3106 
3107 This function is thread-specific.
3108 [clinic start generated code]*/
3109 
3110 static PyObject *
_asyncio_get_running_loop_impl(PyObject * module)3111 _asyncio_get_running_loop_impl(PyObject *module)
3112 /*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/
3113 {
3114     PyObject *loop;
3115     if (get_running_loop(&loop)) {
3116         return NULL;
3117     }
3118     if (loop == NULL) {
3119         /* There's no currently running event loop */
3120         PyErr_SetString(
3121             PyExc_RuntimeError, "no running event loop");
3122     }
3123     return loop;
3124 }
3125 
3126 /*[clinic input]
3127 _asyncio._register_task
3128 
3129     task: object
3130 
3131 Register a new task in asyncio as executed by loop.
3132 
3133 Returns None.
3134 [clinic start generated code]*/
3135 
3136 static PyObject *
_asyncio__register_task_impl(PyObject * module,PyObject * task)3137 _asyncio__register_task_impl(PyObject *module, PyObject *task)
3138 /*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/
3139 {
3140     if (register_task(task) < 0) {
3141         return NULL;
3142     }
3143     Py_RETURN_NONE;
3144 }
3145 
3146 
3147 /*[clinic input]
3148 _asyncio._unregister_task
3149 
3150     task: object
3151 
3152 Unregister a task.
3153 
3154 Returns None.
3155 [clinic start generated code]*/
3156 
3157 static PyObject *
_asyncio__unregister_task_impl(PyObject * module,PyObject * task)3158 _asyncio__unregister_task_impl(PyObject *module, PyObject *task)
3159 /*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/
3160 {
3161     if (unregister_task(task) < 0) {
3162         return NULL;
3163     }
3164     Py_RETURN_NONE;
3165 }
3166 
3167 
3168 /*[clinic input]
3169 _asyncio._enter_task
3170 
3171     loop: object
3172     task: object
3173 
3174 Enter into task execution or resume suspended task.
3175 
3176 Task belongs to loop.
3177 
3178 Returns None.
3179 [clinic start generated code]*/
3180 
3181 static PyObject *
_asyncio__enter_task_impl(PyObject * module,PyObject * loop,PyObject * task)3182 _asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task)
3183 /*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/
3184 {
3185     if (enter_task(loop, task) < 0) {
3186         return NULL;
3187     }
3188     Py_RETURN_NONE;
3189 }
3190 
3191 
3192 /*[clinic input]
3193 _asyncio._leave_task
3194 
3195     loop: object
3196     task: object
3197 
3198 Leave task execution or suspend a task.
3199 
3200 Task belongs to loop.
3201 
3202 Returns None.
3203 [clinic start generated code]*/
3204 
3205 static PyObject *
_asyncio__leave_task_impl(PyObject * module,PyObject * loop,PyObject * task)3206 _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task)
3207 /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/
3208 {
3209     if (leave_task(loop, task) < 0) {
3210         return NULL;
3211     }
3212     Py_RETURN_NONE;
3213 }
3214 
3215 
3216 /*********************** PyRunningLoopHolder ********************/
3217 
3218 
3219 static PyRunningLoopHolder *
new_running_loop_holder(PyObject * loop)3220 new_running_loop_holder(PyObject *loop)
3221 {
3222     PyRunningLoopHolder *rl = PyObject_New(
3223         PyRunningLoopHolder, &PyRunningLoopHolder_Type);
3224     if (rl == NULL) {
3225         return NULL;
3226     }
3227 
3228 #if defined(HAVE_GETPID) && !defined(MS_WINDOWS)
3229     rl->rl_pid = getpid();
3230 #endif
3231 
3232     Py_INCREF(loop);
3233     rl->rl_loop = loop;
3234 
3235     return rl;
3236 }
3237 
3238 
3239 static void
PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder * rl)3240 PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl)
3241 {
3242     if (cached_running_holder == (PyObject *)rl) {
3243         cached_running_holder = NULL;
3244     }
3245     Py_CLEAR(rl->rl_loop);
3246     PyObject_Free(rl);
3247 }
3248 
3249 
3250 static PyTypeObject PyRunningLoopHolder_Type = {
3251     PyVarObject_HEAD_INIT(NULL, 0)
3252     "_RunningLoopHolder",
3253     sizeof(PyRunningLoopHolder),
3254     .tp_getattro = PyObject_GenericGetAttr,
3255     .tp_flags = Py_TPFLAGS_DEFAULT,
3256     .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc,
3257 };
3258 
3259 
3260 /*********************** Module **************************/
3261 
3262 
3263 static void
module_free_freelists(void)3264 module_free_freelists(void)
3265 {
3266     PyObject *next;
3267     PyObject *current;
3268 
3269     next = (PyObject*) fi_freelist;
3270     while (next != NULL) {
3271         assert(fi_freelist_len > 0);
3272         fi_freelist_len--;
3273 
3274         current = next;
3275         next = (PyObject*) ((futureiterobject*) current)->future;
3276         PyObject_GC_Del(current);
3277     }
3278     assert(fi_freelist_len == 0);
3279     fi_freelist = NULL;
3280 }
3281 
3282 
3283 static void
module_free(void * m)3284 module_free(void *m)
3285 {
3286     Py_CLEAR(asyncio_mod);
3287     Py_CLEAR(traceback_extract_stack);
3288     Py_CLEAR(asyncio_future_repr_info_func);
3289     Py_CLEAR(asyncio_get_event_loop_policy);
3290     Py_CLEAR(asyncio_iscoroutine_func);
3291     Py_CLEAR(asyncio_task_get_stack_func);
3292     Py_CLEAR(asyncio_task_print_stack_func);
3293     Py_CLEAR(asyncio_task_repr_info_func);
3294     Py_CLEAR(asyncio_InvalidStateError);
3295     Py_CLEAR(asyncio_CancelledError);
3296 
3297     Py_CLEAR(all_tasks);
3298     Py_CLEAR(current_tasks);
3299     Py_CLEAR(iscoroutine_typecache);
3300 
3301     Py_CLEAR(context_kwname);
3302 
3303     module_free_freelists();
3304 
3305     module_initialized = 0;
3306 }
3307 
3308 static int
module_init(void)3309 module_init(void)
3310 {
3311     PyObject *module = NULL;
3312     if (module_initialized) {
3313         return 0;
3314     }
3315 
3316     asyncio_mod = PyImport_ImportModule("asyncio");
3317     if (asyncio_mod == NULL) {
3318         goto fail;
3319     }
3320 
3321     current_tasks = PyDict_New();
3322     if (current_tasks == NULL) {
3323         goto fail;
3324     }
3325 
3326     iscoroutine_typecache = PySet_New(NULL);
3327     if (iscoroutine_typecache == NULL) {
3328         goto fail;
3329     }
3330 
3331 
3332     context_kwname = Py_BuildValue("(s)", "context");
3333     if (context_kwname == NULL) {
3334         goto fail;
3335     }
3336 
3337 #define WITH_MOD(NAME) \
3338     Py_CLEAR(module); \
3339     module = PyImport_ImportModule(NAME); \
3340     if (module == NULL) { \
3341         goto fail; \
3342     }
3343 
3344 #define GET_MOD_ATTR(VAR, NAME) \
3345     VAR = PyObject_GetAttrString(module, NAME); \
3346     if (VAR == NULL) { \
3347         goto fail; \
3348     }
3349 
3350     WITH_MOD("asyncio.events")
3351     GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy")
3352 
3353     WITH_MOD("asyncio.base_futures")
3354     GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info")
3355 
3356     WITH_MOD("asyncio.exceptions")
3357     GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError")
3358     GET_MOD_ATTR(asyncio_CancelledError, "CancelledError")
3359 
3360     WITH_MOD("asyncio.base_tasks")
3361     GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info")
3362     GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack")
3363     GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack")
3364 
3365     WITH_MOD("asyncio.coroutines")
3366     GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine")
3367 
3368     WITH_MOD("traceback")
3369     GET_MOD_ATTR(traceback_extract_stack, "extract_stack")
3370 
3371     PyObject *weak_set;
3372     WITH_MOD("weakref")
3373     GET_MOD_ATTR(weak_set, "WeakSet");
3374     all_tasks = PyObject_CallNoArgs(weak_set);
3375     Py_CLEAR(weak_set);
3376     if (all_tasks == NULL) {
3377         goto fail;
3378     }
3379 
3380     module_initialized = 1;
3381     Py_DECREF(module);
3382     return 0;
3383 
3384 fail:
3385     Py_CLEAR(module);
3386     module_free(NULL);
3387     return -1;
3388 
3389 #undef WITH_MOD
3390 #undef GET_MOD_ATTR
3391 }
3392 
3393 PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
3394 
3395 static PyMethodDef asyncio_methods[] = {
3396     _ASYNCIO_GET_EVENT_LOOP_METHODDEF
3397     _ASYNCIO__GET_EVENT_LOOP_METHODDEF
3398     _ASYNCIO_GET_RUNNING_LOOP_METHODDEF
3399     _ASYNCIO__GET_RUNNING_LOOP_METHODDEF
3400     _ASYNCIO__SET_RUNNING_LOOP_METHODDEF
3401     _ASYNCIO__REGISTER_TASK_METHODDEF
3402     _ASYNCIO__UNREGISTER_TASK_METHODDEF
3403     _ASYNCIO__ENTER_TASK_METHODDEF
3404     _ASYNCIO__LEAVE_TASK_METHODDEF
3405     {NULL, NULL}
3406 };
3407 
3408 static struct PyModuleDef _asynciomodule = {
3409     PyModuleDef_HEAD_INIT,      /* m_base */
3410     "_asyncio",                 /* m_name */
3411     module_doc,                 /* m_doc */
3412     -1,                         /* m_size */
3413     asyncio_methods,            /* m_methods */
3414     NULL,                       /* m_slots */
3415     NULL,                       /* m_traverse */
3416     NULL,                       /* m_clear */
3417     (freefunc)module_free       /* m_free */
3418 };
3419 
3420 
3421 PyMODINIT_FUNC
PyInit__asyncio(void)3422 PyInit__asyncio(void)
3423 {
3424     if (module_init() < 0) {
3425         return NULL;
3426     }
3427     if (PyType_Ready(&FutureIterType) < 0) {
3428         return NULL;
3429     }
3430     if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) {
3431         return NULL;
3432     }
3433     if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) {
3434         return NULL;
3435     }
3436 
3437     PyObject *m = PyModule_Create(&_asynciomodule);
3438     if (m == NULL) {
3439         return NULL;
3440     }
3441 
3442     /* FutureType and TaskType are made ready by PyModule_AddType() calls below. */
3443     if (PyModule_AddType(m, &FutureType) < 0) {
3444         Py_DECREF(m);
3445         return NULL;
3446     }
3447 
3448     if (PyModule_AddType(m, &TaskType) < 0) {
3449         Py_DECREF(m);
3450         return NULL;
3451     }
3452 
3453     Py_INCREF(all_tasks);
3454     if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) {
3455         Py_DECREF(all_tasks);
3456         Py_DECREF(m);
3457         return NULL;
3458     }
3459 
3460     Py_INCREF(current_tasks);
3461     if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) {
3462         Py_DECREF(current_tasks);
3463         Py_DECREF(m);
3464         return NULL;
3465     }
3466 
3467     return m;
3468 }
3469