Reputation: 842
I am using vfork()
in glibc and according to vfork()
's man page:
Fork handlers established using pthread_atfork(3) are not called when a multithreaded program employing the NPTL threading library calls vfork(). Fork handlers are called in this case in a program using the LinuxThreads threading library.
On NPTL fork handlers are not being called.
In my specific case I need this protection to be engaged so fork handlers will be called the same way as when calling fork()
.
Is there a way to cause pthread library to call registered handlers or even call them manually?
I thought of using clone()
as it gives more precise control of the cloned process but it also avoids fork handlers:
Handlers registered using pthread_atfork(3) are not executed during a clone call.
Also read how to reset handlers registered by pthread_atfork - in my case I don't want to remove handlers but only call them.
Thanks.
Upvotes: 1
Views: 294
Reputation: 213799
Is there a way to cause pthread library to call registered handlers or even call them manually?
If you succeeded in doing this, your program would become corrupt. There is a reason pthread_atfork
handlers aren't called on vfork
.
A typical usage of pthread_atfork
handlers is to guarantee that any locks held in the parent process are in a consistent state in both the child and the parent after the fork
.
Without handlers, suppose thread T1
is holding lock L
, and thread T2
calls fork
. Since only T2
will be replicated into the child, L
will remain locked forever. If T2
needs that lock (say it was the malloc
lock), T2
will deadlock (with T1
which doesn't exist in the child).
The solution: pthread_atfork
handlers. In the parent process prepare()
will acquire L
, and both parent()
and child()
handlers will unlock their own instance of L
in the parent and child processes respectively. Everything is happy1.
Now consider what happens if you do the same after vfork
. prepare()
acquires L
as expected, but when you call parent()
and child()
, they unlock the same instance of L
(because parent and child processes share memory). Thus L
gets unlocked twice, corrupting it!
1 In practice calling either fork
or vfork
in a multithreaded program is fraught with peril, and doing this safely in the presence of arbitrary libraries is near impossible.
Upvotes: 3