diff options
author | Christopher Faylor <me@cgf.cx> | 2006-03-12 23:57:05 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2006-03-12 23:57:05 +0000 |
commit | 51f90b2f01642f40b491df371e016b79f02e3f1b (patch) | |
tree | 151d3fb1691443a2fc1d3051a2b66557bd1976f0 /winsup | |
parent | 0b9632d1fa2c163891dd42e53d773898fa3863af (diff) | |
download | cygnal-51f90b2f01642f40b491df371e016b79f02e3f1b.tar.gz cygnal-51f90b2f01642f40b491df371e016b79f02e3f1b.tar.bz2 cygnal-51f90b2f01642f40b491df371e016b79f02e3f1b.zip |
* cygtls.h (CYGTLS_INITIALIZED): Change to a little more unlikely value.
(CYGTLSMAGIC): Delete.
* dcrt0.cc (dll_crt0_0): Call sigproc_init during init startup.
(_dll_crt0): Don't worry about sync_startup. Just wait for sigthread here.
* dll_init.cc (cygwin_detach_dll): Only pick up tls version of retaddr if we
have a valid tls.
* fork.cc (frok::child): Remove sigproc_init initialization since it happens
much earlier now.
* gendef: Recognize SIGFE_MAYBE.
(fefunc): Generate calls to _sigfe_maybe, if appropriate.
(_sigfe_maybe): New function.
* init.cc (search_for): Always initialize search_for, even on fork.
(calibration_thread): Delete.
(calibration_id): Delete.
(prime_threads): Delete.
(munge_threadfunc): Remove calibration_thread special case. Avoid calling
thread function if we haven't yet hit the "search_for" thread.
(dll_entry): Remove prime_threads call. Only call munge_threadfunc when
hwait_sig is active. Ditto. for _my_tls.remove ();
* sigproc.cc (hwait_sig): Make global.
(sigproc_init): Don't bother with sync_startup.
(sig_send): Treat flush as a no-op when signals are held.
(wait_sig): Cause signals to be held after fork.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 26 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 4 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 14 | ||||
-rw-r--r-- | winsup/cygwin/dll_init.cc | 7 | ||||
-rw-r--r-- | winsup/cygwin/fork.cc | 2 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 27 | ||||
-rw-r--r-- | winsup/cygwin/init.cc | 53 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 14 |
9 files changed, 80 insertions, 70 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3ead72e5d..7d9a24d31 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,29 @@ +2006-03-12 Christopher Faylor <cgf@timesys.com> + + * cygtls.h (CYGTLS_INITIALIZED): Change to a little more unlikely value. + (CYGTLSMAGIC): Delete. + * dcrt0.cc (dll_crt0_0): Call sigproc_init during init startup. + (_dll_crt0): Don't worry about sync_startup. Just wait for sigthread here. + * dll_init.cc (cygwin_detach_dll): Only pick up tls version of retaddr + if we have a valid tls. + * fork.cc (frok::child): Remove sigproc_init initialization since it + happens much earlier now. + * gendef: Recognize SIGFE_MAYBE. + (fefunc): Generate calls to _sigfe_maybe, if appropriate. + (_sigfe_maybe): New function. + * init.cc (search_for): Always initialize search_for, even on fork. + (calibration_thread): Delete. + (calibration_id): Delete. + (prime_threads): Delete. + (munge_threadfunc): Remove calibration_thread special case. Avoid + calling thread function if we haven't yet hit the "search_for" thread. + (dll_entry): Remove prime_threads call. Only call munge_threadfunc + when hwait_sig is active. Ditto. for _my_tls.remove (); + * sigproc.cc (hwait_sig): Make global. + (sigproc_init): Don't bother with sync_startup. + (sig_send): Treat flush as a no-op when signals are held. + (wait_sig): Cause signals to be held after fork. + 2006-03-09 Corinna Vinschen <corinna@vinschen.de> * syscalls.cc (rename): Move existance check for oldpath further up diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 5e3155a76..c21201434 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -23,8 +23,7 @@ details. */ typedef unsigned int SOCKET; #endif -#define CYGTLS_INITIALIZED 0x43227 -#define CYGTLSMAGIC "D0Ub313v31nm&G1c?"; +#define CYGTLS_INITIALIZED 0xc763173f #ifndef CYG_MAX_PATH # define CYG_MAX_PATH 260 diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index ae91911cd..9fc71162a 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -301,8 +301,8 @@ cygwin_conv_to_posix_path SIGFE cygwin32_conv_to_posix_path = cygwin_conv_to_posix_path SIGFE cygwin_conv_to_win32_path SIGFE cygwin32_conv_to_win32_path = cygwin_conv_to_win32_path SIGFE -cygwin_detach_dll SIGFE -cygwin32_detach_dll = cygwin_detach_dll SIGFE +cygwin_detach_dll SIGFE_MAYBE +cygwin32_detach_dll = cygwin_detach_dll SIGFE_MAYBE cygwin_dll_init NOSIGFE endprotoent = cygwin_endprotoent SIGFE endservent = cygwin_endservent SIGFE diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 8122939b6..9da090f30 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -750,6 +750,8 @@ dll_crt0_0 () DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &hProcImpToken); + /* Initialize signal/subprocess handling. */ + sigproc_init (); debug_printf ("finished dll_crt0_0 initialization"); } @@ -835,9 +837,6 @@ dll_crt0_1 (char *) /* Initialize user info. */ uinfo_init (); - /* Initialize signal/subprocess handling. */ - sigproc_init (); - /* Connect to tty. */ tty_init (); @@ -924,7 +923,6 @@ dll_crt0_1 (char *) /* Flush signals and ensure that signal thread is up and running. Can't do this for noncygwin case since the signal thread is blocked due to LoadLibrary serialization. */ - wait_for_sigthread (); ld_preload (); if (user_data->main) cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr)); @@ -950,14 +948,8 @@ initialize_main_tls (char *padding) extern "C" void __stdcall _dll_crt0 () { - extern HANDLE sync_startup; extern DWORD threadfunc_ix; - if (sync_startup != INVALID_HANDLE_VALUE) - { - WaitForSingleObject (sync_startup, INFINITE); - CloseHandle (sync_startup); - } - + wait_for_sigthread (); if (!threadfunc_ix) system_printf ("internal error: couldn't determine location of thread function on stack. Expect signal problems."); diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 7d35c1633..7c7fc6407 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -404,7 +404,12 @@ dll_noncygwin_dllcrt0 (HMODULE h, per_process *p) extern "C" void cygwin_detach_dll (dll *) { - dlls.detach ((HANDLE) _my_tls.retaddr ()); + HANDLE retaddr; + if (_my_tls.isinitialized ()) + retaddr = (HANDLE) _my_tls.retaddr (); + else + retaddr = __builtin_return_address (0); + dlls.detach (retaddr); } extern "C" void diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index e4c3c31bb..244bb71db 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -171,8 +171,6 @@ frok::child (void *) ForceCloseHandle1 (fork_info->forker_finished, forker_finished); - sigproc_init (); - pthread::atforkchild (); fixup_timers_after_fork (); cygbench ("fork-child"); diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index c6b6a7909..40796f094 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -1,5 +1,5 @@ #!/usr/bin/perl -# Copyright 2003, 2004, 2005 Red Hat, Inc. +# Copyright 2003, 2004, 2005, 2006 Red Hat, Inc. # # This file is part of Cygwin. # @@ -43,12 +43,14 @@ for (@in) { chomp; if (/=/o) { if (s/\s+NOSIGFE\s*$//) { - } elsif (s/ SIGFE$//) { - my $func = (split(' '))[2]; - $sigfe{$func} = '_sigfe_' . $func; + # nothing + } elsif (s/ SIGFE(_MAYBE)?$//) { + my $func = (split(' '))[2]; + my $maybe = lc $1 . '_'; + $sigfe{$func} = '_sigfe' . $maybe . $func; } } else { - my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGR?FE))?$%o; + my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGFE(?:_MAYBE)?))?$%o; if (defined($sigfe) && $sigfe =~ /^NO/o) { $_ = $func; } else { @@ -83,13 +85,14 @@ close SIGFE; sub fefunc { my $func = '_' . shift; my $fe = '_' . shift; + my $sigfe_func = ($fe =~ /^(.*)$func/)[0]; my $extra; my $res = <<EOF; .extern $func .global $fe $fe: pushl \$$func - jmp __sigfe + jmp $sigfe_func EOF if (!$main::first++) { @@ -97,6 +100,18 @@ EOF .text .stabs "_sigfe:F(0,1)",36,0,0,__sigfe +__sigfe_maybe: + pushl %ebx + pushl %edx + movl %fs:4,%ebx # location of bottom of stack + movl $tls::initialized(%ebx),%eax + cmpl \$0xc763173f,%eax # initialized? + je 1f + popl %edx + popl %ebx + popl %eax + jmp *%eax + __sigfe: pushl %ebx pushl %edx diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index 3fd91c1d6..342bb1cfe 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -19,11 +19,9 @@ details. */ #include "ntdll.h" int NO_COPY dynamically_loaded; -static char *search_for = (char *) cygthread::stub; +static char NO_COPY *search_for = (char *) cygthread::stub; unsigned threadfunc_ix[8] __attribute__((section (".cygwin_dll_common"), shared)); -DWORD tls_func; - -HANDLE sync_startup; +extern cygthread *hwait_sig; #define OLDFUNC_OFFSET -1 @@ -35,32 +33,6 @@ threadfunc_fe (VOID *arg) _cygtls::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg); } -static DWORD WINAPI -calibration_thread (VOID *arg) -{ - ExitThread (0); -} - -static DWORD calibration_id; - -/* We need to know where the OS stores the address of the thread function - on the stack so that we can intercept the call and insert some tls - stuff on the stack. This function starts a known calibration thread. - When it starts, a call will be made to dll_entry which will call munge_threadfunc - looking for the calibration thread offset on the stack. This offset will - be stored and used by all executing cygwin processes. */ -static void -prime_threads () -{ - if (threadfunc_ix[0]) - sync_startup = INVALID_HANDLE_VALUE; - else - { - search_for = (char *) calibration_thread; - sync_startup = CreateThread (NULL, 0, calibration_thread, 0, 0, &calibration_id); - } -} - /* If possible, redirect the thread entry point to a cygwin routine which adds tls stuff to the stack. */ static void @@ -82,14 +54,16 @@ munge_threadfunc () } } - char *threadfunc = ebp[threadfunc_ix[0]]; - if (threadfunc == (char *) calibration_thread) - /* no need for the overhead */; - else if (threadfunc_ix[0]) + if (threadfunc_ix[0]) { - for (i = 0; threadfunc_ix[i]; i++) - ebp[threadfunc_ix[i]] = (char *) threadfunc_fe; - ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc; + char *threadfunc = ebp[threadfunc_ix[0]]; + if (!search_for || threadfunc == search_for) + { + search_for = NULL; + for (i = 0; threadfunc_ix[i]; i++) + ebp[threadfunc_ix[i]] = (char *) threadfunc_fe; + ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc; + } } } @@ -170,16 +144,15 @@ dll_entry (HANDLE h, DWORD reason, void *static_load) respawn_wow64_process (); dll_crt0_0 (); - prime_threads (); // this should be the last thing to happen break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: - if (!sync_startup || GetCurrentThreadId () == calibration_id) + if (hwait_sig) munge_threadfunc (); break; case DLL_THREAD_DETACH: - if (!sync_startup) + if (hwait_sig) _my_tls.remove (0); break; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 5e9ad1915..845f7cd80 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -61,10 +61,10 @@ HANDLE NO_COPY signal_arrived; // Event signaled when a signal has HANDLE NO_COPY sigCONT; // Used to "STOP" a process -Static cygthread *hwait_sig; +cygthread *hwait_sig; Static HANDLE wait_sig_inited; // Control synchronization of // message queue startup -Static bool sigheld; // True if holding signals +static bool sigheld; // True if holding signals Static int nprocs; // Number of deceased children Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info @@ -475,7 +475,6 @@ create_signal_arrived () void __stdcall sigproc_init () { - extern HANDLE sync_startup; wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); ProtectHandle (wait_sig_inited); @@ -484,7 +483,6 @@ sigproc_init () */ sync_proc_subproc.init ("sync_proc_subproc"); - sync_startup = NULL; hwait_sig = new cygthread (wait_sig, 0, cygself, "sig"); hwait_sig->zap_h (); @@ -523,6 +521,8 @@ sig_send (_pinfo *p, int sig) #endif return -1; } + else if (sig == __SIGFLUSH || sig == __SIGFLUSHFAST) + return 0; else { SetEvent (sigCONT); @@ -1091,8 +1091,12 @@ wait_sig (VOID *) readsig, myself->sendsig); sigpacket pack; + if (in_forkee) + pack.si.si_signo = __SIGHOLD; for (;;) { + if (pack.si.si_signo == __SIGHOLD) + WaitForSingleObject (sigCONT, INFINITE); DWORD nb; pack.tls = NULL; if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL)) @@ -1194,8 +1198,6 @@ wait_sig (VOID *) sigproc_printf ("signalling pack.wakeup %p", pack.wakeup); SetEvent (pack.wakeup); } - if (pack.si.si_signo == __SIGHOLD) - WaitForSingleObject (sigCONT, INFINITE); if (pack.si.si_signo == __SIGEXIT) break; } |