summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/cygheap.cc2
-rw-r--r--winsup/cygwin/cygtls.h9
-rw-r--r--winsup/cygwin/dcrt0.cc1
-rw-r--r--winsup/cygwin/exceptions.cc1
-rw-r--r--winsup/cygwin/pinfo.cc18
-rw-r--r--winsup/cygwin/sigproc.cc23
-rw-r--r--winsup/cygwin/winsup.h1
8 files changed, 47 insertions, 25 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f1a607580..b4716ee36 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,22 @@
2005-09-22 Christopher Faylor <cgf@timesys.com>
+ * cygheap.cc (cygheap_fixup_in_child): It's not just for exec.
+ * cygtls.h (struct _cygtls::thread_handle): New field.
+ * dcrt0.cc (exit_lock): Remove declaration.
+ * winsup.h (exit_lock): Add declaration.
+ * exceptions.cc (sigpacket::process): Properly return after
+ signal_exit.
+ * pinfo.cc (pinfo::exit): Only exit the process if
+ _my_tls.thread_handle has not been filled out -- which should be an
+ impossible event.
+ * sigproc.cc (sigproc_terminate): Fillout _my_tls.thread_handle to
+ provide something for wait_sig to wait for. Use the siginfo_t version
+ of sig_send and fill out the tls argument with _my_tls.
+ (wait_sig): Wait for the thread specified in pack.tls or (for now)
+ complain bitterly if it doesn't exit.
+
+2005-09-22 Christopher Faylor <cgf@timesys.com>
+
* pinfo.cc (set_myself): Call strace.hello unconditionally when
DEBUGGING.
(pinfo::init): Sleep and issue debugging output before looping when a
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index fff2ad0d2..6cbdf6ef7 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -59,7 +59,7 @@ cygheap_fixup_in_child (bool execed)
cygheap_max = child_proc_info->cygheap;
cygheap = (init_cygheap *) cygheap_max;
_csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
- child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap for exec", cygheap, cygheap_max);
+ child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap", cygheap, cygheap_max);
cygheap_init ();
debug_fixup_after_fork_exec ();
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 33ffccb2f..9bffe8f88 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -176,14 +176,15 @@ struct _cygtls
siginfo_t infodata;
struct pthread *tid;
union
- {
- struct _reent local_clib;
- char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
- };
+ {
+ struct _reent local_clib;
+ char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
+ };
struct _local_storage locals;
class cygthread *_ctinfo;
san andreas;
waitq wq;
+ HANDLE thread_handle;
struct _cygtls *prev, *next;
__stack_t *stackptr;
int sig;
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 39dd08c13..ca8b601c9 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -998,7 +998,6 @@ __main (void)
}
exit_states NO_COPY exit_state;
-extern CRITICAL_SECTION exit_lock;
void __stdcall
do_exit (int status)
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index efd49ce6f..79cc251a3 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1162,6 +1162,7 @@ exit_sig:
sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
signal_exit (si.si_signo);
/* May not return */
+ return rc;
}
CRITICAL_SECTION NO_COPY exit_lock;
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 78964a486..1d7b837cb 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -140,6 +140,7 @@ pinfo::zap_cwd ()
void
pinfo::exit (DWORD n)
{
+ EnterCriticalSection (&exit_lock);
cygthread::terminate ();
if (n != EXITCODE_NOSET)
self->exitcode = EXITCODE_SET | n;/* We're really exiting. Record the UNIX exit code. */
@@ -152,7 +153,7 @@ pinfo::exit (DWORD n)
sigproc_terminate (ES_FINAL);
/* FIXME: There is a potential race between an execed process and its
- parent here. I hated to add a mutex just for this, though. */
+ parent here. I hated to add a mutex just for that, though. */
struct rusage r;
fill_rusage (&r, hMainProc);
add_rusage (&self->rusage_self, &r);
@@ -169,27 +170,16 @@ pinfo::exit (DWORD n)
_my_tls.stacklock = 0;
_my_tls.stackptr = _my_tls.stack;
- if (&_my_tls == _main_tls)
+ if (_my_tls.thread_handle)
{
sigproc_printf ("Calling ExitThread hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode);
ExitThread (exitcode);
}
- else if (hMainThread)
- {
-#if 0 /* This would be nice, but I don't think that Windows guarantees that
- TerminateThread will not block. */
- sigproc_printf ("Calling TerminateThread since %p != %p, %p, n %p, exitcode %p",
- &_my_tls, _main_tls, hProcess, n, exitcode);
- TerminateThread (hMainThread, exitcode);
- if (&_my_tls != _sig_tls)
- ExitThread (0);
-#endif
- }
sigproc_printf ("Calling ExitProcess since hMainthread is 0, hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode);
- // release (); Could race with signal thread. Sigh.
+ release ();
ExitProcess (exitcode);
}
# undef self
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index b9c66f376..8d84551eb 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -497,7 +497,15 @@ sigproc_terminate (exit_states es)
else
{
sigproc_printf ("entering");
- sig_send (myself_nowait, __SIGEXIT);
+ siginfo_t si;
+ memset (&si, 0, sizeof (si));
+ si.si_signo = __SIGEXIT;
+ if (&_my_tls == _main_tls)
+ _my_tls.thread_handle = hMainThread;
+ else
+ DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc, &_my_tls.thread_handle, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ sig_send (myself_nowait, si, &_my_tls);
proc_terminate (); // clean up process stuff
}
}
@@ -1005,10 +1013,11 @@ wait_sig (VOID *self)
debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p",
readsig, myself->sendsig);
+ sigpacket pack;
for (;;)
{
DWORD nb;
- sigpacket pack;
+ pack.tls = NULL;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break;
@@ -1114,9 +1123,13 @@ wait_sig (VOID *self)
break;
}
- HANDLE h = hMainThread;
- my_sendsig = hMainThread = NULL;
- DWORD res = !h ? WAIT_OBJECT_0 : WaitForSingleObject (h, INFINITE);
+ my_sendsig = NULL;
+ if (!pack.tls)
+ api_fatal ("no exit packet received");
+ if (!pack.tls->thread_handle)
+ api_fatal ("no thread handle set on exit");
+ HANDLE h = pack.tls->thread_handle;
+ DWORD res = WaitForSingleObject (h, INFINITE);
DWORD exitcode = 1;
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index d31dd9abd..f9004e16d 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -347,6 +347,7 @@ extern HANDLE hMainProc;
extern HANDLE hProcToken;
extern HANDLE hProcImpToken;
extern HANDLE hExeced;
+extern CRITICAL_SECTION exit_lock;
extern bool cygwin_testing;