bpo-36688: Adding an implementation of RLock in _dummy_thread (GH-12943) · python/cpython@c5905f3

@@ -14,7 +14,7 @@

1414

# Exports only things specified by thread documentation;

1515

# skipping obsolete synonyms allocate(), start_new(), exit_thread().

1616

__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',

17-

'interrupt_main', 'LockType']

17+

'interrupt_main', 'LockType', 'RLock']

18181919

# A dummy value

2020

TIMEOUT_MAX = 2**31

@@ -148,6 +148,36 @@ def __repr__(self):

148148

hex(id(self))

149149

)

150150151+152+

class RLock(LockType):

153+

"""Dummy implementation of threading._RLock.

154+155+

Re-entrant lock can be aquired multiple times and needs to be released

156+

just as many times. This dummy implemention does not check wheter the

157+

current thread actually owns the lock, but does accounting on the call

158+

counts.

159+

"""

160+

def __init__(self):

161+

super().__init__()

162+

self._levels = 0

163+164+

def acquire(self, waitflag=None, timeout=-1):

165+

"""Aquire the lock, can be called multiple times in succession.

166+

"""

167+

locked = super().acquire(waitflag, timeout)

168+

if locked:

169+

self._levels += 1

170+

return locked

171+172+

def release(self):

173+

"""Release needs to be called once for every call to acquire().

174+

"""

175+

if self._levels == 0:

176+

raise error

177+

if self._levels == 1:

178+

super().release()

179+

self._levels -= 1

180+151181

# Used to signal that interrupt_main was called in a "thread"

152182

_interrupt = False

153183

# True when not executing in a "thread"