diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-03-30 23:03:10 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-03-30 23:03:10 (GMT) |
commit | d85456279f129e19a3f4c8ba0b3d05f5bdbfca1d (patch) | |
tree | b6dba00c7a9e08d4dcb12a96106186df8debd48c | |
parent | 3c136e19b9de13f8d4163a0feb3af54ab8b8c765 (diff) | |
parent | 7899acfc23c6262cea8f69bda36cf256cdfc3501 (diff) | |
download | cpython-d85456279f129e19a3f4c8ba0b3d05f5bdbfca1d.zip cpython-d85456279f129e19a3f4c8ba0b3d05f5bdbfca1d.tar.gz cpython-d85456279f129e19a3f4c8ba0b3d05f5bdbfca1d.tar.bz2 |
Issue #11618: Fix the timeout logic in threading.Lock.acquire() under
Windows.
-rw-r--r-- | Lib/test/lock_tests.py | 10 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Python/thread_nt.h | 67 |
3 files changed, 20 insertions, 59 deletions
diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index b6d818e..005c912 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -213,6 +213,16 @@ class LockTests(BaseLockTests): lock.acquire() lock.release() + def test_state_after_timeout(self): + # Issue #11618: check that lock is in a proper state after a + # (non-zero) timeout. + lock = self.locktype() + lock.acquire() + self.assertFalse(lock.acquire(timeout=0.01)) + lock.release() + self.assertFalse(lock.locked()) + self.assertTrue(lock.acquire(blocking=False)) + class RLockTests(BaseLockTests): """ @@ -87,6 +87,8 @@ Core and Builtins Library ------- +- Issue #11618: Fix the timeout logic in threading.Lock.acquire() under Windows. + - Removed the 'strict' argument to email.parser.Parser, which has been deprecated since Python 2.4. diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 684b545..d1bb0e5 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -9,82 +9,31 @@ #include <process.h> #endif -typedef struct NRMUTEX { - LONG owned ; - DWORD thread_id ; - HANDLE hevent ; -} NRMUTEX, *PNRMUTEX ; +#define PNRMUTEX HANDLE - -BOOL -InitializeNonRecursiveMutex(PNRMUTEX mutex) +PNRMUTEX +AllocNonRecursiveMutex() { - mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */ - mutex->thread_id = 0 ; - mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ; - return mutex->hevent != NULL ; /* TRUE if the mutex is created */ + return CreateSemaphore(NULL, 1, 1, NULL); } VOID -DeleteNonRecursiveMutex(PNRMUTEX mutex) +FreeNonRecursiveMutex(PNRMUTEX mutex) { /* No in-use check */ - CloseHandle(mutex->hevent) ; - mutex->hevent = NULL ; /* Just in case */ + CloseHandle(mutex); } DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) { - /* Assume that the thread waits successfully */ - DWORD ret ; - - /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */ - if (milliseconds == 0) - { - if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1) - return WAIT_TIMEOUT ; - ret = WAIT_OBJECT_0 ; - } - else - ret = InterlockedIncrement(&mutex->owned) ? - /* Some thread owns the mutex, let's wait... */ - WaitForSingleObject(mutex->hevent, milliseconds) : WAIT_OBJECT_0 ; - - mutex->thread_id = GetCurrentThreadId() ; /* We own it */ - return ret ; + return WaitForSingleObject(mutex, milliseconds); } BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex) { - /* We don't own the mutex */ - mutex->thread_id = 0 ; - return - InterlockedDecrement(&mutex->owned) < 0 || - SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */ -} - -PNRMUTEX -AllocNonRecursiveMutex(void) -{ - PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ; - if (mutex && !InitializeNonRecursiveMutex(mutex)) - { - free(mutex) ; - mutex = NULL ; - } - return mutex ; -} - -void -FreeNonRecursiveMutex(PNRMUTEX mutex) -{ - if (mutex) - { - DeleteNonRecursiveMutex(mutex) ; - free(mutex) ; - } + return ReleaseSemaphore(mutex, 1, NULL); } long PyThread_get_thread_ident(void); |