Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions Doc/library/_thread.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ Lock objects have the following methods:
.. versionchanged:: 3.2
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()

Expand Down Expand Up @@ -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
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
survive. On most systems, they are killed without executing
:keyword:`try` ... :keyword:`finally` clauses or executing object
Expand Down
3 changes: 3 additions & 0 deletions Doc/library/threading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,9 @@ All methods are executed atomically.
Lock acquisition can now be interrupted by signals on POSIX if the
underlying threading implementation supports it.

.. versionchanged:: 3.14
Lock acquisition can now be interrupted by signals on Windows.


.. method:: release()

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
17 changes: 15 additions & 2 deletions Python/parking_lot.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,28 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, PyTime_t timeout)
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) {
res = Py_PARK_OK;
}
else if (wait == WAIT_OBJECT_0 + 1) {
ResetEvent(sigint_event);
res = Py_PARK_INTR;
}
else if (wait == WAIT_TIMEOUT) {
res = Py_PARK_TIMEOUT;
}
else {
res = Py_PARK_INTR;
_Py_FatalErrorFormat(__func__,
"unexpected error from semaphore: %u (error: %u)",
wait, GetLastError());
}
#elif defined(_Py_USE_SEMAPHORES)
int err;
Expand Down
Loading