diff options
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r-- | Modules/_asynciomodule.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 72dbdb8..6725e2e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -91,6 +91,7 @@ typedef struct { PyObject *task_context; int task_must_cancel; int task_log_destroy_pending; + int task_cancel_requested; } TaskObj; typedef struct { @@ -2039,6 +2040,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, Py_CLEAR(self->task_fut_waiter); self->task_must_cancel = 0; self->task_log_destroy_pending = 1; + self->task_cancel_requested = 0; Py_INCREF(coro); Py_XSETREF(self->task_coro, coro); @@ -2205,6 +2207,11 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) Py_RETURN_FALSE; } + if (self->task_cancel_requested) { + Py_RETURN_FALSE; + } + self->task_cancel_requested = 1; + if (self->task_fut_waiter) { PyObject *res; int is_true; @@ -2233,6 +2240,56 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) } /*[clinic input] +_asyncio.Task.cancelling + +Return True if the task is in the process of being cancelled. + +This is set once .cancel() is called +and remains set until .uncancel() is called. + +As long as this flag is set, further .cancel() calls will be ignored, +until .uncancel() is called to reset it. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_cancelling_impl(TaskObj *self) +/*[clinic end generated code: output=803b3af96f917d7e input=c50e50f9c3ca4676]*/ +/*[clinic end generated code]*/ +{ + if (self->task_cancel_requested) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +/*[clinic input] +_asyncio.Task.uncancel + +Reset the flag returned by cancelling(). + +This should be used by tasks that catch CancelledError +and wish to continue indefinitely until they are cancelled again. + +Returns the previous value of the flag. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_uncancel_impl(TaskObj *self) +/*[clinic end generated code: output=58184d236a817d3c input=5db95e28fcb6f7cd]*/ +/*[clinic end generated code]*/ +{ + if (self->task_cancel_requested) { + self->task_cancel_requested = 0; + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +/*[clinic input] _asyncio.Task.get_stack * @@ -2455,6 +2512,8 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_SET_RESULT_METHODDEF _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF _ASYNCIO_TASK_CANCEL_METHODDEF + _ASYNCIO_TASK_CANCELLING_METHODDEF + _ASYNCIO_TASK_UNCANCEL_METHODDEF _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF |