STINNER Victor <vstin...@python.org> added the comment:

> subprocess.Popen.send_signal() doesn't check if the process exited since the 
> poll() method has been called for the last time. If the process exit just 
> before os.kill() is called, the signal can be sent to the wrong process if 
> the process identified is recycled.

I'm not sure under which conditions this case happens.

I understood that the pid is released (and so can be reused) as soon as the 
child process completes *and* waitpid() has been called.

Two cases:

* os.waitpid(pid, 0) can be called directly ("raw call")
* Popen API used, but called from a different thread: thread A calls 
send_signal(), thread B calls waitpid()

I'm mostly concerned by the multithreading case. I noticed the race condition 
while working on regrtest which uses 2 threads. One thread which is responsible 
for the process (call .communicate(), call .wait(), etc.), and one "main" 
thread which sends a signal to every child processes to interrupt them.

My first implementation called .wait() after calling .send_signal() in the main 
thread. But it seems like Popen is not "fully" thread safe: the "waitpid lock" 
only protects the os.waitpid() call, it doesn't protect the self.returncode 
attribute.

I modified regrtest to only call .waitpid() in the thread responsible of the 
process, to avoid such race condition. It seems like the new design is more 
reliable. The main thread only calls .send_signal(): it doesn't call .wait() 
(which calls os.waitpid()) anymore.

----------

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

Reply via email to