* 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.
This commit is contained in:
Christopher Faylor 2006-03-12 23:57:05 +00:00
parent 0b9632d1fa
commit 51f90b2f01
9 changed files with 80 additions and 70 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.");

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}