* pinfo.h (maybe_set_exit_code_from_windows): Renamed from set_exit_state.
* pinfo.cc (pinfo::exit): Use renamed function. (proc_waiter): Ditto. Make a copy of input argument to avoid problems when procs array is shuffled. Flag when copy is made so that remove_proc knows when it is safe to reshuffle. * sigproc.cc (proc_terminate): Don't flag process_state as PID_EXITED. (remove_proc): Wait for waiter to finish copying pinfo element before moving it (an actual wait should be an extremely rare event).
This commit is contained in:
parent
459a956197
commit
37d5841f83
@ -1,3 +1,15 @@
|
|||||||
|
2005-01-16 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* pinfo.h (maybe_set_exit_code_from_windows): Renamed from
|
||||||
|
set_exit_state.
|
||||||
|
* pinfo.cc (pinfo::exit): Use renamed function.
|
||||||
|
(proc_waiter): Ditto. Make a copy of input argument to avoid problems
|
||||||
|
when procs array is shuffled. Flag when copy is made so that
|
||||||
|
remove_proc knows when it is safe to reshuffle.
|
||||||
|
* sigproc.cc (proc_terminate): Don't flag process_state as PID_EXITED.
|
||||||
|
(remove_proc): Wait for waiter to finish copying pinfo element before
|
||||||
|
moving it (an actual wait should be an extremely rare event).
|
||||||
|
|
||||||
2005-01-15 Christopher Faylor <cgf@timesys.com>
|
2005-01-15 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* init.cc (dll_entry): Remove unused extern.
|
* init.cc (dll_entry): Remove unused extern.
|
||||||
|
@ -105,7 +105,7 @@ pinfo_init (char **envp, int envc)
|
|||||||
|
|
||||||
# define self (*this)
|
# define self (*this)
|
||||||
void
|
void
|
||||||
pinfo::set_exit_state ()
|
pinfo::maybe_set_exit_code_from_windows ()
|
||||||
{
|
{
|
||||||
DWORD x = 0xdeadbeef;
|
DWORD x = 0xdeadbeef;
|
||||||
DWORD oexitcode = self->exitcode;
|
DWORD oexitcode = self->exitcode;
|
||||||
@ -135,7 +135,7 @@ pinfo::exit (DWORD n)
|
|||||||
fill_rusage (&r, hMainProc);
|
fill_rusage (&r, hMainProc);
|
||||||
add_rusage (&self->rusage_self, &r);
|
add_rusage (&self->rusage_self, &r);
|
||||||
|
|
||||||
set_exit_state ();
|
maybe_set_exit_code_from_windows ();
|
||||||
if (n != EXITCODE_NOSET)
|
if (n != EXITCODE_NOSET)
|
||||||
self->alert_parent (0);
|
self->alert_parent (0);
|
||||||
int exitcode = self->exitcode;
|
int exitcode = self->exitcode;
|
||||||
@ -675,7 +675,8 @@ _pinfo::cmdline (size_t& n)
|
|||||||
static DWORD WINAPI
|
static DWORD WINAPI
|
||||||
proc_waiter (void *arg)
|
proc_waiter (void *arg)
|
||||||
{
|
{
|
||||||
pinfo& vchild = *(pinfo *) arg;
|
pinfo vchild = *(pinfo *) arg;
|
||||||
|
((pinfo *) arg)->waiter_ready = true;
|
||||||
|
|
||||||
siginfo_t si;
|
siginfo_t si;
|
||||||
si.si_signo = SIGCHLD;
|
si.si_signo = SIGCHLD;
|
||||||
@ -714,8 +715,7 @@ proc_waiter (void *arg)
|
|||||||
/* Child exited. Do some cleanup and signal myself. */
|
/* Child exited. Do some cleanup and signal myself. */
|
||||||
CloseHandle (vchild.rd_proc_pipe);
|
CloseHandle (vchild.rd_proc_pipe);
|
||||||
vchild.rd_proc_pipe = NULL;
|
vchild.rd_proc_pipe = NULL;
|
||||||
vchild.set_exit_state ();
|
vchild.maybe_set_exit_code_from_windows ();
|
||||||
vchild->process_state = PID_EXITED;
|
|
||||||
if (WIFEXITED (vchild->exitcode))
|
if (WIFEXITED (vchild->exitcode))
|
||||||
si.si_sigval.sival_int = CLD_EXITED;
|
si.si_sigval.sival_int = CLD_EXITED;
|
||||||
else if (WCOREDUMP (vchild->exitcode))
|
else if (WCOREDUMP (vchild->exitcode))
|
||||||
@ -723,6 +723,8 @@ proc_waiter (void *arg)
|
|||||||
else
|
else
|
||||||
si.si_sigval.sival_int = CLD_KILLED;
|
si.si_sigval.sival_int = CLD_KILLED;
|
||||||
si.si_status = vchild->exitcode;
|
si.si_status = vchild->exitcode;
|
||||||
|
vchild->process_state = PID_EXITED;
|
||||||
|
/* This should always be last. Do not use vchild-> beyond this point */
|
||||||
break;
|
break;
|
||||||
case SIGTTIN:
|
case SIGTTIN:
|
||||||
case SIGTTOU:
|
case SIGTTOU:
|
||||||
@ -812,6 +814,7 @@ pinfo::wait ()
|
|||||||
|
|
||||||
preserve (); /* Preserve the shared memory associated with the pinfo */
|
preserve (); /* Preserve the shared memory associated with the pinfo */
|
||||||
|
|
||||||
|
waiter_ready = false;
|
||||||
/* Fire up a new thread to track the subprocess */
|
/* Fire up a new thread to track the subprocess */
|
||||||
cygthread *h = new cygthread (proc_waiter, this, "proc_waiter");
|
cygthread *h = new cygthread (proc_waiter, this, "proc_waiter");
|
||||||
if (!h)
|
if (!h)
|
||||||
@ -854,6 +857,7 @@ _pinfo::alert_parent (char sig)
|
|||||||
debug_printf ("sending %d notification to parent failed, %E", sig);
|
debug_printf ("sending %d notification to parent failed, %E", sig);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ppid = 1;
|
||||||
HANDLE closeit = wr_proc_pipe;
|
HANDLE closeit = wr_proc_pipe;
|
||||||
wr_proc_pipe = INVALID_HANDLE_VALUE;
|
wr_proc_pipe = INVALID_HANDLE_VALUE;
|
||||||
CloseHandle (closeit);
|
CloseHandle (closeit);
|
||||||
|
@ -140,6 +140,7 @@ public:
|
|||||||
HANDLE rd_proc_pipe;
|
HANDLE rd_proc_pipe;
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
CRITICAL_SECTION _lock;
|
CRITICAL_SECTION _lock;
|
||||||
|
bool waiter_ready;
|
||||||
/* Handle associated with initial Windows pid which started it all. */
|
/* Handle associated with initial Windows pid which started it all. */
|
||||||
class cygthread *wait_thread;
|
class cygthread *wait_thread;
|
||||||
void init (pid_t, DWORD, HANDLE = NULL) __attribute__ ((regparm(3)));
|
void init (pid_t, DWORD, HANDLE = NULL) __attribute__ ((regparm(3)));
|
||||||
@ -155,7 +156,7 @@ public:
|
|||||||
release ();
|
release ();
|
||||||
}
|
}
|
||||||
void exit (DWORD n) __attribute__ ((noreturn, regparm(2)));
|
void exit (DWORD n) __attribute__ ((noreturn, regparm(2)));
|
||||||
void set_exit_state () __attribute__ ((regparm(2)));
|
void maybe_set_exit_code_from_windows () __attribute__ ((regparm(1)));
|
||||||
void initialize_lock () {InitializeCriticalSection (&_lock);}
|
void initialize_lock () {InitializeCriticalSection (&_lock);}
|
||||||
void lock () {EnterCriticalSection (&_lock);}
|
void lock () {EnterCriticalSection (&_lock);}
|
||||||
void unlock () {LeaveCriticalSection (&_lock);}
|
void unlock () {LeaveCriticalSection (&_lock);}
|
||||||
|
@ -65,8 +65,9 @@ Static HANDLE wait_sig_inited; // Control synchronization of
|
|||||||
// message queue startup
|
// message queue startup
|
||||||
|
|
||||||
Static int nprocs; // Number of deceased children
|
Static int nprocs; // Number of deceased children
|
||||||
Static char cprocs[(NPROCS + 1) * sizeof (pinfo)]; // All my deceased children info
|
Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info
|
||||||
#define procs ((pinfo *) cprocs)
|
#define procs ((pinfo *) cprocs) // All this just to avoid expensive
|
||||||
|
// constructor operation at DLL startup
|
||||||
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
|
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
|
||||||
|
|
||||||
muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
|
muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
|
||||||
@ -406,8 +407,6 @@ proc_terminate (void)
|
|||||||
for (i = 0; i < nprocs; i++)
|
for (i = 0; i < nprocs; i++)
|
||||||
{
|
{
|
||||||
procs[i]->ppid = 1;
|
procs[i]->ppid = 1;
|
||||||
if (!proc_exists (procs[i]))
|
|
||||||
procs[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
|
|
||||||
if (procs[i].wait_thread)
|
if (procs[i].wait_thread)
|
||||||
{
|
{
|
||||||
// CloseHandle (procs[i].rd_proc_pipe);
|
// CloseHandle (procs[i].rd_proc_pipe);
|
||||||
@ -860,7 +859,15 @@ remove_proc (int ci)
|
|||||||
ForceCloseHandle1 (procs[ci].hProcess, childhProc);
|
ForceCloseHandle1 (procs[ci].hProcess, childhProc);
|
||||||
}
|
}
|
||||||
if (ci < --nprocs)
|
if (ci < --nprocs)
|
||||||
procs[ci] = procs[nprocs];
|
{
|
||||||
|
/* Wait for proc_waiter thread to make a copy of this element before
|
||||||
|
moving it or it may become confused. The chances are very high that
|
||||||
|
the proc_waiter thread has already done this by the time we
|
||||||
|
get here. */
|
||||||
|
while (!procs[nprocs].waiter_ready)
|
||||||
|
low_priority_sleep (0);
|
||||||
|
procs[ci] = procs[nprocs];
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user