* child_info.h (child_info_fork::parent_wr_proc_pipe): New element.
* fork.cc (fork_parent): Set parent_wr_proc. * pinfo.cc (set_myself): Close child_proc_info->parent_wr_proc if it exists rather than trying to get value from parent _pinfo. * pinfo.h (enum parent_aleter): New enum. (pinfo::alert_parent): Declare as returning a value. (pinfo::parent_alive): New function. * pinfo.cc (pinfo::alert_parent): Set wr_proc_pipe to invalid non-NULL value when parent disappears. Return success of operation. (proc_waiter): Use __ALERT_* enum for control since these are not really signals. Implement __ALERT_ALIVE. * sigproc.cc (my_parent_is_alive): Eliminate. * sigproc.h (my_parent_is_alive): Ditto for declaration. (__SIGREPARENT): Eliminate.
This commit is contained in:
parent
3ef7d75861
commit
82b7b4fd4f
|
@ -1,3 +1,23 @@
|
|||
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* child_info.h (child_info_fork::parent_wr_proc_pipe): New element.
|
||||
* fork.cc (fork_parent): Set parent_wr_proc.
|
||||
* pinfo.cc (set_myself): Close child_proc_info->parent_wr_proc if it
|
||||
exists rather than trying to get value from parent _pinfo.
|
||||
|
||||
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* pinfo.h (enum parent_aleter): New enum.
|
||||
(pinfo::alert_parent): Declare as returning a value.
|
||||
(pinfo::parent_alive): New function.
|
||||
* pinfo.cc (pinfo::alert_parent): Set wr_proc_pipe to invalid non-NULL
|
||||
value when parent disappears. Return success of operation.
|
||||
(proc_waiter): Use __ALERT_* enum for control since these are not really signals.
|
||||
Implement __ALERT_ALIVE.
|
||||
* sigproc.cc (my_parent_is_alive): Eliminate.
|
||||
* sigproc.h (my_parent_is_alive): Ditto for declaration.
|
||||
(__SIGREPARENT): Eliminate.
|
||||
|
||||
2004-12-02 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* pinfo.cc (pinfo::wait): Use better name for cygthread.
|
||||
|
|
|
@ -29,7 +29,7 @@ enum
|
|||
|
||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||
|
||||
#define CURR_CHILD_INFO_MAGIC 0x83e9a7b7U
|
||||
#define CURR_CHILD_INFO_MAGIC 0x694cd4b8U
|
||||
|
||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||
below class. The layout is checksummed to determine compatibility between
|
||||
|
@ -49,6 +49,7 @@ public:
|
|||
void *cygheap_max;
|
||||
DWORD cygheap_reserve_sz;
|
||||
HANDLE cygheap_h;
|
||||
HANDLE parent_wr_proc_pipe;
|
||||
unsigned fhandler_union_cb;
|
||||
};
|
||||
|
||||
|
|
|
@ -401,6 +401,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
|||
init_child_info (PROC_FORK, &ch, subproc_ready);
|
||||
|
||||
ch.forker_finished = forker_finished;
|
||||
ch.parent_wr_proc_pipe = myself->wr_proc_pipe == INVALID_HANDLE_VALUE
|
||||
? NULL : myself->wr_proc_pipe;
|
||||
|
||||
stack_base (ch);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ details. */
|
|||
#include "fhandler.h"
|
||||
#include "cygmalloc.h"
|
||||
#include "cygtls.h"
|
||||
#include "child_info.h"
|
||||
|
||||
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
|
||||
|
||||
|
@ -43,6 +44,8 @@ pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
|
|||
void __stdcall
|
||||
set_myself (HANDLE h)
|
||||
{
|
||||
extern child_info *child_proc_info;
|
||||
|
||||
if (!h)
|
||||
cygheap->pid = cygwin_pid (GetCurrentProcessId ());
|
||||
myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
|
||||
|
@ -61,22 +64,19 @@ set_myself (HANDLE h)
|
|||
static pinfo NO_COPY myself_identity;
|
||||
myself_identity.init (cygwin_pid (myself->dwProcessId), PID_EXECED);
|
||||
}
|
||||
else if (myself->ppid)
|
||||
else if (myself->wr_proc_pipe)
|
||||
{
|
||||
/* here if forked/spawned */
|
||||
pinfo parent (myself->ppid);
|
||||
/* We've inherited the parent's wr_proc_pipe. We don't need it,
|
||||
so close it. This could cause problems for the spawn case since there
|
||||
is no guarantee that a parent will still be around by the time we get
|
||||
here. If so, we would have a handle leak. FIXME? */
|
||||
if (parent && parent->wr_proc_pipe)
|
||||
CloseHandle (parent->wr_proc_pipe);
|
||||
so close it. */
|
||||
if (child_proc_info->parent_wr_proc_pipe)
|
||||
CloseHandle (child_proc_info->parent_wr_proc_pipe);
|
||||
if (cygheap->pid_handle)
|
||||
{
|
||||
ForceCloseHandle (cygheap->pid_handle);
|
||||
cygheap->pid_handle = NULL;
|
||||
}
|
||||
}
|
||||
# undef child_proc_info
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -704,6 +704,8 @@ proc_waiter (void *arg)
|
|||
|
||||
switch (buf)
|
||||
{
|
||||
case __ALERT_ALIVE:
|
||||
continue;
|
||||
case 0:
|
||||
/* Child exited. Do some cleanup and signal myself. */
|
||||
CloseHandle (vchild.rd_proc_pipe);
|
||||
|
@ -733,7 +735,7 @@ proc_waiter (void *arg)
|
|||
break;
|
||||
case SIGCONT:
|
||||
continue;
|
||||
case __SIGREPARENT: /* sigh */
|
||||
case __ALERT_REPARENT: /* sigh */
|
||||
/* spawn_guts has signalled us that it has just started a new
|
||||
subprocess which will take over this cygwin pid. */
|
||||
|
||||
|
@ -830,23 +832,26 @@ pinfo::wait ()
|
|||
|
||||
/* function to send a "signal" to the parent when something interesting happens
|
||||
in the child. */
|
||||
void
|
||||
bool
|
||||
pinfo::alert_parent (char sig)
|
||||
{
|
||||
DWORD nb;
|
||||
DWORD nb = 0;
|
||||
/* Send something to our parent. If the parent has gone away,
|
||||
close the pipe. */
|
||||
if (myself->wr_proc_pipe
|
||||
&& WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
|
||||
if (myself->wr_proc_pipe == INVALID_HANDLE_VALUE)
|
||||
/* no parent */;
|
||||
else if (myself->wr_proc_pipe
|
||||
&& WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL))
|
||||
/* all is well */;
|
||||
else if (GetLastError () != ERROR_BROKEN_PIPE)
|
||||
debug_printf ("sending %d notification to parent failed, %E", sig);
|
||||
else
|
||||
{
|
||||
HANDLE closeit = myself->wr_proc_pipe;
|
||||
myself->wr_proc_pipe = NULL;
|
||||
myself->wr_proc_pipe = INVALID_HANDLE_VALUE;
|
||||
CloseHandle (closeit);
|
||||
}
|
||||
return (bool) nb;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -118,6 +118,12 @@ public:
|
|||
friend class pinfo;
|
||||
};
|
||||
|
||||
enum parent_alerter
|
||||
{
|
||||
__ALERT_REPARENT = 111, // arbitrary non-signal value
|
||||
__ALERT_ALIVE = 112
|
||||
};
|
||||
|
||||
class pinfo
|
||||
{
|
||||
HANDLE h;
|
||||
|
@ -153,7 +159,8 @@ public:
|
|||
operator _pinfo * () const {return procinfo;}
|
||||
// operator bool () const {return (int) h;}
|
||||
void preserve () { destroy = false; }
|
||||
void alert_parent (char);
|
||||
bool alert_parent (char);
|
||||
bool parent_alive () { return alert_parent (__ALERT_ALIVE); }
|
||||
#ifndef _SIGPROC_H
|
||||
int remember () {system_printf ("remember is not here"); return 0;}
|
||||
#else
|
||||
|
|
|
@ -125,23 +125,6 @@ signal_fixup_after_exec ()
|
|||
}
|
||||
}
|
||||
|
||||
/* Determine if the parent process is alive.
|
||||
*/
|
||||
|
||||
bool __stdcall
|
||||
my_parent_is_alive ()
|
||||
{
|
||||
bool res;
|
||||
if (myself->cygstarted)
|
||||
res = pid_exists (myself->ppid);
|
||||
else
|
||||
{
|
||||
debug_printf ("Not started by cygwin app");
|
||||
res = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void __stdcall
|
||||
wait_for_sigthread ()
|
||||
{
|
||||
|
|
|
@ -22,8 +22,7 @@ enum
|
|||
__SIGDELETE = -(NSIG + 5),
|
||||
__SIGFLUSHFAST = -(NSIG + 6),
|
||||
__SIGHOLD = -(NSIG + 7),
|
||||
__SIGNOHOLD = -(NSIG + 8),
|
||||
__SIGREPARENT = (NSIG + 2)
|
||||
__SIGNOHOLD = -(NSIG + 8)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -55,7 +54,6 @@ struct sigpacket
|
|||
extern HANDLE signal_arrived;
|
||||
extern HANDLE sigCONT;
|
||||
|
||||
bool __stdcall my_parent_is_alive ();
|
||||
void __stdcall sig_dispatch_pending (bool fast = false);
|
||||
#ifdef _PINFO_H
|
||||
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ());
|
||||
|
|
|
@ -636,6 +636,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
|||
ProtectHandle (cygheap->pid_handle);
|
||||
else
|
||||
system_printf ("duplicate to pid_handle failed, %E");
|
||||
ciresrv.parent_wr_proc_pipe = myself->wr_proc_pipe;
|
||||
}
|
||||
|
||||
/* Start the process in a suspended state. Needed so that any potential parent will
|
||||
|
@ -643,7 +644,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
|||
to handle exec'ed windows processes since cygwin processes are smart enough that
|
||||
the parent doesn't have to bother but what are you gonna do? Cygwin lives in
|
||||
a windows world. */
|
||||
flags |= CREATE_SUSPENDED;
|
||||
if (mode != _P_OVERLAY || !real_path.iscygexec ())
|
||||
flags |= CREATE_SUSPENDED;
|
||||
|
||||
const char *runpath = null_app_name ? NULL : (const char *) real_path;
|
||||
|
||||
|
@ -784,21 +786,24 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
|||
DWORD exec_cygstarted;
|
||||
if (mode == _P_OVERLAY)
|
||||
{
|
||||
/* Store the old exec_cygstarted since this is used as a crude semaphore for
|
||||
detecting when the parent has noticed the change in windows pid for this
|
||||
cygwin pid. */
|
||||
exec_cygstarted = myself->cygstarted;
|
||||
myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
|
||||
myself.alert_parent (__SIGREPARENT);
|
||||
if (!real_path.iscygexec ())
|
||||
{
|
||||
/* Store the old exec_cygstarted since this is used as a crude semaphore for
|
||||
detecting when the parent has noticed the change in windows pid for this
|
||||
cygwin pid. */
|
||||
exec_cygstarted = myself->cygstarted;
|
||||
myself->dwProcessId = dwExeced = pi.dwProcessId; /* Reparenting needs this */
|
||||
myself.alert_parent (__ALERT_REPARENT);
|
||||
}
|
||||
CloseHandle (saved_sendsig);
|
||||
strace.execing = 1;
|
||||
hExeced = pi.hProcess;
|
||||
strcpy (myself->progname, real_path);
|
||||
strcpy (myself->progname, real_path); // FIXME: race?
|
||||
close_all_files ();
|
||||
/* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
|
||||
/* If wr_proc_pipe is NULL 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 accommodeate
|
||||
is some minor special case code in proc_waiter and friends to accommodate
|
||||
this). */
|
||||
if (!myself->wr_proc_pipe)
|
||||
{
|
||||
|
@ -854,9 +859,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
|||
else
|
||||
{
|
||||
/* Loop, waiting for parent to notice pid change, if exec_cygstarted.
|
||||
In theory this wait should be a no-op. */
|
||||
In theory this wait should usually be a no-op. */
|
||||
if (exec_cygstarted)
|
||||
while (myself->cygstarted == exec_cygstarted)
|
||||
while (myself->cygstarted == exec_cygstarted && myself.parent_alive ())
|
||||
low_priority_sleep (0);
|
||||
res = 42;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue