Eliminate use of sigframe and sigthread throughout.

* Makefile.in (DLL_OFILES): Add sigfe.o.  Remove reliance on cygwin.def from
cygwin0.dll dependency since dependence on sigfe.o implies that.  Generate def
file on the fly using 'gendef'.
* configure.in: Don't auto-generate cygwin.def.
* configure: Regenerate.
* cygwin.din: Add SIGFE stuff where appropriate.
* dcrt0.cc (dll_crt0_1): Initialize cygwin tls early in process startup.  Set
_main_tls to address of the main thread's cygwin tls.
* debug.h: Remove now unneeded WFSO and WFMO declarations.
* exceptions.cc (_last_thread): Define.
(set_thread_state_for_signals): New function.
(reset_thread_exception_for_signals): Ditto.
(init_thread_for_signals): Ditto.
(delete_thread_for_signals): Ditto.
(capture_thread_for_signals): Ditto.
(handle_exceptions): Set return address explicitly for exceptions prior to
calling sig_send.
(interrupt_on_return): Eliminate.
(setup_handler): Add preliminary implementation for dealing with
thread-specific signals by querying _main_tls.
(signal_exit): Use cygthread::main_thread_id instead of mainthread.id.
(call_signal_handler_now): For now, just handle the main thread.
* fork.cc (vfork): Save and restore main _my_tls.
* gendef: New file.  Generates def file and sigfe.s file.
* gentls_offsets: New file.  Generates offsets for perl to use in sigfe.s.
* how-signals-work.txt: Mention that info is obsolete.
* init.cc (dll_entry): Initialize cygwin tls storage here.
* miscfuncs.cc (low_priority_sleep): Make a C function for easier calling from
asm.
* perthread.h (vfork_save::tls): New element.
* signal.cc (nanosleep): Replace previous use of
sigframe.call_signal_handler_now with straight call to call_signal_handler_now.
(abort): Ditto.
* syscalls.cc (readv): Ditto.
* termios.cc (tcsetattr): Ditto.
* wait.cc (wait4): Ditto.
* sigproc.cc (sig_dispatch_pending): Ditto.
(sig_send): Ditto.
* sigproc.h: Declare call_signal_handler_now.
* thread.cc (pthread::thread_init_wrapper): Initialize cygwin tls.  Remove
obsolete and unworking signal stuff.
* thread.h (verifyable_object::sigs): Eliminate.
(verifyable_object::sigmask): Eliminate.
(verifyable_object::sigtodo): Eliminate.
(verifyable_object::exit): Make attribute noreturn.
(verifyable_object::thread_init_wrapper): Ditto.
(pthread_null::exit): Ditto.
* winbase.h (__stackbase): Always define.
* winsup.h (low_priority_sleep): Declare as a "C" function.
* include/cygwin/version.h: Bump API version to reflect sigwait export.
* include/sys/queue.h: Protect SLIST_ENTRY from previous declaration.
* signal.cc (sigwait): Implement.
* select.cc (fhandler_base::ready_for_read): Add debugging output.
* devices.h: Define more device pointers via their storage.
* devices.in: Don't parse things like /dev/inet/tcp, as they really have no
meaning.
* devices.cc: Regenerate.
* gendevices: Set proper protection for output file.
* cygtls.h: New file.
* gendef: New file.
* gentls_offsets: New file.
* tlsoffsets.h: New file.  Autogenerated.
* config/i386/longjmp.c: Remove.  File subsumed by gendef output.
* config/i386/makefrag: Remove obsolete file.
* fhandler.cc: Remove spurious access_worker declaration.
* spawn.cc (spawnve): Make debugging output more accurate.
* cygwin-gperf: Remove.
* devices.cc: Remove.
This commit is contained in:
Christopher Faylor
2003-11-28 20:55:59 +00:00
parent ffe0063843
commit 9a4d574b8d
50 changed files with 3311 additions and 3466 deletions

