LCOV - code coverage report
Current view: top level - Modules - _asynciomodule.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 1147 1362 84.2 %
Date: 2022-07-20 13:12:14 Functions: 110 111 99.1 %
Branches: 634 905 70.1 %

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

Generated by: LCOV version 1.14