1- from threading import RLock
1+ from gevent .hub import getcurrent
2+ from gevent ._semaphore import Semaphore
23
34from .exceptions import LockError
45
56
7+ class RLock (object ):
8+ """
9+ A mutex that can be acquired more than once by the same greenlet.
10+ A mutex can only be locked by one greenlet at a time. A single greenlet
11+ can `acquire` the mutex as many times as desired, though. Each call to
12+ `acquire` must be paired with a matching call to `release`.
13+ It is an error for a greenlet that has not acquired the mutex
14+ to release it.
15+ Instances are context managers.
16+ """
17+
18+ __slots__ = (
19+ '_block' ,
20+ '_owner' ,
21+ '_count' ,
22+ '__weakref__' ,
23+ )
24+
25+ def __init__ (self ):
26+ self ._block = Semaphore (1 )
27+ self ._owner = None
28+ self ._count = 0
29+
30+ def __repr__ (self ):
31+ return "<%s at 0x%x _block=%s _count=%r _owner=%r)>" % (
32+ self .__class__ .__name__ ,
33+ id (self ),
34+ self ._block ,
35+ self ._count ,
36+ self ._owner )
37+
38+ def acquire (self , blocking = True , timeout = None ):
39+ """
40+ Acquire the mutex, blocking if *blocking* is true, for up to
41+ *timeout* seconds.
42+ .. versionchanged:: 1.5a4
43+ Added the *timeout* parameter.
44+ :return: A boolean indicating whether the mutex was acquired.
45+ """
46+ me = getcurrent ()
47+ if self ._owner is me :
48+ self ._count = self ._count + 1
49+ return 1
50+ rc = self ._block .acquire (blocking , timeout )
51+ if rc :
52+ self ._owner = me
53+ self ._count = 1
54+ return rc
55+
56+ def __enter__ (self ):
57+ return self .acquire ()
58+
59+ def release (self ):
60+ """
61+ Release the mutex.
62+ Only the greenlet that originally acquired the mutex can
63+ release it.
64+ """
65+ if self ._owner is not getcurrent ():
66+ raise RuntimeError ("cannot release un-acquired lock" )
67+ self ._count = count = self ._count - 1
68+ if not count :
69+ self ._owner = None
70+ self ._block .release ()
71+
72+ def __exit__ (self , typ , value , tb ):
73+ self .release ()
74+
75+ # Internal methods used by condition variables
76+
77+ def _acquire_restore (self , count_owner ):
78+ count , owner = count_owner
79+ self ._block .acquire ()
80+ self ._count = count
81+ self ._owner = owner
82+
83+ def _release_save (self ):
84+ count = self ._count
85+ self ._count = 0
86+ owner = self ._owner
87+ self ._owner = None
88+ self ._block .release ()
89+ return (count , owner )
90+
91+ def _is_owned (self ):
92+ return self ._owner is getcurrent ()
93+
94+
695class StrictLock :
796 """
897 Class that behaves like a Python RLock,
@@ -16,9 +105,10 @@ class StrictLock:
16105 timeout (int): Time in seconds acquisition will wait before raising an exception
17106 """
18107
19- def __init__ (self , timeout = 1 ):
108+ def __init__ (self , timeout = 1 , name = None ):
20109 self ._lock = RLock ()
21110 self .timeout = timeout
111+ self .name = name
22112
23113 def locked (self ):
24114 return self ._lock .locked ()
0 commit comments