Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix race between
_PyParkingLot_Park
and _PyParkingLot_UnparkAll
w…
…hen handling interrupts There is a potential race when `_PyParkingLot_UnparkAll` is executing in one thread and another thread is unblocked because of an interrupt in `_PyParkingLot_Park`. Consider the following scenario: 1. Thread T0 is blocked[^1] in `_PyParkingLot_Park` on address `A`. 2. Thread T1 executes `_PyParkingLot_UnparkAll` on address `A`. It finds the `wait_entry` for `T0` and unlinks[^2] its list node. 3. Immediately after (2), T0 is woken up due to an interrupt. It then segfaults trying to unlink[^3] the node that was previously unlinked in (2). To fix this we mark each waiter as unparking before releasing the bucket lock. `_PyParkingLot_Park` will wait to handle the coming wakeup, and not attempt to unlink the node, when this field is set. `_PyParkingLot_Unpark` does this already, presumably to handle this case. [^1]: https://github.com/python/cpython/blob/f35c7c070ca6b49c5d6a97be34e6c02f828f5873/Python/parking_lot.c#L303 [^2]: https://github.com/python/cpython/blob/f35c7c070ca6b49c5d6a97be34e6c02f828f5873/Python/parking_lot.c#L369 [^3]: https://github.com/python/cpython/blob/f35c7c070ca6b49c5d6a97be34e6c02f828f5873/Python/parking_lot.c#L320
- Loading branch information