Skip to content
This repository was archived by the owner on Feb 4, 2020. It is now read-only.

Commit 177171f

Browse files
author
Hubert Hesse
committed
Hotfix race condition in mutex creation/deletion
On my machine TestHeaderChange.testDirect() fails with cache.lock, cache.statistics as stats: File "C:\Users\hesse\code\clcache\clcache.py", line 211, in __enter__ self.acquire() File "C:\Users\hesse\code\clcache\clcache.py", line 227, in acquire raise CacheLockException(errorString) __main__.CacheLockException: Error! WaitForSingleObject returns -1, last error 6
1 parent e25b61a commit 177171f

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

clcache.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import multiprocessing
2121
import re
2222

23+
2324
VERSION = "3.2.0-dev"
2425

2526
HashAlgorithm = hashlib.md5
@@ -198,17 +199,21 @@ class CacheLock(object):
198199
can be used in 'with' statements. """
199200
INFINITE = 0xFFFFFFFF
200201
WAIT_ABANDONED_CODE = 0x00000080
202+
INVALID_HANDLE = 0x00000006
201203

202204
def __init__(self, mutexName, timeoutMs):
203-
mutexName = 'Local\\' + mutexName
204-
self._mutex = windll.kernel32.CreateMutexW(
205-
wintypes.INT(0),
206-
wintypes.INT(0),
207-
mutexName)
205+
self.mutexName = 'Local\\' + mutexName
206+
self.create_mutex()
208207
self._timeoutMs = timeoutMs
209208
self._acquired = False
210209
assert self._mutex
211210

211+
def create_mutex(self):
212+
self._mutex = windll.kernel32.CreateMutexW(
213+
wintypes.INT(0),
214+
wintypes.BOOLEAN(False),
215+
self.mutexName)
216+
212217
def __enter__(self):
213218
if not self._acquired:
214219
self.acquire()
@@ -224,10 +229,15 @@ def acquire(self):
224229
result = windll.kernel32.WaitForSingleObject(
225230
self._mutex, wintypes.INT(self._timeoutMs))
226231
if result not in [0, self.WAIT_ABANDONED_CODE]:
232+
errno = windll.kernel32.GetLastError()
227233
errorString = 'Error! WaitForSingleObject returns {result}, last error {error}'.format(
228234
result=result,
229-
error=windll.kernel32.GetLastError())
230-
raise CacheLockException(errorString)
235+
error=errno)
236+
if errno == self.INVALID_HANDLE:
237+
self.create_mutex()
238+
self.acquire()
239+
else:
240+
raise CacheLockException(errorString)
231241
self._acquired = True
232242

233243
def release(self):

0 commit comments

Comments
 (0)