Taylor R Campbell <campbell+netbsd-tech-userlevel%mumble.net@localhost> writes: > Pthread_atfork(3) says that no pthread_* routines may be used in the > child handler. But this completely defeats the purpose of > pthread_atfork. As the POSIX rationale section explains, > > `The expected usage is that the prepare handler acquires all mutex > locks and the other two fork handlers release them.' > > http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html This whole issue is a big mess. The basic issue is the notion of "async-signal-safe", and which calls may be invoked from a signal handler. After a fork, only one thread survives, and you basically can't do much in the child except exec. As I read POSIX, I don't see the restriction about pthread calls in the child. But it may be implicit with the requirement not to use calls which are not documented to be async-signal-safe. We had a big problem with this where python (among other things) would fork and then call malloc in the child. If the malloc lock were taken by some other thread in the parent, then it would deadlock. python is wrong here, as malloc is not specificed to be async-signal-safe. But the workaround (which I'm a bit fuzzy on) was to take the malloc lock in the before handler and release it in both - in libc, not in python. > There is a long comment in src/lib/libc/gen/pthread_atfork.c > explaining why the child does mutex_init instead of mutex_unlock: if > the spin lock inside a mutex is held by another thread, then trying to > unlock the mutex in the child will wait forever because the other > thread won't be there in the child. I think this is unsound (calling mutex_init). If the mutex is acquired in the thread that calls fork, then it should be safe to unlock it. Are you trying to figure out how to have the child act like a full-fledged process without doing an exec? I don't think that's really possible.
Attachment:
pgpTxt2eMwUXn.pgp
Description: PGP signature