summaryrefslogtreecommitdiffstats
path: root/Modules/_asynciomodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_asynciomodule.c')
-rw-r--r--Modules/_asynciomodule.c59
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