* fork.cc (lock_signals): Move to sigproc.h.
(lock_pthread): Ditto. (hold_everything): Ditto. (frok::parent): Call myself.prefork() just before calling CreateProcess. Call myself.postfork () on function exit. * pinfo.cc (pinfo::pending_rd_proc_pipe): Define. (pinfo::pending_wr_proc_pipe): Ditto. (_pinfo::dup_proc_pipe): Delete. (pinfo::wait): Move pipe creation into pinfo::prefork. Set pipe variables from pending_*. (_pinfo::sync_proc_pipe): Delete. (_pinfo::proc_pipe_owner): Ditto. (pinfo::prefork): Define new function. (pinfo::postfork): Ditto. (pinfo::postexec): Ditto. (_pinfo::alert_parent): Remove obsolete call to sync_proc_pipe. (_pinfo::dup_proc_pipe): Delete declaration. (_pinfo::sync_proc_pipe): Ditto. (pinfo::pending_rd_proc_pipe): Declare. (pinfo::pending_wr_proc_pipe): Ditto. (pinfo::prefork): Declare new function. (pinfo::postfork): Ditto. (pinfo::postexec): Ditto. (pinfo::wr_proc_pipe): Define new wrapper function. * sigproc.h: Include "sync.h". Move locking functions from fork to here. * spawn.cc (child_info_spawn::worker): Delete now-unneeded requirement to record orig_wr_proc_pipe. Call hold_everything prior to doing anything. Call myself.prefork() if spawning. Replace wr_proc_pipe synchronization with call to myself.postexec(). Call myself.postfork() if not execing. * sync.h: Replace #ifdef wrapper with "#pragma once".
This commit is contained in:
@ -47,83 +47,6 @@ class frok
|
||||
friend int fork ();
|
||||
};
|
||||
|
||||
class lock_signals
|
||||
{
|
||||
bool worked;
|
||||
public:
|
||||
lock_signals ()
|
||||
{
|
||||
worked = sig_send (NULL, __SIGHOLD) == 0;
|
||||
}
|
||||
operator int () const
|
||||
{
|
||||
return worked;
|
||||
}
|
||||
void dont_bother ()
|
||||
{
|
||||
worked = false;
|
||||
}
|
||||
~lock_signals ()
|
||||
{
|
||||
if (worked)
|
||||
sig_send (NULL, __SIGNOHOLD);
|
||||
}
|
||||
};
|
||||
|
||||
class lock_pthread
|
||||
{
|
||||
bool bother;
|
||||
public:
|
||||
lock_pthread (): bother (1)
|
||||
{
|
||||
pthread::atforkprepare ();
|
||||
}
|
||||
void dont_bother ()
|
||||
{
|
||||
bother = false;
|
||||
}
|
||||
~lock_pthread ()
|
||||
{
|
||||
if (bother)
|
||||
pthread::atforkparent ();
|
||||
}
|
||||
};
|
||||
|
||||
class hold_everything
|
||||
{
|
||||
public: /* DELETEME*/
|
||||
bool& ischild;
|
||||
/* Note the order of the locks below. It is important,
|
||||
to avoid races, that the lock order be preserved.
|
||||
|
||||
pthread is first because it serves as a master lock
|
||||
against other forks being attempted while this one is active.
|
||||
|
||||
signals is next to stop signal processing for the duration
|
||||
of the fork.
|
||||
|
||||
process is last. If it is put before signals, then a deadlock
|
||||
could be introduced if the process attempts to exit due to a signal. */
|
||||
lock_pthread pthread;
|
||||
lock_signals signals;
|
||||
lock_process process;
|
||||
|
||||
public:
|
||||
hold_everything (bool& x): ischild (x) {}
|
||||
operator int () const {return signals;}
|
||||
|
||||
~hold_everything()
|
||||
{
|
||||
if (ischild)
|
||||
{
|
||||
pthread.dont_bother ();
|
||||
process.dont_bother ();
|
||||
signals.dont_bother ();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
resume_child (HANDLE forker_finished)
|
||||
{
|
||||
@ -407,6 +330,7 @@ frok::parent (volatile char * volatile stack_here)
|
||||
while (1)
|
||||
{
|
||||
hchild = NULL;
|
||||
myself.prefork ();
|
||||
rc = CreateProcessW (myself->progname, /* image to run */
|
||||
myself->progname, /* what we send in arg0 */
|
||||
&sec_none_nih,
|
||||
@ -592,6 +516,7 @@ frok::parent (volatile char * volatile stack_here)
|
||||
|
||||
/* Common cleanup code for failure cases */
|
||||
cleanup:
|
||||
myself.postfork ();
|
||||
if (fix_impersonation)
|
||||
cygheap->user.reimpersonate ();
|
||||
if (locked)
|
||||
|
Reference in New Issue
Block a user