You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3468 lines
88 KiB

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