Skip to content

Commit 807cbef

Browse files
committed
core: wake Latch outside of lock.
Given: - thread A asleep in Latch._get_sleep() - thread B calling Latch.put() Previously, - B takes lock, - B wakes socket by dropping GIL and writing to it - A wakes from poll(), acquires GIL only to find Latch._lock is held - A drops GIL, sleeps on futex() for _lock - B wakes, acquires GIL, releases _lock - A wakes from futex(), acquires lock Now, - B takes lock, updates state, releases lock - B wakes socket by droppping GIL and writing to it - A wakes from poll(), acquires GIL and _lock - Everyone lives happily ever after.
1 parent 7e51a93 commit 807cbef

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

mitogen/core.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2489,17 +2489,20 @@ def put(self, obj=None):
24892489
raise LatchError()
24902490
self._queue.append(obj)
24912491

2492+
wsock = None
24922493
if self._waking < len(self._sleeping):
24932494
wsock, cookie = self._sleeping[self._waking]
24942495
self._waking += 1
24952496
_vv and IOLOG.debug('%r.put() -> waking wfd=%r',
24962497
self, wsock.fileno())
2497-
self._wake(wsock, cookie)
24982498
elif self.notify:
24992499
self.notify(self)
25002500
finally:
25012501
self._lock.release()
25022502

2503+
if wsock:
2504+
self._wake(wsock, cookie)
2505+
25032506
def _wake(self, wsock, cookie):
25042507
written, disconnected = io_op(os.write, wsock.fileno(), cookie)
25052508
assert written == len(cookie) and not disconnected

0 commit comments

Comments
 (0)