This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author neologix
Recipients barry, benjamin.peterson, christian.heimes, georg.brandl, neologix, pitrou, python-dev, sbt, vstinner
Date 2013-08-21.16:45:22
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <CAH_1eM16NDNvsX2nGpeeDx0u1zZX51CtDvps_0ppJQr+ypKuuw@mail.gmail.com>
In-reply-to <5214DC5D.6020002@gmail.com>
Content
>> Another, probably cleaner way would be to finally add the atfork()
>> module (issue #16500), and register this reseed hook (which could then
>> be implemented in ssl.py).
>
> Wouldn't that still suffer from the double-fork() issue?

Not for the "officially" supported way of creating child processes,
subprocess, since it calls fork() + exec() from C.
The problem with pthread_atfork() is that it would make the whole
interpreter non-safe even for correct code paths that call fork() +
exec(), which is not the case now.

Not reseeding with pthread_atfork() or atfork module, but only when
the ssl library is entered, just means that if a deadlock must occur,
it will only occur if the process re-enters the ssl library after
fork().

> Under which condition can a non-async safe function cause trouble? Is it just fork() inside a signal handler or can an incoming signal during fork() also cause havoc?

Actually, it doesn't need a signal to cause havoc: imagine that thread
A is inside an ssl function, holding a mutex protecting process-wide
internal ssl data. Then, thread B forks: in the child process, the ssl
mutex is already held (since the adress space is COW), so upon next
ssl library call in the child, the process will deadlock (trying to
acquire a mutex already held). That's an example with lock, but the
same holds if the library uses a global/static variable, etc. As an
approximation, sync-signal safe means "reentrant" (async-signal safe
comes from the fact that such restrictions apply to signal handler,
for the exact same reasons).

So you can pretty much only use reentrant functions between fork() and
exec() in a multi-threaded process (i.e. no malloc(), no strtok()...).
Which basically means that you can't run Python code at all between
fork() and exec() in a multi-threaded code.
History
Date User Action Args
2013-08-21 16:45:23neologixsetrecipients: + neologix, barry, georg.brandl, pitrou, vstinner, christian.heimes, benjamin.peterson, python-dev, sbt
2013-08-21 16:45:23neologixlinkissue18747 messages
2013-08-21 16:45:22neologixcreate