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