diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index dd1ab484d..c9acb7ec8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,25 @@ +2006-06-01 Christopher Faylor + + * cygheap.cc (cygheap_fixup_in_child): Don't close parent handle here. + Let the caller do that. + * dcrt0.cc (child_info_spawn::handle_spawn): Close parent handle here + to allow fixup_after_exec functions to use it. + + * cygtls.cc (_cygtls::call2): Avoid calling exit thread if called with + *crt0_1 functions. + * cygtls.h (_cygtls::isinitialized): Check that we actually have a tls + before seeing if it is initialized. + * gendef (_sigfe_maybe): Ditto. + * dcrt0.cc (dll_crt0_1): Remove static, use just one argument. + * dll_init.cc (dllcrt0_info): New structure. + (dll_dllcrt0): Change into a front-end to renamed dll_dllcrt0_1 so that + we'll always be assured of having something like a tls. + (dll_dllcrt0_1): New function, basically renamed from from dll_dllcrt0. + Unconditionally call _my_tls.init_exception_handler now that we are + assured of having a tls. Change variable name from "linking" to "linked". + * winsup.h (dll_crt0_1): Declare. + (dll_dllcrt0_1): Ditto. + 2006-05-30 Christopher Faylor * cygtls.cc (_cygtls::call2): Don't call ExitThread on the main thread. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 0c555e37e..9f44c8a30 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -62,15 +62,6 @@ cygheap_fixup_in_child (bool execed) child_copy (child_proc_info->parent, false, "cygheap", cygheap, cygheap_max, NULL); cygheap_init (); debug_fixup_after_fork_exec (); - - /* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of - handles might get confused. */ - if (execed) - { - CloseHandle (child_proc_info->parent); - child_proc_info->parent = NULL; - } - if (execed) { cygheap->hooks.next = NULL; diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 8dd15ad6e..e03175a1f 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -75,7 +75,8 @@ _cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf) remove (INFINITE); /* Don't call ExitThread on the main thread since we may have been dynamically loaded. */ - if (this != _main_tls) + if ((void *) func != (void *) dll_crt0_1 + && (void *) func != (void *) dll_dllcrt0_1) ExitThread (res); } diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 6379f8cec..0a3b06d6f 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -182,7 +182,11 @@ struct _cygtls void push (__stack_t) __attribute__ ((regparm (2))); __stack_t pop () __attribute__ ((regparm (1))); __stack_t retaddr () {return stackptr[-1];} - bool isinitialized () const {return initialized == CYGTLS_INITIALIZED;} + bool isinitialized () const + { + volatile char here; + return ((char *) this > &here) && initialized == CYGTLS_INITIALIZED; + } bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3))); void __stdcall interrupt_setup (int sig, void *handler, diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 8d76d66fe..b18aaa1a6 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -692,6 +692,12 @@ child_info_spawn::handle_spawn () envc = moreinfo->envc; if (!dynamically_loaded) cygheap->fdtab.fixup_after_exec (); + + /* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of + handles might get confused. */ + CloseHandle (child_proc_info->parent); + child_proc_info->parent = NULL; + signal_fixup_after_exec (); if (moreinfo->old_title) { @@ -783,8 +789,8 @@ dll_crt0_0 () various special cases when Cygwin DLL is being runtime loaded (as opposed to being link-time loaded by Cygwin apps) from a non cygwin app via LoadLibrary. */ -static void -dll_crt0_1 (void *, void *) +void +dll_crt0_1 (void *) { check_sanity_and_sync (user_data); malloc_init (); diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 977ca312d..189d9b188 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -348,24 +348,47 @@ dll_list::load_after_fork (HANDLE parent, dll *first) in_forkee = false; } +struct dllcrt0_info +{ + HMODULE h; + per_process *p; + int res; + dllcrt0_info (HMODULE h0, per_process *p0): h(h0), p(p0) {} +}; + extern "C" int dll_dllcrt0 (HMODULE h, per_process *p) { + dllcrt0_info x (h, p); + + if (_my_tls.isinitialized ()) + dll_dllcrt0_1 (&x); + else + _my_tls.call ((DWORD (*) (void *, void *)) dll_dllcrt0_1, &x); + return x.res; +} + +void +dll_dllcrt0_1 (VOID *x) +{ + HMODULE& h = ((dllcrt0_info *)x)->h; + per_process*& p = ((dllcrt0_info *)x)->p; + int& res = ((dllcrt0_info *)x)->res; + /* Windows apparently installs a bunch of exception handlers prior to this function getting called and one of them may trip before cygwin gets to it. So, install our own exception handler only. FIXME: It is possible that we may have to save state of the previous exception handler chain and restore it, if problems are noted. */ - if (cygwin_finished_initializing) - _my_tls.init_exception_handler (_cygtls::handle_exceptions); + _my_tls.init_exception_handler (_cygtls::handle_exceptions); if (p == NULL) p = &__cygwin_user_data; else *(p->impure_ptr_ptr) = __cygwin_user_data.impure_ptr; - bool linking = !in_forkee && !cygwin_finished_initializing; + bool linked = !in_forkee && !cygwin_finished_initializing; /* Partially initialize Cygwin guts for non-cygwin apps. */ if (dynamically_loaded && user_data->magic_biscuit == 0) @@ -379,7 +402,7 @@ dll_dllcrt0 (HMODULE h, per_process *p) initializing, then the DLL must be a cygwin-aware DLL that was explicitly linked into the program rather than a dlopened DLL. */ - if (linking) + if (linked) type = DLL_LINK; else { @@ -395,10 +418,10 @@ dll_dllcrt0 (HMODULE h, per_process *p) initialize the DLL. If we haven't finished initializing, it may not be safe to call the dll's "main" since not all of cygwin's internal structures may have been set up. */ - if (!d || (!linking && !d->init ())) - return -1; - - return (DWORD) d; + if (!d || (!linked && !d->init ())) + res = -1; + else + res = (DWORD) d; } /* OBSOLETE: This function is obsolescent and will go away in the diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index b31d71b3a..4f60ea686 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -104,10 +104,14 @@ __sigfe_maybe: pushl %ebx pushl %edx movl %fs:4,%ebx # location of bottom of stack + addl \$$tls::initialized,%ebx # where we will be looking + cmpl %ebx,%esp # stack loc > than tls + jge 0f # yep. we don't have a tls. + subl \$$tls::initialized,%ebx # where we will be looking movl $tls::initialized(%ebx),%eax cmpl \$0xc763173f,%eax # initialized? je 1f - popl %edx +0: popl %edx popl %ebx ret diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 73ef0a59f..9a1039dc1 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -169,6 +169,8 @@ class per_process; /* cygwin .dll initialization */ void dll_crt0 (per_process *) __asm__ ("_dll_crt0__FP11per_process"); extern "C" void __stdcall _dll_crt0 (); +extern void dll_crt0_1 (void *); +extern void dll_dllcrt0_1 (void *); /* dynamically loaded dll initialization */ extern "C" int dll_dllcrt0 (HMODULE, per_process *);