]> git.ipfire.org Git - thirdparty/Python/cpython.git/commit
gh-114944: Fix race between `_PyParkingLot_Park` and `_PyParkingLot_UnparkAll` when...
authormpage <mpage@meta.com>
Mon, 5 Feb 2024 21:48:37 +0000 (13:48 -0800)
committerGitHub <noreply@github.com>
Mon, 5 Feb 2024 21:48:37 +0000 (13:48 -0800)
commitc32bae52904723d99e1f98e2ef54570268d86467
treea7c789d955c6a67cd49c93e75ea76b5205f45c55
parent652fbf88c4c422ff17fefd4dcb5e06b5c0e26e74
gh-114944: Fix race between `_PyParkingLot_Park` and `_PyParkingLot_UnparkAll` when handling interrupts (#114945)

Fix race between `_PyParkingLot_Park` and `_PyParkingLot_UnparkAll` when 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.
Misc/NEWS.d/next/Core and Builtins/2024-02-03-01-48-38.gh-issue-114944.4J5ELD.rst [new file with mode: 0644]
Python/parking_lot.c