Charles-François Natali <[email protected]> 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 <[email protected]>
<http://bugs.python.org/issue13697>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com