
For Python 2, patching existing locks replaces RLock._RLock__owner with current thread ID no matter the old lock is locked or not and thus an unlocked RLock would have a non None owner (e.g. <_RLock owner=140106584489808 count=0>). Then if we acquire the RLock in the same thread, the method RLock.acquire would not invoke the _RLock__block.acquire() since it treats this is a recursive acquire by checking current thread ID. And then the following RLock.release would invoke the _RLock__block.release method resulting in the counter of Semaphore being improved to 2. There should be only two states being expected for RLock: 1. owner != None and count > 0 2. owner == None and count == 0 This patch fixs it by only setting locked RLocks' owner during patching.
26 lines
449 B
Python
26 lines
449 B
Python
__test__ = False
|
|
|
|
|
|
def take(lock, e1, e2):
|
|
with lock:
|
|
e1.set()
|
|
e2.wait()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
import threading
|
|
lock = threading.RLock()
|
|
import eventlet
|
|
eventlet.monkey_patch()
|
|
|
|
lock.acquire()
|
|
lock.release()
|
|
|
|
e1, e2 = threading.Event(), threading.Event()
|
|
eventlet.spawn(take, lock, e1, e2)
|
|
e1.wait()
|
|
assert not lock.acquire(blocking=0)
|
|
e2.set()
|
|
print('pass')
|