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