summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-03-14 06:34:05 +0000
committerChristopher Faylor <me@cgf.cx>2004-03-14 06:34:05 +0000
commitf8a8e7a1f6364f620685406cf9f3a9770b1d5789 (patch)
tree5405c4afeb2e3706083ed6e2fccf951e63868a9f
parent8308950ca5611565b842800e285ad4c8378344f5 (diff)
downloadcygnal-f8a8e7a1f6364f620685406cf9f3a9770b1d5789.tar.gz
cygnal-f8a8e7a1f6364f620685406cf9f3a9770b1d5789.tar.bz2
cygnal-f8a8e7a1f6364f620685406cf9f3a9770b1d5789.zip
* 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.
-rw-r--r--winsup/cygwin/ChangeLog10
-rw-r--r--winsup/cygwin/cygtls.cc1
-rw-r--r--winsup/cygwin/cygtls.h1
-rw-r--r--winsup/cygwin/sigproc.cc17
-rw-r--r--winsup/cygwin/spawn.cc3
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 <cgf@redhat.com>
+
+ * 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 <corinna@vinschen.de>
* 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. */