* 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:
Christopher Faylor
2012-03-16 20:20:29 +00:00
parent d3f6480e44
commit 4aeaedf961
7 changed files with 192 additions and 169 deletions

View File

@ -308,6 +308,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
return -1;
}
hold_everything for_now;
/* FIXME: There is a small race here and FIXME: not thread safe! */
pthread_cleanup cleanup;
@ -335,7 +336,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
bool null_app_name = false;
STARTUPINFOW si = {};
int looped = 0;
HANDLE orig_wr_proc_pipe = NULL;
myfault efault;
if (efault.faulted ())
@ -349,10 +349,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
}
child_info_types chtype;
if (mode != _P_OVERLAY)
chtype = _CH_SPAWN;
else
if (mode == _P_OVERLAY)
chtype = _CH_EXEC;
else
{
chtype = _CH_SPAWN;
myself.prefork ();
}
moreinfo = cygheap_exec_info::alloc ();
@ -770,23 +773,16 @@ loop:
sigproc_printf ("new process name %W", myself->progname);
/* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
process. So, we need to wait around until the process we've just "execed"
dies. Use our own wait facility to wait for our own pid to exit (there
is some minor special case code in proc_waiter and friends to accommodate
this).
dies. Use our own wait facility below to wait for our own pid to exit
(there is some minor special case code in proc_waiter and friends to
accommodate this).
If wr_proc_pipe exists, then it should be duplicated to the child.
If wr_proc_pipe exists, then it will be inherited by the child.
If the child has exited already, that's ok. The parent will pick up
on this fact when we exit. dup_proc_pipe will close our end of the pipe.
Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE. That will make
dup_proc_pipe essentially a no-op. */
on this fact when we exit. myself.postexec () will close our end of
the pipe. */
if (!newargv.win16_exe && myself->wr_proc_pipe)
{
if (!looped)
myself->sync_proc_pipe (); /* Make sure that we own wr_proc_pipe
just in case we've been previously
execed. */
orig_wr_proc_pipe = myself->dup_proc_pipe (pi.hProcess, "child_info_spawn::worker");
}
myself.postexec ();
pid = myself->pid;
if (!iscygwin ())
close_all_files ();
@ -851,11 +847,6 @@ loop:
myself.hProcess = pi.hProcess;
if (!synced)
{
if (orig_wr_proc_pipe)
{
myself->wr_proc_pipe_owner = GetCurrentProcessId ();
myself->wr_proc_pipe = orig_wr_proc_pipe;
}
if (!proc_retry (pi.hProcess))
{
looped++;
@ -896,6 +887,8 @@ loop:
}
out:
if (mode != _P_OVERLAY)
myself.postfork ();
this->cleanup ();
if (envblock)
free (envblock);