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>2003-11-28 23:55:59 +0300
committerChristopher Faylor <me@cgf.cx>2003-11-28 23:55:59 +0300
commit9a4d574b8d4550f53036dced342022b64e508abf (patch)
tree79d7ab65654ff5cb2fd2c0c035ac2b98deb1fcc2 /winsup/cygwin/sigproc.cc
parentffe006384344b5d2a86e6bedad96725391cfe88e (diff)
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.
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc123
1 files changed, 46 insertions, 77 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index cecbe70c3..984000478 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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;
-}
-}