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