* 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.
This commit is contained in:
Christopher Faylor 2005-09-23 03:35:41 +00:00
parent 4340c43955
commit 936e4018b6
8 changed files with 47 additions and 25 deletions

View File

@ -1,3 +1,20 @@
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> 2005-09-22 Christopher Faylor <cgf@timesys.com>
* pinfo.cc (set_myself): Call strace.hello unconditionally when * pinfo.cc (set_myself): Call strace.hello unconditionally when

View File

@ -59,7 +59,7 @@ cygheap_fixup_in_child (bool execed)
cygheap_max = child_proc_info->cygheap; cygheap_max = child_proc_info->cygheap;
cygheap = (init_cygheap *) cygheap_max; cygheap = (init_cygheap *) cygheap_max;
_csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap); _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 (); cygheap_init ();
debug_fixup_after_fork_exec (); debug_fixup_after_fork_exec ();

View File

@ -176,14 +176,15 @@ struct _cygtls
siginfo_t infodata; siginfo_t infodata;
struct pthread *tid; struct pthread *tid;
union union
{ {
struct _reent local_clib; struct _reent local_clib;
char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)]; char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
}; };
struct _local_storage locals; struct _local_storage locals;
class cygthread *_ctinfo; class cygthread *_ctinfo;
san andreas; san andreas;
waitq wq; waitq wq;
HANDLE thread_handle;
struct _cygtls *prev, *next; struct _cygtls *prev, *next;
__stack_t *stackptr; __stack_t *stackptr;
int sig; int sig;

View File

@ -998,7 +998,6 @@ __main (void)
} }
exit_states NO_COPY exit_state; exit_states NO_COPY exit_state;
extern CRITICAL_SECTION exit_lock;
void __stdcall void __stdcall
do_exit (int status) do_exit (int status)

View File

@ -1162,6 +1162,7 @@ exit_sig:
sigproc_printf ("signal %d, about to call do_exit", si.si_signo); sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
signal_exit (si.si_signo); signal_exit (si.si_signo);
/* May not return */ /* May not return */
return rc;
} }
CRITICAL_SECTION NO_COPY exit_lock; CRITICAL_SECTION NO_COPY exit_lock;

View File

@ -140,6 +140,7 @@ pinfo::zap_cwd ()
void void
pinfo::exit (DWORD n) pinfo::exit (DWORD n)
{ {
EnterCriticalSection (&exit_lock);
cygthread::terminate (); cygthread::terminate ();
if (n != EXITCODE_NOSET) if (n != EXITCODE_NOSET)
self->exitcode = EXITCODE_SET | n;/* We're really exiting. Record the UNIX exit code. */ 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); sigproc_terminate (ES_FINAL);
/* FIXME: There is a potential race between an execed process and its /* 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; struct rusage r;
fill_rusage (&r, hMainProc); fill_rusage (&r, hMainProc);
add_rusage (&self->rusage_self, &r); add_rusage (&self->rusage_self, &r);
@ -169,27 +170,16 @@ pinfo::exit (DWORD n)
_my_tls.stacklock = 0; _my_tls.stacklock = 0;
_my_tls.stackptr = _my_tls.stack; _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", sigproc_printf ("Calling ExitThread hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode); hProcess, n, exitcode);
ExitThread (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", sigproc_printf ("Calling ExitProcess since hMainthread is 0, hProcess %p, n %p, exitcode %p",
hProcess, n, exitcode); hProcess, n, exitcode);
// release (); Could race with signal thread. Sigh. release ();
ExitProcess (exitcode); ExitProcess (exitcode);
} }
# undef self # undef self

View File

@ -497,7 +497,15 @@ sigproc_terminate (exit_states es)
else else
{ {
sigproc_printf ("entering"); 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 proc_terminate (); // clean up process stuff
} }
} }
@ -1005,10 +1013,11 @@ wait_sig (VOID *self)
debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p", debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p",
readsig, myself->sendsig); readsig, myself->sendsig);
sigpacket pack;
for (;;) for (;;)
{ {
DWORD nb; DWORD nb;
sigpacket pack; pack.tls = NULL;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL)) if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break; break;
@ -1114,9 +1123,13 @@ wait_sig (VOID *self)
break; break;
} }
HANDLE h = hMainThread; my_sendsig = NULL;
my_sendsig = hMainThread = NULL; if (!pack.tls)
DWORD res = !h ? WAIT_OBJECT_0 : WaitForSingleObject (h, INFINITE); 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; DWORD exitcode = 1;

View File

@ -347,6 +347,7 @@ extern HANDLE hMainProc;
extern HANDLE hProcToken; extern HANDLE hProcToken;
extern HANDLE hProcImpToken; extern HANDLE hProcImpToken;
extern HANDLE hExeced; extern HANDLE hExeced;
extern CRITICAL_SECTION exit_lock;
extern bool cygwin_testing; extern bool cygwin_testing;