View File

@ -20,6 +20,7 @@ details. */
#include <sys/signal.h>
#include "cygerrno.h"
#include "sync.h"
#include "cygtls.h"
#include "sigproc.h"
#include "pinfo.h"
#include "security.h"
@ -37,10 +38,6 @@ details. */
*/
#define WSSC 60000 // Wait for signal completion
#define WPSP 40000 // Wait for proc_subproc mutex
#define WSPX 20000 // Wait for wait_sig to terminate
#define WWSP 20000 // Wait for wait_subproc to terminate
#define TOTSIGS (NSIG + __SIGOFFSET)
#define wake_wait_subproc() SetEvent (events[0])
@ -48,9 +45,11 @@ details. */
#define NZOMBIES 256
class sigelem
struct sigelem
{
int sig;
int pid;
_threadinfo *tls;
class sigelem *next;
friend class pending_signals;
friend int __stdcall sig_dispatch_pending ();
@ -66,9 +65,9 @@ class pending_signals
int empty;
public:
void reset () {curr = &start; prev = &start;}
void add (int sig);
void add (int sig, int pid, _threadinfo *tls);
void del ();
int next ();
sigelem *next ();
friend int __stdcall sig_dispatch_pending ();
};
@ -78,6 +77,7 @@ struct sigpacket
pid_t pid;
HANDLE wakeup;
sigset_t *mask;
_threadinfo *tls;
};
static pending_signals sigqueue;
@ -112,10 +112,6 @@ int __sp_ln;
char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
// current process but no wait is required
char NO_COPY myself_nowait_nonmain_dummy[1] = {'1'};// Flag to sig_send that signal goes to
// current process but no wait is required
// if this is the main thread.
HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
// resulted in a user-specified
// function call
@ -244,7 +240,7 @@ get_proc_lock (DWORD what, DWORD val)
static BOOL __stdcall
proc_can_be_signalled (_pinfo *p)
{
if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
if (p == myself_nowait || p == myself)
{
assert (!wait_sig_inited);
return 1;
@ -549,10 +545,10 @@ sig_clear (int target_sig)
sig_send (myself, -target_sig);
else
{
int sig;
sigqueue.reset ();
while ((sig = sigqueue.next ()))
if (sig == target_sig)
sigelem *q;
while ((q = sigqueue.next ()))
if (q->sig == target_sig)
{
sigqueue.del ();
break;
@ -578,9 +574,8 @@ sig_dispatch_pending ()
if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next)
return 0;
sigframe thisframe (mainthread);
(void) sig_send (myself, __SIGFLUSH);
return thisframe.call_signal_handler ();
return call_signal_handler_now ();
}
/* Message initialization. Called from dll_crt0_1
@ -654,18 +649,15 @@ sigproc_terminate (void)
* completed before returning.
*/
int __stdcall
sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
sig_send (_pinfo *p, int sig, void *tls)
{
int rc = 1;
DWORD tid = GetCurrentThreadId ();
BOOL its_me;
HANDLE sendsig;
bool wait_for_completion;
sigframe thisframe;
sigpacket pack;
if (p == myself_nowait_nonmain)
p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
bool wait_for_completion;
// FIXMENOW: Avoid using main thread's completion event!
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
wait_for_completion = false;
else
@ -674,7 +666,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
goto out; // Either exiting or not yet initializing
if (wait_sig_inited)
wait_for_sigthread ();
wait_for_completion = p != myself_nowait;
wait_for_completion = p != myself_nowait && _my_tls.isinitialized ();
p = myself;
}
@ -695,11 +687,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
{
sendsig = myself->sendsig;
if (wait_for_completion)
{
if (tid == mainthread.id)
thisframe.init (mainthread, ebp, exception);
pack.wakeup = sigcomplete_main;
}
pack.wakeup = sigcomplete_main;
}
else
{
@ -735,6 +723,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
pack.sig = sig;
pack.pid = myself->pid;
pack.tls = (_threadinfo *) tls;
DWORD nb;
if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
{
@ -790,7 +779,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
}
if (wait_for_completion)
thisframe.call_signal_handler ();
call_signal_handler_now ();
out:
if (sig != __SIGPENDING)
@ -995,7 +984,7 @@ talktome ()
has been handled, as per POSIX. */
void
pending_signals::add (int sig)
pending_signals::add (int sig, int pid, _threadinfo *tls)
{
sigelem *se;
for (se = start.next; se; se = se->next)
@ -1007,6 +996,8 @@ pending_signals::add (int sig)
se = sigs + empty;
se->sig = sig;
se->next = NULL;
se->tls = tls;
se->pid = pid;
if (end)
end->next = se;
end = se;
@ -1030,16 +1021,16 @@ pending_signals::del ()
curr = next;
}
int
sigelem *
pending_signals::next ()
{
int sig;
sigelem *res;
prev = curr;
if (!curr || !(curr = curr->next))
sig = 0;
res = NULL;
else
sig = curr->sig;
return sig;
res = curr;
return res;
}
/* Process signals by waiting for signal data to arrive in a pipe.
@ -1105,7 +1096,12 @@ wait_sig (VOID *self)
}
if (!pack.sig)
continue; /* Just checking to see if we exist */
{
#ifdef DEBUGGING
system_printf ("zero signal?");
#endif
continue;
}
sigset_t dummy_mask;
if (!pack.mask)
@ -1114,40 +1110,39 @@ wait_sig (VOID *self)
pack.mask = &dummy_mask;
}
sigelem *q;
switch (pack.sig)
{
case __SIGCOMMUNE:
talktome ();
continue;
break;
case __SIGSTRACE:
strace.hello ();
continue;
break;
case __SIGPENDING:
*pack.mask = 0;
unsigned bit;
sigqueue.reset ();
while ((pack.sig = sigqueue.next ()))
if (myself->getsigmask () & (bit = SIGTOMASK (pack.sig)))
while ((q = sigqueue.next ()))
if (myself->getsigmask () & (bit = SIGTOMASK (q->sig)))
*pack.mask |= bit;
break;
case __SIGFLUSH:
sigqueue.reset ();
while ((q = sigqueue.next ()))
if (sig_handle (q->sig, *pack.mask, q->pid, q->tls) > 0)
sigqueue.del ();
break;
default:
if (pack.sig < 0)
sig_clear (-pack.sig);
else
{
int sh;
for (int i = 0; !(sh = sig_handle (pack.sig, *pack.mask)) && i < 100 ; i++)
low_priority_sleep (0); // hopefully a temporary condition
if (sh <= 0)
sigqueue.add (pack.sig); // FIXME: Shouldn't add this in !sh condition
if (sig_handle (pack.sig, *pack.mask, pack.pid, pack.tls) <= 0)
sigqueue.add (pack.sig, pack.pid, pack.tls);// FIXME: Shouldn't add this in !sh condition
if (pack.sig == SIGCHLD)
proc_subproc (PROC_CLEARWAIT, 0);
}
case __SIGFLUSH:
sigqueue.reset ();
while ((pack.sig = sigqueue.next ()))
if (sig_handle (pack.sig, *pack.mask) > 0)
sigqueue.del ();
break;
}
if (pack.wakeup)
@ -1231,29 +1226,3 @@ wait_subproc (VOID *)
sigproc_printf ("done");
ExitThread (0);
}
extern "C" {
/* Provide a stack frame when calling WaitFor* functions */
#undef WaitForSingleObject
DWORD __stdcall
WFSO (HANDLE hHandle, DWORD dwMilliseconds)
{
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForSingleObject (hHandle, dwMilliseconds);
return ret;
}
#undef WaitForMultipleObjects
DWORD __stdcall
WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
{
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
return ret;
}
}