Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-03-13 02:57:05 +0300
committerChristopher Faylor <me@cgf.cx>2006-03-13 02:57:05 +0300
commit51f90b2f01642f40b491df371e016b79f02e3f1b (patch)
tree151d3fb1691443a2fc1d3051a2b66557bd1976f0
parent0b9632d1fa2c163891dd42e53d773898fa3863af (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/cygtls.h3
-rw-r--r--winsup/cygwin/cygwin.din4
-rw-r--r--winsup/cygwin/dcrt0.cc14
-rw-r--r--winsup/cygwin/dll_init.cc7
-rw-r--r--winsup/cygwin/fork.cc2
-rwxr-xr-xwinsup/cygwin/gendef27
-rw-r--r--winsup/cygwin/init.cc53
-rw-r--r--winsup/cygwin/sigproc.cc14
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;
}