Charles-François Natali <neolo...@free.fr> added the comment:

The core of the problem is that we don't just want those methods to be atomic 
or thread-safe, but reentrant (or rather async-safe).
As such, protecting by a lock isn't enough (and it's not really feasible in 
Python).

Note that the RLock implementation already checks whether the lock is already 
acquire by the current thread, but there's a "race":
if self._owner == me:
    [...]
    self._count = self._count + 1
    return 1
rc = self._block.acquire(blocking, timeout)
if rc:
    self._owner = me

If the signal handler is called after _block has been acquired, but before 
self._owner is set, the next call to acquire from the signal handler won't 
"realize" that the block has already been acquired by the current thread, and 
will deadlock.

Now, the fun part: this affects not only RLock, but every Python code 
performing "atomic" actions: condition variables, barriers, etc. There are some 
constraints on what can be done from a signal handler, and it should probably 
be documented.

Note that another solution would be to use a dedicated thread for signal 
management (like Java does), but that's another story.

Also, this shouldn't be a problem for the buffered I/O code, since the code 
already accounts for this possibility (if the lock is already acquired by the 
current thread, an exception is raised).

Now, there's something I don't understand: I've just had a quick look, but 
AFAICT, there's no reason why the C version of RLock could not be available: am 
I missing something? Why do we even have a Python implementation?

----------
nosy: +neologix

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue13697>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to