Issue 35391: threading.RLock exception handling while waiting (original) (raw)

(tested on python 2.7)

Created a threading.Condition(threading.RLock()) A piece of code acquires the lock using a with block and waits (for a notify) While wait() is running a KeyboardInterrupt is raised An exception is raised while exiting the lock's with block: File "/usr/lib/python2.7/threading.py", line 289, in exit return self.__lock.exit(*args) File "/usr/lib/python2.7/threading.py", line 216, in exit self.release() File "/usr/lib/python2.7/threading.py", line 204, in release raise RuntimeError("cannot release un-acquired lock")

example code running on the main thread: def waiting(lock): # (the lock was created using Condition(RLock())) with lock: lock.wait(timeout=xxx) # while waiting a keyboard interrupt is raised

The issue is caused because threading.RLock doesn't handle the exception correctly: def _acquire_restore(self, count_owner): count, owner = count_owner self.__block.acquire() self.__count = count self.__owner = owner if debug: self._note("%s._acquire_restore()", self)

The exception is raised after the acquire() returns and the count and owner are not restored.

The problem was solved using the following fix (added try, finally): def _acquire_restore(self, count_owner): count, owner = count_owner try: self.__block.acquire() finally: self.__count = count self.__owner = owner if debug: self._note("%s._acquire_restore()", self)

Looking at the code, this issue exists in python 3.8 as well.