* 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

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