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