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>2011-12-04 21:58:24 +0400
committerChristopher Faylor <me@cgf.cx>2011-12-04 21:58:24 +0400
commit8f937028d9b8d387cf35b64d92056241bffabd78 (patch)
tree2ed73616733809fc902b1e33bc2370a0468ba142
parent69864e48cb0ef1efd1ac29a80b34bbc9c604533b (diff)
* exceptions.cc (exception::handle): Drop abbreviation for "exception" since I
never remember what it stands for. (sig_handle_tty_stop): Remove obsolete call to sig_handle_tty_stop. (_cygtls::call_signal_handler): Rework to grab signal information from _main_tls if none is set for _my_tls. Try harder to keep thread locked. (reset_signal_arrived): Delete. * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use new cygWFMO call to wait for an event + standard cygwin stuff. Modify debug output to acccomodate new function. * fhandler_console.cc (fhandler_console::read): Replace WaitForMultipleObjects with cygWFMO. * fhandler_socket.cc (get_inet_addr): Add comment. * gendef (_sigdelayed): Remove call to reset_signal_arrived. * sigproc.cc (_cygtls::signal_exit): Don't close my_readsig here unless we're in the signal thread. (create_signal_arrived): Create signal_arrived as auto-reset so that only one thread is woken when a signal arrives. * sigproc.h (cygWFMO): New function. (reset_signal_arrived): Delete declaration.
-rw-r--r--winsup/cygwin/ChangeLog23
-rw-r--r--winsup/cygwin/exceptions.cc46
-rw-r--r--winsup/cygwin/fhandler.cc7
-rw-r--r--winsup/cygwin/fhandler_console.cc4
-rw-r--r--winsup/cygwin/fhandler_socket.cc2
-rwxr-xr-xwinsup/cygwin/gendef1
-rw-r--r--winsup/cygwin/sigproc.cc14
-rw-r--r--winsup/cygwin/sigproc.h16
8 files changed, 82 insertions, 31 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fc37e0d12..ba23ea6d0 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,26 @@
+2011-12-04 Christopher Faylor <me.cygwin2011@cgf.cx>
+
+ * exceptions.cc (exception::handle): Drop abbreviation for "exception"
+ since I never remember what it stands for.
+ (sig_handle_tty_stop): Remove obsolete call to sig_handle_tty_stop.
+ (_cygtls::call_signal_handler): Rework to grab signal information from
+ _main_tls if none is set for _my_tls. Try harder to keep thread
+ locked.
+ (reset_signal_arrived): Delete.
+ * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use new
+ cygWFMO call to wait for an event + standard cygwin stuff. Modify
+ debug output to acccomodate new function.
+ * fhandler_console.cc (fhandler_console::read): Replace
+ WaitForMultipleObjects with cygWFMO.
+ * fhandler_socket.cc (get_inet_addr): Add comment.
+ * gendef (_sigdelayed): Remove call to reset_signal_arrived.
+ * sigproc.cc (_cygtls::signal_exit): Don't close my_readsig here unless
+ we're in the signal thread.
+ (create_signal_arrived): Create signal_arrived as auto-reset so that only
+ one thread is woken when a signal arrives.
+ * sigproc.h (cygWFMO): New function.
+ (reset_signal_arrived): Delete declaration.
+
2011-12-03 Christopher Faylor <me.cygwin2011@cgf.cx>
* mmap.cc (mlock): Add standard syscall return value debugging output.
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 5e6137ffd..c62b81662 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -600,7 +600,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
return 1;
}
- debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
+ debug_printf ("In cygwin_except_handler exception %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
debug_printf ("In cygwin_except_handler signal %d at %p", si.si_signo, in->Eip);
bool masked = !!(me.sigmask & SIGTOMASK (si.si_signo));
@@ -755,7 +755,6 @@ sig_handle_tty_stop (int sig)
{
case WAIT_OBJECT_0:
case WAIT_OBJECT_0 + 1:
- reset_signal_arrived ();
myself->stopsig = SIGCONT;
myself->alert_parent (SIGCONT);
break;
@@ -1325,25 +1324,42 @@ events_terminate ()
int
_cygtls::call_signal_handler ()
{
- int this_sa_flags = 0;
- /* Call signal handler. */
- while (sig && func)
+ int this_sa_flags = SA_RESTART;
+ while (1)
{
lock ();
+ if (sig)
+ pop ();
+ else if (this != _main_tls)
+ {
+ _main_tls->lock ();
+ if (_main_tls->sig)
+ {
+ sig = _main_tls->sig;
+ sa_flags = _main_tls->sa_flags;
+ func = _main_tls->func;
+ infodata = _main_tls->infodata;
+ _main_tls->pop ();
+ _main_tls->sig = 0;
+
+ }
+ _main_tls->unlock ();
+ }
+ if (!sig)
+ break;
+
this_sa_flags = sa_flags;
int thissig = sig;
void (*thisfunc) (int) = func;
- pop ();
- reset_signal_arrived ();
sigset_t this_oldmask = set_process_mask_delta ();
int this_errno = saved_errno;
sig = 0;
unlock (); // make sure synchronized
- incyg = 0;
if (!(this_sa_flags & SA_SIGINFO))
{
void (*sigfunc) (int) = thisfunc;
+ incyg = false;
sigfunc (thissig);
}
else
@@ -1351,27 +1367,19 @@ _cygtls::call_signal_handler ()
siginfo_t thissi = infodata;
void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) thisfunc;
/* no ucontext_t information provided yet */
+ incyg = false;
sigact (thissig, &thissi, NULL);
}
- incyg = 1;
+ incyg = true;
set_signal_mask (this_oldmask, _my_tls.sigmask);
if (this_errno >= 0)
set_errno (this_errno);
}
+ unlock ();
return this_sa_flags & SA_RESTART;
}
-extern "C" void __stdcall
-reset_signal_arrived ()
-{
- // NEEDED? WaitForSingleObject (signal_arrived, 10);
- ResetEvent (signal_arrived);
- sigproc_printf ("reset signal_arrived");
- if (_my_tls.stackptr > _my_tls.stack)
- debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
-}
-
void
_cygtls::copy_context (CONTEXT *c)
{
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 6049036b5..a29b1f235 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1925,11 +1925,8 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
}
if (res == overlapped_unknown)
{
- HANDLE w4[3] = { get_overlapped ()->hEvent, signal_arrived,
- pthread::get_cancel_event () };
- DWORD n = w4[2] ? 3 : 2;
HANDLE h = writing ? get_output_handle () : get_handle ();
- DWORD wfres = WaitForMultipleObjects (n, w4, false, INFINITE);
+ DWORD wfres = cygWFMO (1, INFINITE, get_overlapped ()->hEvent);
/* Cancelling here to prevent races. It's possible that the I/O has
completed already, in which case this is a no-op. Otherwise,
WFMO returned because 1) This is a non-blocking call, 2) a signal
@@ -1960,7 +1957,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
pthread::static_cancel_self (); /* never returns */
else
{
- debug_printf ("GetOverLappedResult failed, h %p, bytes %u, w4: %p, %p, %p %E", h, *bytes, w4[0], w4[1], w4[2]);
+ debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes);
res = overlapped_error;
}
}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 0e9717bd1..e8a8d6a08 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -333,8 +333,6 @@ fhandler_console::read (void *pv, size_t& buflen)
return;
}
- HANDLE w4[3] = { h, signal_arrived, pthread::get_cancel_event () };
- DWORD nwait = w4[2] ? 3 : 2;
DWORD timeout = is_nonblocking () ? 0 : INFINITE;
char tmp[60];
@@ -350,7 +348,7 @@ fhandler_console::read (void *pv, size_t& buflen)
set_cursor_maybe (); /* to make cursor appear on the screen immediately */
restart:
- switch (WaitForMultipleObjects (nwait, w4, FALSE, timeout))
+ switch (cygWFMO (1, timeout, h))
{
case WAIT_OBJECT_0:
break;
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index fff1083c3..17d98dc38 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -127,6 +127,8 @@ get_inet_addr (const struct sockaddr *in, int inlen,
some greedy Win32 application. Therefore we should never wait
endlessly without checking for signals and thread cancel event. */
pthread_testcancel ();
+ /* Using IsEventSignalled like this is racy since another thread could
+ be waiting for signal_arrived. */
if (IsEventSignalled (signal_arrived)
&& !_my_tls.call_signal_handler ())
{
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index e1fa0d9e4..0cd27341f 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -232,7 +232,6 @@ _sigdelayed:
pushl %eax # siginfo
pushl $tls::sig(%ebx) # signal number
- call _reset_signal_arrived\@0
pushl \$_sigreturn # where to return
pushl $tls::func(%ebx) # user-supplied signal func
cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal?
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index eef082f6f..1770b4f21 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -368,8 +368,18 @@ _cygtls::signal_exit (int rc)
{
extern void stackdump (DWORD, int, bool);
+ HANDLE myss = my_sendsig;
my_sendsig = NULL; /* Make no_signals_allowed return true */
- ForceCloseHandle (my_readsig); /* Stop any currently executing sig_sends */
+ if (&_my_tls == _sig_tls)
+ ForceCloseHandle (my_readsig); /* Stop any currently executing sig_sends */
+ else
+ {
+ sigpacket sp = {};
+ sp.si.si_signo = __SIGEXIT;
+ DWORD len;
+ WriteFile (myss, &sp, sizeof (sp), &len, NULL);
+ }
+
SetEvent (signal_arrived); /* Avoid potential deadlock with proc_lock */
if (rc == SIGQUIT || rc == SIGABRT)
@@ -493,7 +503,7 @@ create_signal_arrived ()
return;
/* local event signaled when main thread has been dispatched
to a signal handler function. */
- signal_arrived = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
+ signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
ProtectHandle (signal_arrived);
}
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index b6f17a612..086466b6f 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -59,6 +59,21 @@ struct sigpacket
};
extern HANDLE signal_arrived;
+
+static inline
+DWORD cygWFMO (DWORD n, DWORD howlong, ...)
+{
+ va_list ap;
+ va_start (ap, howlong);
+ HANDLE w4[n + 2];
+ va_start (ap, howlong);
+ unsigned i;
+ for (i = 0; i < n; i++)
+ w4[i] = va_arg (ap, HANDLE);
+ w4[i++] = signal_arrived;
+ w4[i++] = pthread::get_cancel_event ();
+ return WaitForMultipleObjects (n, w4, FALSE, howlong);
+}
extern HANDLE sigCONT;
void __stdcall sig_dispatch_pending (bool fast = false);
@@ -69,7 +84,6 @@ int __stdcall handle_sigprocmask (int sig, const sigset_t *set,
sigset_t *oldset, sigset_t& opmask)
__attribute__ ((regparm (3)));
-extern "C" void __stdcall reset_signal_arrived ();
void __stdcall sig_clear (int) __attribute__ ((regparm (1)));
void __stdcall sig_set_pending (int) __attribute__ ((regparm (1)));
int __stdcall handle_sigsuspend (sigset_t);