mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
gh-125541: Make Ctrl-C interrupt threading.Lock.acquire()
on Windows (#125546)
This commit is contained in:
parent
b454662921
commit
d8c8648161
4 changed files with 25 additions and 8 deletions
|
@ -187,6 +187,9 @@ Lock objects have the following methods:
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
Lock acquires can now be interrupted by signals on POSIX.
|
Lock acquires can now be interrupted by signals on POSIX.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.14
|
||||||
|
Lock acquires can now be interrupted by signals on Windows.
|
||||||
|
|
||||||
|
|
||||||
.. method:: lock.release()
|
.. method:: lock.release()
|
||||||
|
|
||||||
|
@ -219,12 +222,6 @@ In addition to these methods, lock objects can also be used via the
|
||||||
* Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is
|
* Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is
|
||||||
equivalent to calling :func:`_thread.exit`.
|
equivalent to calling :func:`_thread.exit`.
|
||||||
|
|
||||||
* It is platform-dependent whether the :meth:`~threading.Lock.acquire` method
|
|
||||||
on a lock can be interrupted (so that the :exc:`KeyboardInterrupt` exception
|
|
||||||
will happen immediately, rather than only after the lock has been acquired or
|
|
||||||
the operation has timed out). It can be interrupted on POSIX, but not on
|
|
||||||
Windows.
|
|
||||||
|
|
||||||
* When the main thread exits, it is system defined whether the other threads
|
* When the main thread exits, it is system defined whether the other threads
|
||||||
survive. On most systems, they are killed without executing
|
survive. On most systems, they are killed without executing
|
||||||
:keyword:`try` ... :keyword:`finally` clauses or executing object
|
:keyword:`try` ... :keyword:`finally` clauses or executing object
|
||||||
|
|
|
@ -567,6 +567,9 @@ All methods are executed atomically.
|
||||||
Lock acquisition can now be interrupted by signals on POSIX if the
|
Lock acquisition can now be interrupted by signals on POSIX if the
|
||||||
underlying threading implementation supports it.
|
underlying threading implementation supports it.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.14
|
||||||
|
Lock acquisition can now be interrupted by signals on Windows.
|
||||||
|
|
||||||
|
|
||||||
.. method:: release()
|
.. method:: release()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Pressing :kbd:`Ctrl-C` while blocked in :meth:`threading.Lock.acquire`,
|
||||||
|
:meth:`threading.RLock.acquire`, and :meth:`threading.Thread.join` now
|
||||||
|
interrupts the function call and raises a :exc:`KeyboardInterrupt` exception
|
||||||
|
on Windows, similar to how those functions behave on macOS and Linux.
|
|
@ -111,15 +111,28 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout)
|
||||||
millis = (DWORD) div;
|
millis = (DWORD) div;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wait = WaitForSingleObjectEx(sema->platform_sem, millis, FALSE);
|
|
||||||
|
// NOTE: we wait on the sigint event even in non-main threads to match the
|
||||||
|
// behavior of the other platforms. Non-main threads will ignore the
|
||||||
|
// Py_PARK_INTR result.
|
||||||
|
HANDLE sigint_event = _PyOS_SigintEvent();
|
||||||
|
HANDLE handles[2] = { sema->platform_sem, sigint_event };
|
||||||
|
DWORD count = sigint_event != NULL ? 2 : 1;
|
||||||
|
wait = WaitForMultipleObjects(count, handles, FALSE, millis);
|
||||||
if (wait == WAIT_OBJECT_0) {
|
if (wait == WAIT_OBJECT_0) {
|
||||||
res = Py_PARK_OK;
|
res = Py_PARK_OK;
|
||||||
}
|
}
|
||||||
|
else if (wait == WAIT_OBJECT_0 + 1) {
|
||||||
|
ResetEvent(sigint_event);
|
||||||
|
res = Py_PARK_INTR;
|
||||||
|
}
|
||||||
else if (wait == WAIT_TIMEOUT) {
|
else if (wait == WAIT_TIMEOUT) {
|
||||||
res = Py_PARK_TIMEOUT;
|
res = Py_PARK_TIMEOUT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = Py_PARK_INTR;
|
_Py_FatalErrorFormat(__func__,
|
||||||
|
"unexpected error from semaphore: %u (error: %u)",
|
||||||
|
wait, GetLastError());
|
||||||
}
|
}
|
||||||
#elif defined(_Py_USE_SEMAPHORES)
|
#elif defined(_Py_USE_SEMAPHORES)
|
||||||
int err;
|
int err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue