From f8a8e7a1f6364f620685406cf9f3a9770b1d5789 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 14 Mar 2004 06:34:05 +0000 Subject: [PATCH] * cygtls.cc (_cygtls::remove): Call remove_wq to ensure that wait stuff is removed from proc_subproc linked list. * cygtls.h (_cygtls::remove_wq): Declare. * sigproc.cc (_cygtls::remove_wq): Define. (proc_subproc): Label event handle appropriately. * spawn.cc (spawn_guts): Return -1 when wait() fails for spawn types that require waiting. --- winsup/cygwin/ChangeLog | 10 ++++++++++ winsup/cygwin/cygtls.cc | 1 + winsup/cygwin/cygtls.h | 1 + winsup/cygwin/sigproc.cc | 17 ++++++++++++++++- winsup/cygwin/spawn.cc | 3 ++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e3e4253aa..42bcc14ae 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2004-03-14 Christopher Faylor + + * cygtls.cc (_cygtls::remove): Call remove_wq to ensure that wait stuff + is removed from proc_subproc linked list. + * cygtls.h (_cygtls::remove_wq): Declare. + * sigproc.cc (_cygtls::remove_wq): Define. + (proc_subproc): Label event handle appropriately. + * spawn.cc (spawn_guts): Return -1 when wait() fails for spawn types + that require waiting. + 2004-03-12 Corinna Vinschen * errno.cc (errmap): Handle ERROR_BUS_RESET. diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 36aaa86d6..f9770bbb0 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -159,6 +159,7 @@ _cygtls::remove (DWORD wait) if (i < --nthreads) cygheap->threadlist[i] = cygheap->threadlist[nthreads]; debug_printf ("removed %p element %d", this, i); + remove_wq (); break; } } diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 1a9e75f0a..df4b62b65 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -154,6 +154,7 @@ struct _cygtls void set_threadkill () {threadkill = true;} void reset_threadkill () {threadkill = false;} int call_signal_handler () __attribute__ ((regparm (1))); + void remove_wq () __attribute__ ((regparm (1))); void fixup_after_fork () __attribute__ ((regparm (1))); void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 9c3b200b6..30318a7e1 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -401,7 +401,7 @@ proc_subproc (DWORD what, DWORD val) { wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - ProtectHandle (wval->ev); + ProtectHandle1 (wval->ev, wq_ev); } ResetEvent (wval->ev); @@ -469,6 +469,21 @@ out1: return rc; } +// FIXME: This is inelegant +void +_cygtls::remove_wq () +{ + sync_proc_subproc->acquire (); + for (waitq *w = &waitq_head; w->next != NULL; w = w->next) + if (w->next == &wq) + { + ForceCloseHandle1 (wq.thread_ev, wq_ev); + w->next = wq.next; + break; + } + sync_proc_subproc->release (); +} + /* Terminate the wait_subproc thread. * Called on process exit. * Also called by spawn_guts to disassociate any subprocesses from this diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 992bad1ab..e7d25e976 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -912,7 +912,8 @@ spawn_guts (const char * prog_arg, const char *const *argv, break; case _P_WAIT: case _P_SYSTEM: - waitpid (cygpid, (int *) &res, 0); + if (waitpid (cygpid, (int *) &res, 0) != cygpid) + res = -1; break; case _P_DETACH: res = 0; /* Lose all memory of this child. */