* 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:
parent
4340c43955
commit
936e4018b6
|
@ -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
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue