* 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:
parent
0b9632d1fa
commit
51f90b2f01
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue