diff options
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r-- | Modules/_asynciomodule.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 0d6b21d..8847123 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -91,7 +91,7 @@ typedef struct { PyObject *task_context; int task_must_cancel; int task_log_destroy_pending; - int task_cancel_requested; + int task_num_cancels_requested; } TaskObj; typedef struct { @@ -2036,7 +2036,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; + self->task_num_cancels_requested = 0; Py_INCREF(coro); Py_XSETREF(self->task_coro, coro); @@ -2191,11 +2191,13 @@ not return True (unless the task was already cancelled). A task will be marked as cancelled when the wrapped coroutine terminates with a CancelledError exception (even if cancel() was not called). + +This also increases the task's count of cancellation requests. [clinic start generated code]*/ static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) -/*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00]*/ +/*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/ { self->task_log_tb = 0; @@ -2203,10 +2205,10 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) Py_RETURN_FALSE; } - if (self->task_cancel_requested) { + self->task_num_cancels_requested += 1; + if (self->task_num_cancels_requested > 1) { Py_RETURN_FALSE; } - self->task_cancel_requested = 1; if (self->task_fut_waiter) { PyObject *res; @@ -2238,51 +2240,40 @@ _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. +Return the count of the task's cancellation requests. -As long as this flag is set, further .cancel() calls will be ignored, -until .uncancel() is called to reset it. +This count is incremented when .cancel() is called +and may be decremented using .uncancel(). [clinic start generated code]*/ static PyObject * _asyncio_Task_cancelling_impl(TaskObj *self) -/*[clinic end generated code: output=803b3af96f917d7e input=c50e50f9c3ca4676]*/ +/*[clinic end generated code: output=803b3af96f917d7e input=b625224d310cbb17]*/ /*[clinic end generated code]*/ { - if (self->task_cancel_requested) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } + return PyLong_FromLong(self->task_num_cancels_requested); } /*[clinic input] _asyncio.Task.uncancel -Reset the flag returned by cancelling(). +Decrement the task's count of cancellation requests. 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. +Returns the remaining number of cancellation requests. [clinic start generated code]*/ static PyObject * _asyncio_Task_uncancel_impl(TaskObj *self) -/*[clinic end generated code: output=58184d236a817d3c input=5db95e28fcb6f7cd]*/ +/*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/ /*[clinic end generated code]*/ { - if (self->task_cancel_requested) { - self->task_cancel_requested = 0; - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; + if (self->task_num_cancels_requested > 0) { + self->task_num_cancels_requested -= 1; } + return PyLong_FromLong(self->task_num_cancels_requested); } /*[clinic input] |