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