8000 gh-125541: Make Ctrl-C interrupt `threading.Lock.acquire()` on Windows · colesbury/cpython@2c47487 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2c47487

Browse files
committed
pythongh-125541: Make Ctrl-C interrupt threading.Lock.acquire() on Windows
1 parent aac89b5 commit 2c47487

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

Doc/library/_thread.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ Lock objects have the following methods:
187187
.. versionchanged:: 3.2
188188
Lock acquires can now be interrupted by signals on POSIX.
189189

190+
.. versionchanged:: 3.14
191+
Lock acquires can now be interrupted by signals on Windows.
192+
190193

191194
.. method:: lock.release()
192195

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Pressing :kbd:`Ctrl-C` while blocked in :meth:`threading.Lock.acquire` now
2+
interrupts the function and raises a :exc:`KeyboardInterrupt` exception on
3+
Windows, similar to how it behaves on macOS and Linux.

Python/parking_lot.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,24 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout)
111111
millis = (DWORD) div;
112112
}
113113
}
114-
wait = WaitForSingleObjectEx(sema->platform_sem, millis, FALSE);
114+
115+
HANDLE sigint_event = _PyOS_SigintEvent();
116+
HANDLE handles[2] = {sema->platform_sem, sigint_event};
117+
wait = WaitForMultipleObjectsEx(2, handles, FALSE, millis, FALSE);
115118
if (wait == WAIT_OBJECT_0) {
116119
res = Py_PARK_OK;
117120
}
121+
else if (wait == WAIT_OBJECT_0 + 1) {
122+
ResetEvent(sigint_event);
123+
res = Py_PARK_INTR;
124+
}
118125
else if (wait == WAIT_TIMEOUT) {
6B60 119126
res = Py_PARK_TIMEOUT;
120127
}
121128
else {
122-
res = Py_PARK_INTR;
129+
_Py_FatalErrorFormat(__func__,
130+
"unexpected error from semaphore: %u (error: %u)",
131+
wait, GetLastError());
123132
}
124133
#elif defined(_Py_USE_SEMAPHORES)
125134
int err;

0 commit comments

Comments
 (0)
0