* 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>
|
2006-03-09 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* syscalls.cc (rename): Move existance check for oldpath further up
|
* syscalls.cc (rename): Move existance check for oldpath further up
|
||||||
|
|
|
@ -23,8 +23,7 @@ details. */
|
||||||
typedef unsigned int SOCKET;
|
typedef unsigned int SOCKET;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CYGTLS_INITIALIZED 0x43227
|
#define CYGTLS_INITIALIZED 0xc763173f
|
||||||
#define CYGTLSMAGIC "D0Ub313v31nm&G1c?";
|
|
||||||
|
|
||||||
#ifndef CYG_MAX_PATH
|
#ifndef CYG_MAX_PATH
|
||||||
# define CYG_MAX_PATH 260
|
# 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
|
cygwin32_conv_to_posix_path = cygwin_conv_to_posix_path SIGFE
|
||||||
cygwin_conv_to_win32_path SIGFE
|
cygwin_conv_to_win32_path SIGFE
|
||||||
cygwin32_conv_to_win32_path = cygwin_conv_to_win32_path SIGFE
|
cygwin32_conv_to_win32_path = cygwin_conv_to_win32_path SIGFE
|
||||||
cygwin_detach_dll SIGFE
|
cygwin_detach_dll SIGFE_MAYBE
|
||||||
cygwin32_detach_dll = cygwin_detach_dll SIGFE
|
cygwin32_detach_dll = cygwin_detach_dll SIGFE_MAYBE
|
||||||
cygwin_dll_init NOSIGFE
|
cygwin_dll_init NOSIGFE
|
||||||
endprotoent = cygwin_endprotoent SIGFE
|
endprotoent = cygwin_endprotoent SIGFE
|
||||||
endservent = cygwin_endservent SIGFE
|
endservent = cygwin_endservent SIGFE
|
||||||
|
|
|
@ -750,6 +750,8 @@ dll_crt0_0 ()
|
||||||
DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
|
DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
|
||||||
SecurityImpersonation, TokenImpersonation,
|
SecurityImpersonation, TokenImpersonation,
|
||||||
&hProcImpToken);
|
&hProcImpToken);
|
||||||
|
/* Initialize signal/subprocess handling. */
|
||||||
|
sigproc_init ();
|
||||||
debug_printf ("finished dll_crt0_0 initialization");
|
debug_printf ("finished dll_crt0_0 initialization");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,9 +837,6 @@ dll_crt0_1 (char *)
|
||||||
/* Initialize user info. */
|
/* Initialize user info. */
|
||||||
uinfo_init ();
|
uinfo_init ();
|
||||||
|
|
||||||
/* Initialize signal/subprocess handling. */
|
|
||||||
sigproc_init ();
|
|
||||||
|
|
||||||
/* Connect to tty. */
|
/* Connect to tty. */
|
||||||
tty_init ();
|
tty_init ();
|
||||||
|
|
||||||
|
@ -924,7 +923,6 @@ dll_crt0_1 (char *)
|
||||||
/* Flush signals and ensure that signal thread is up and running. Can't
|
/* 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
|
do this for noncygwin case since the signal thread is blocked due to
|
||||||
LoadLibrary serialization. */
|
LoadLibrary serialization. */
|
||||||
wait_for_sigthread ();
|
|
||||||
ld_preload ();
|
ld_preload ();
|
||||||
if (user_data->main)
|
if (user_data->main)
|
||||||
cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr));
|
cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr));
|
||||||
|
@ -950,14 +948,8 @@ initialize_main_tls (char *padding)
|
||||||
extern "C" void __stdcall
|
extern "C" void __stdcall
|
||||||
_dll_crt0 ()
|
_dll_crt0 ()
|
||||||
{
|
{
|
||||||
extern HANDLE sync_startup;
|
|
||||||
extern DWORD threadfunc_ix;
|
extern DWORD threadfunc_ix;
|
||||||
if (sync_startup != INVALID_HANDLE_VALUE)
|
wait_for_sigthread ();
|
||||||
{
|
|
||||||
WaitForSingleObject (sync_startup, INFINITE);
|
|
||||||
CloseHandle (sync_startup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!threadfunc_ix)
|
if (!threadfunc_ix)
|
||||||
system_printf ("internal error: couldn't determine location of thread function on stack. Expect signal problems.");
|
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
|
extern "C" void
|
||||||
cygwin_detach_dll (dll *)
|
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
|
extern "C" void
|
||||||
|
|
|
@ -171,8 +171,6 @@ frok::child (void *)
|
||||||
|
|
||||||
ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
||||||
|
|
||||||
sigproc_init ();
|
|
||||||
|
|
||||||
pthread::atforkchild ();
|
pthread::atforkchild ();
|
||||||
fixup_timers_after_fork ();
|
fixup_timers_after_fork ();
|
||||||
cygbench ("fork-child");
|
cygbench ("fork-child");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
# Copyright 2003, 2004, 2005 Red Hat, Inc.
|
# Copyright 2003, 2004, 2005, 2006 Red Hat, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Cygwin.
|
# This file is part of Cygwin.
|
||||||
#
|
#
|
||||||
|
@ -43,12 +43,14 @@ for (@in) {
|
||||||
chomp;
|
chomp;
|
||||||
if (/=/o) {
|
if (/=/o) {
|
||||||
if (s/\s+NOSIGFE\s*$//) {
|
if (s/\s+NOSIGFE\s*$//) {
|
||||||
} elsif (s/ SIGFE$//) {
|
# nothing
|
||||||
my $func = (split(' '))[2];
|
} elsif (s/ SIGFE(_MAYBE)?$//) {
|
||||||
$sigfe{$func} = '_sigfe_' . $func;
|
my $func = (split(' '))[2];
|
||||||
|
my $maybe = lc $1 . '_';
|
||||||
|
$sigfe{$func} = '_sigfe' . $maybe . $func;
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
if (defined($sigfe) && $sigfe =~ /^NO/o) {
|
||||||
$_ = $func;
|
$_ = $func;
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,13 +85,14 @@ close SIGFE;
|
||||||
sub fefunc {
|
sub fefunc {
|
||||||
my $func = '_' . shift;
|
my $func = '_' . shift;
|
||||||
my $fe = '_' . shift;
|
my $fe = '_' . shift;
|
||||||
|
my $sigfe_func = ($fe =~ /^(.*)$func/)[0];
|
||||||
my $extra;
|
my $extra;
|
||||||
my $res = <<EOF;
|
my $res = <<EOF;
|
||||||
.extern $func
|
.extern $func
|
||||||
.global $fe
|
.global $fe
|
||||||
$fe:
|
$fe:
|
||||||
pushl \$$func
|
pushl \$$func
|
||||||
jmp __sigfe
|
jmp $sigfe_func
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
if (!$main::first++) {
|
if (!$main::first++) {
|
||||||
|
@ -97,6 +100,18 @@ EOF
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.stabs "_sigfe:F(0,1)",36,0,0,__sigfe
|
.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:
|
__sigfe:
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
pushl %edx
|
pushl %edx
|
||||||
|
|
|
@ -19,11 +19,9 @@ details. */
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
|
||||||
int NO_COPY dynamically_loaded;
|
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));
|
unsigned threadfunc_ix[8] __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
DWORD tls_func;
|
extern cygthread *hwait_sig;
|
||||||
|
|
||||||
HANDLE sync_startup;
|
|
||||||
|
|
||||||
#define OLDFUNC_OFFSET -1
|
#define OLDFUNC_OFFSET -1
|
||||||
|
|
||||||
|
@ -35,32 +33,6 @@ threadfunc_fe (VOID *arg)
|
||||||
_cygtls::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), 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
|
/* If possible, redirect the thread entry point to a cygwin routine which
|
||||||
adds tls stuff to the stack. */
|
adds tls stuff to the stack. */
|
||||||
static void
|
static void
|
||||||
|
@ -82,14 +54,16 @@ munge_threadfunc ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *threadfunc = ebp[threadfunc_ix[0]];
|
if (threadfunc_ix[0])
|
||||||
if (threadfunc == (char *) calibration_thread)
|
|
||||||
/* no need for the overhead */;
|
|
||||||
else if (threadfunc_ix[0])
|
|
||||||
{
|
{
|
||||||
for (i = 0; threadfunc_ix[i]; i++)
|
char *threadfunc = ebp[threadfunc_ix[0]];
|
||||||
ebp[threadfunc_ix[i]] = (char *) threadfunc_fe;
|
if (!search_for || threadfunc == search_for)
|
||||||
((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
|
{
|
||||||
|
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 ();
|
respawn_wow64_process ();
|
||||||
|
|
||||||
dll_crt0_0 ();
|
dll_crt0_0 ();
|
||||||
prime_threads (); // this should be the last thing to happen
|
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
if (!sync_startup || GetCurrentThreadId () == calibration_id)
|
if (hwait_sig)
|
||||||
munge_threadfunc ();
|
munge_threadfunc ();
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
if (!sync_startup)
|
if (hwait_sig)
|
||||||
_my_tls.remove (0);
|
_my_tls.remove (0);
|
||||||
break;
|
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
|
HANDLE NO_COPY sigCONT; // Used to "STOP" a process
|
||||||
|
|
||||||
Static cygthread *hwait_sig;
|
cygthread *hwait_sig;
|
||||||
Static HANDLE wait_sig_inited; // Control synchronization of
|
Static HANDLE wait_sig_inited; // Control synchronization of
|
||||||
// message queue startup
|
// 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 int nprocs; // Number of deceased children
|
||||||
Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info
|
Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info
|
||||||
|
@ -475,7 +475,6 @@ create_signal_arrived ()
|
||||||
void __stdcall
|
void __stdcall
|
||||||
sigproc_init ()
|
sigproc_init ()
|
||||||
{
|
{
|
||||||
extern HANDLE sync_startup;
|
|
||||||
wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
ProtectHandle (wait_sig_inited);
|
ProtectHandle (wait_sig_inited);
|
||||||
|
|
||||||
|
@ -484,7 +483,6 @@ sigproc_init ()
|
||||||
*/
|
*/
|
||||||
sync_proc_subproc.init ("sync_proc_subproc");
|
sync_proc_subproc.init ("sync_proc_subproc");
|
||||||
|
|
||||||
sync_startup = NULL;
|
|
||||||
hwait_sig = new cygthread (wait_sig, 0, cygself, "sig");
|
hwait_sig = new cygthread (wait_sig, 0, cygself, "sig");
|
||||||
hwait_sig->zap_h ();
|
hwait_sig->zap_h ();
|
||||||
|
|
||||||
|
@ -523,6 +521,8 @@ sig_send (_pinfo *p, int sig)
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else if (sig == __SIGFLUSH || sig == __SIGFLUSHFAST)
|
||||||
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetEvent (sigCONT);
|
SetEvent (sigCONT);
|
||||||
|
@ -1091,8 +1091,12 @@ wait_sig (VOID *)
|
||||||
readsig, myself->sendsig);
|
readsig, myself->sendsig);
|
||||||
|
|
||||||
sigpacket pack;
|
sigpacket pack;
|
||||||
|
if (in_forkee)
|
||||||
|
pack.si.si_signo = __SIGHOLD;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
if (pack.si.si_signo == __SIGHOLD)
|
||||||
|
WaitForSingleObject (sigCONT, INFINITE);
|
||||||
DWORD nb;
|
DWORD nb;
|
||||||
pack.tls = NULL;
|
pack.tls = NULL;
|
||||||
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
|
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
|
||||||
|
@ -1194,8 +1198,6 @@ wait_sig (VOID *)
|
||||||
sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
|
sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
|
||||||
SetEvent (pack.wakeup);
|
SetEvent (pack.wakeup);
|
||||||
}
|
}
|
||||||
if (pack.si.si_signo == __SIGHOLD)
|
|
||||||
WaitForSingleObject (sigCONT, INFINITE);
|
|
||||||
if (pack.si.si_signo == __SIGEXIT)
|
if (pack.si.si_signo == __SIGEXIT)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue