@@ -91,7 +91,7 @@ typedef struct {
91
91
PyObject * task_context ;
92
92
int task_must_cancel ;
93
93
int task_log_destroy_pending ;
94
- int task_cancel_requested ;
94
+ int task_num_cancels_requested ;
95
95
} TaskObj ;
96
96
97
97
typedef struct {
@@ -2036,7 +2036,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
2036
2036
Py_CLEAR (self -> task_fut_waiter );
2037
2037
self -> task_must_cancel = 0 ;
2038
2038
self -> task_log_destroy_pending = 1 ;
2039
- self -> task_cancel_requested = 0 ;
2039
+ self -> task_num_cancels_requested = 0 ;
2040
2040
Py_INCREF (coro );
2041
2041
Py_XSETREF (self -> task_coro , coro );
2042
2042
@@ -2191,22 +2191,24 @@ not return True (unless the task was already cancelled). A
2191
2191
task will be marked as cancelled when the wrapped coroutine
2192
2192
terminates with a CancelledError exception (even if cancel()
2193
2193
was not called).
2194
+
2195
+ This also increases the task's count of cancellation requests.
2194
2196
[clinic start generated code]*/
2195
2197
2196
2198
static PyObject *
2197
2199
_asyncio_Task_cancel_impl (TaskObj * self , PyObject * msg )
2198
- /*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00 ]*/
2200
+ /*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783 ]*/
2199
2201
{
2200
2202
self -> task_log_tb = 0 ;
2201
2203
2202
2204
if (self -> task_state != STATE_PENDING ) {
2203
2205
Py_RETURN_FALSE ;
2204
2206
}
2205
2207
2206
- if (self -> task_cancel_requested ) {
2208
+ self -> task_num_cancels_requested += 1 ;
2209
+ if (self -> task_num_cancels_requested > 1 ) {
2207
2210
Py_RETURN_FALSE ;
2208
2211
}
2209
- self -> task_cancel_requested = 1 ;
2210
2212
2211
2213
if (self -> task_fut_waiter ) {
2212
2214
PyObject * res ;
@@ -2238,51 +2240,40 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
2238
2240
/*[clinic input]
2239
2241
_asyncio.Task.cancelling
2240
2242
2241
- Return True if the task is in the process of being cancelled.
2242
-
2243
- This is set once .cancel() is called
2244
- and remains set until .uncancel() is called.
2243
+ Return the count of the task's cancellation requests.
2245
2244
2246
- As long as this flag is set, further .cancel() calls will be ignored,
2247
- until .uncancel() is called to reset it .
2245
+ This count is incremented when .cancel() is called
2246
+ and may be decremented using .uncancel() .
2248
2247
[clinic start generated code]*/
2249
2248
2250
2249
static PyObject *
2251
2250
_asyncio_Task_cancelling_impl (TaskObj * self )
2252
- /*[clinic end generated code: output=803b3af96f917d7e input=c50e50f9c3ca4676 ]*/
2251
+ /*[clinic end generated code: output=803b3af96f917d7e input=b625224d310cbb17 ]*/
2253
2252
/*[clinic end generated code]*/
2254
2253
{
2255
- if (self -> task_cancel_requested ) {
2256
- Py_RETURN_TRUE ;
2257
- }
2258
- else {
2259
- Py_RETURN_FALSE ;
2260
- }
2254
+ return PyLong_FromLong (self -> task_num_cancels_requested );
2261
2255
}
2262
2256
2263
2257
/*[clinic input]
2264
2258
_asyncio.Task.uncancel
2265
2259
2266
- Reset the flag returned by cancelling() .
2260
+ Decrement the task's count of cancellation requests .
2267
2261
2268
2262
This should be used by tasks that catch CancelledError
2269
2263
and wish to continue indefinitely until they are cancelled again.
2270
2264
2271
- Returns the previous value of the flag .
2265
+ Returns the remaining number of cancellation requests .
2272
2266
[clinic start generated code]*/
2273
2267
2274
2268
static PyObject *
2275
2269
_asyncio_Task_uncancel_impl (TaskObj * self )
2276
- /*[clinic end generated code: output=58184d236a817d3c input=5db95e28fcb6f7cd ]*/
2270
+ /*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2 ]*/
2277
2271
/*[clinic end generated code]*/
2278
2272
{
2279
- if (self -> task_cancel_requested ) {
2280
- self -> task_cancel_requested = 0 ;
2281
- Py_RETURN_TRUE ;
2282
- }
2283
- else {
2284
- Py_RETURN_FALSE ;
2273
+ if (self -> task_num_cancels_requested > 0 ) {
2274
+ self -> task_num_cancels_requested -= 1 ;
2285
2275
}
2276
+ return PyLong_FromLong (self -> task_num_cancels_requested );
2286
2277
}
2287
2278
2288
2279
/*[clinic input]
0 commit comments