@@ -31,6 +31,9 @@ def __repr__(self):
3131 self ._owner ,
3232 )
3333
34+ def locked (self ):
35+ return self ._block .locked ()
36+
3437 def acquire (self , blocking = True , timeout = None ):
3538 """
3639 Acquire the mutex, blocking if *blocking* is true, for up to
@@ -68,22 +71,6 @@ def release(self):
6871 def __exit__ (self , typ , value , tb ):
6972 self .release ()
7073
71- # Internal methods used by condition variables
72-
73- def _acquire_restore (self , count_owner ):
74- count , owner = count_owner
75- self ._block .acquire ()
76- self ._count = count
77- self ._owner = owner
78-
79- def _release_save (self ):
80- count = self ._count
81- self ._count = 0
82- owner = self ._owner
83- self ._owner = None
84- self ._block .release ()
85- return (count , owner )
86-
8774 def _is_owned (self ):
8875 return self ._owner is getcurrent ()
8976
@@ -109,22 +96,35 @@ def __init__(self, timeout=1, name=None):
10996 def locked (self ):
11097 return self ._lock .locked ()
11198
112- def acquire (self , blocking = True ):
113- return self ._lock .acquire (blocking , timeout = self .timeout )
99+ def acquire (self , blocking = True , timeout = None , _strict = True ):
100+ if not timeout :
101+ timeout = self .timeout
102+ result = self ._lock .acquire (blocking , timeout = timeout )
103+ if _strict and not result :
104+ raise LockError ("ACQUIRE_ERROR" , self )
105+ else :
106+ return result
114107
115108 def __enter__ (self ):
116- result = self ._lock .acquire (blocking = True , timeout = self .timeout )
117- if result :
118- return result
119- else :
120- raise LockError ("ACQUIRE_ERROR" , self )
109+ return self .acquire (blocking = True , timeout = self .timeout )
121110
122111 def __exit__ (self , * args ):
123- self ._lock . release ()
112+ self .release ()
124113
125114 def release (self ):
126115 self ._lock .release ()
127116
117+ @property
118+ def _owner (self ):
119+ return self ._lock ._owner
120+
121+ @_owner .setter
122+ def _owner (self , new_owner ):
123+ self ._lock ._owner = new_owner
124+
125+ def _is_owned (self ):
126+ return self ._lock ._is_owned ()
127+
128128
129129class CompositeLock :
130130 """
@@ -144,20 +144,53 @@ def __init__(self, locks, timeout=1):
144144 self .locks = locks
145145 self .timeout = timeout
146146
147- def acquire (self , blocking = True ):
148- return (lock .acquire (blocking = blocking ) for lock in self .locks )
147+ def acquire (self , blocking = True , timeout = None ):
148+ if not timeout :
149+ timeout = self .timeout
150+
151+ lock_all = all (
152+ [
153+ lock .acquire (blocking = blocking , timeout = timeout , _strict = False )
154+ for lock in self .locks
155+ ]
156+ )
149157
150- def __enter__ (self ):
151- result = (lock .acquire (blocking = True ) for lock in self .locks )
152- if all (result ):
153- return result
154- else :
158+ if not lock_all :
159+ self ._emergency_release ()
155160 raise LockError ("ACQUIRE_ERROR" , self )
156161
162+ return True
163+
164+ def __enter__ (self ):
165+ return self .acquire (blocking = True , timeout = self .timeout )
166+
157167 def __exit__ (self , * args ):
158- for lock in self .locks :
159- lock .release ()
168+ return self .release ()
160169
161170 def release (self ):
171+ # If not all child locks are owner by caller
172+ if not all ([owner is getcurrent () for owner in self ._owner ]):
173+ raise RuntimeError ("cannot release un-acquired lock" )
162174 for lock in self .locks :
163- lock .release ()
175+ if lock .locked ():
176+ lock .release ()
177+
178+ def _emergency_release (self ):
179+ for lock in self .locks :
180+ if lock .locked () and lock ._is_owned ():
181+ lock .release ()
182+
183+ def locked (self ):
184+ return any ([lock .locked () for lock in self .locks ])
185+
186+ @property
187+ def _owner (self ):
188+ return [lock ._owner for lock in self .locks ]
189+
190+ @_owner .setter
191+ def _owner (self , new_owner ):
192+ for lock in self .locks :
193+ lock ._owner = new_owner
194+
195+ def _is_owned (self ):
196+ return all ([lock ._is_owned () for lock in self .locks ])
0 commit comments