Right now the _start_task method may be subject to a context switch, if the pool size is limited and there is no room for the new task at this point:
|
await self._enough_room.acquire() |
Since the _start_task coroutine is itself scheduled in a task from TaskPool.apply, TaskPool._map, and SimpleTaskPool.start (by proxy of TaskPool._apply_spawner, TaskPool._arg_consumer, and SimpleTaskPool._start_num respectively), this can introduce a race condition:
The _start_task coroutine may still be awaiting the semaphore for enough room, while a cancel was already issued for the group it is assigned to or the entire pool. Cancellation right now only affects tasks in the _tasks_running dictionary. This means the _start_task call may still spawn a new task and add it to _tasks_running after it was supposedly cancelled.
Right now the
_start_taskmethod may be subject to a context switch, if the pool size is limited and there is no room for the new task at this point:asyncio-taskpool/src/asyncio_taskpool/pool.py
Line 395 in 27eb3bf
Since the
_start_taskcoroutine is itself scheduled in a task fromTaskPool.apply,TaskPool._map, andSimpleTaskPool.start(by proxy ofTaskPool._apply_spawner,TaskPool._arg_consumer, andSimpleTaskPool._start_numrespectively), this can introduce a race condition:The
_start_taskcoroutine may still be awaiting the semaphore for enough room, while acancelwas already issued for the group it is assigned to or the entire pool. Cancellation right now only affects tasks in the_tasks_runningdictionary. This means the_start_taskcall may still spawn a new task and add it to_tasks_runningafter it was supposedly cancelled.