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>2012-06-19 04:38:02 +0400
committerChristopher Faylor <me@cgf.cx>2012-06-19 04:38:02 +0400
commit2addde8cb1e794a9818b9417839524dbc05401da (patch)
tree389e9271ffc3ea88d97116b52fa8e838889ab12f /winsup/cygwin
parentaf5cd145835d35519af02d0d226f67eb777e4945 (diff)
Revert errneous checkin.
Check in actual change associated with ChangeLog.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/cygserver_ipc.h2
-rw-r--r--winsup/cygwin/cygthread.cc23
-rw-r--r--winsup/cygwin/cygtls.h3
-rw-r--r--winsup/cygwin/cygwait.cc9
-rw-r--r--winsup/cygwin/cygwait.h42
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/exceptions.cc7
-rw-r--r--winsup/cygwin/fhandler_socket.cc7
-rw-r--r--winsup/cygwin/fhandler_tape.cc14
-rw-r--r--winsup/cygwin/fhandler_termios.cc2
-rw-r--r--winsup/cygwin/fhandler_tty.cc2
-rw-r--r--winsup/cygwin/fhandler_windows.cc3
-rw-r--r--winsup/cygwin/flock.cc2
-rw-r--r--winsup/cygwin/posix_ipc.cc9
-rw-r--r--winsup/cygwin/select.cc2
-rw-r--r--winsup/cygwin/signal.cc22
-rw-r--r--winsup/cygwin/sigproc.cc14
-rw-r--r--winsup/cygwin/sigproc.h2
-rw-r--r--winsup/cygwin/syscalls.cc2
-rw-r--r--winsup/cygwin/thread.h3
20 files changed, 95 insertions, 77 deletions
diff --git a/winsup/cygwin/cygserver_ipc.h b/winsup/cygwin/cygserver_ipc.h
index 31eea3464..2f7c3531f 100644
--- a/winsup/cygwin/cygserver_ipc.h
+++ b/winsup/cygwin/cygserver_ipc.h
@@ -43,7 +43,7 @@ ipc_set_proc_info (proc &blk)
blk.gidcnt = 0;
blk.gidlist = NULL;
blk.is_admin = false;
- blk.signal_arrived = _my_tls.signal_arrived;
+ blk.signal_arrived = signal_arrived;
}
#endif /* __INSIDE_CYGWIN__ */
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index 604521c58..4cbd3b064 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -373,16 +373,20 @@ cygthread::detach (HANDLE sigwait)
LONG prio = GetThreadPriority (hth);
::SetThreadPriority (hth, THREAD_PRIORITY_BELOW_NORMAL);
+ HANDLE w4[2];
+ unsigned n = 2;
DWORD howlong = INFINITE;
+ w4[0] = sigwait;
+ w4[1] = signal_arrived;
/* For a description of the below loop see the end of this file */
for (int i = 0; i < 2; i++)
- switch (res = cygwait (sigwait, howlong))
+ switch (res = WaitForMultipleObjects (n, w4, FALSE, howlong))
{
case WAIT_OBJECT_0:
if (n == 1)
howlong = 50;
break;
- case WAIT_SIGNALED:
+ case WAIT_OBJECT_0 + 1:
n = 1;
if (i--)
howlong = 50;
@@ -391,7 +395,20 @@ cygthread::detach (HANDLE sigwait)
break;
default:
if (!exiting)
- api_fatal ("WFMO failed waiting for cygthread '%s', %E", __name);
+ {
+ system_printf ("WFMO failed waiting for cygthread '%s', %E", __name);
+ for (unsigned j = 0; j < n; j++)
+ switch (WaitForSingleObject (w4[j], 0))
+ {
+ case WAIT_OBJECT_0:
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ system_printf ("%s handle %p is bad", (j ? "signal_arrived" : "semaphore"), w4[j]);
+ break;
+ }
+ api_fatal ("exiting on fatal error");
+ }
break;
}
/* WAIT_OBJECT_0 means that the thread successfully read something,
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index e4240984e..40c6151c2 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -174,8 +174,7 @@ public:
int sa_flags;
sigset_t oldmask;
sigset_t deltamask;
- HANDLE signal_arrived;
- bool waiting;
+ HANDLE event;
int *errno_addr;
sigset_t sigmask;
sigset_t sigwait_mask;
diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc
index 377012a1a..9b22bd01f 100644
--- a/winsup/cygwin/cygwait.cc
+++ b/winsup/cygwin/cygwait.cc
@@ -21,8 +21,6 @@
#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
-TIMER_BASIC_INFORMATION cw_nowait;
-
DWORD
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
{
@@ -85,11 +83,8 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
/* all set */;
else if (is_cw_sig_eintr)
res = WAIT_SIGNALED;
- else
- {
- _my_tls.call_signal_handler ();
- continue;
- }
+ else if (_my_tls.call_signal_handler () || &_my_tls != _main_tls)
+ continue;
break;
}
diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h
index a7daf88eb..9b2be02ac 100644
--- a/winsup/cygwin/cygwait.h
+++ b/winsup/cygwin/cygwait.h
@@ -11,6 +11,9 @@
#pragma once
+#define WAIT_CANCELED (WAIT_OBJECT_0 + 2)
+#define WAIT_SIGNALED (WAIT_OBJECT_0 + 1)
+
enum cw_wait_mask
{
cw_cancel = 0x0001,
@@ -19,8 +22,6 @@ enum cw_wait_mask
cw_sig_eintr = 0x0008
};
-extern TIMER_BASIC_INFORMATION cw_nowait;
-
const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
@@ -28,7 +29,7 @@ DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
__attribute__ ((regparm (3)));
static inline DWORD __attribute__ ((always_inline))
-cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
+cygwait (HANDLE h, DWORD howlong = INFINITE)
{
PLARGE_INTEGER pli_howlong;
LARGE_INTEGER li_howlong;
@@ -39,14 +40,7 @@ cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
li_howlong.QuadPart = 10000ULL * howlong;
pli_howlong = &li_howlong;
}
-
- return cancelable_wait (h, pi_howlong, mask);
-}
-
-static inline DWORD __attribute__ ((always_inline))
-cygwait (HANDLE h, DWORD howlong = INFINITE)
-{
- return cancelable_wait (h, howlong, cw_cancel | cw_sig_eintr);
+ return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig);
}
static inline DWORD __attribute__ ((always_inline))
@@ -54,29 +48,3 @@ cygwait (DWORD howlong)
{
return cygwait ((HANDLE) NULL, howlong);
}
-
-class set_thread_waiting
-{
- void doit (bool setit, DWORD& here)
- {
- if (setit)
- {
- if (_my_tls.signal_arrived == NULL)
- _my_tls.signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
- here = _my_tls.signal_arrived;
- _my_tls.waiting = true;
- }
- }
-public:
- set_thread_waiting (bool setit, DWORD& here) { doit (setit, here); }
- set_thread_waiting (DWORD& here) { doit (true, here); }
-
- ~set_thread_waiting ()
- {
- if (_my_tls.waiting)
- {
- _my_tls.waiting = false;
- ResetEvent (_my_tls.signal_arrived);
- }
- }
-};
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 71b3d2ac3..e28aecde9 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -842,6 +842,8 @@ dll_crt0_1 (void *)
strace.microseconds ();
#endif
+ create_signal_arrived (); /* FIXME: move into wait_sig? */
+
/* Initialize debug muto, if DLL is built with --enable-debugging.
Need to do this before any helper threads start. */
debug_init ();
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index fe233cf49..3c22e35c3 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -715,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
pthread_testcancel ();
- cancelable_wait (NULL, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr);
+ cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
set_sig_errno (EINTR); // Per POSIX
@@ -748,7 +748,8 @@ sig_handle_tty_stop (int sig)
sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
HANDLE w4[2];
w4[0] = sigCONT;
- switch (cancelable_wait (sigCONT, NULL, cw_sig_eintr))
+ w4[1] = signal_arrived;
+ switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
{
case WAIT_OBJECT_0:
case WAIT_OBJECT_0 + 1:
@@ -1247,7 +1248,7 @@ sigpacket::process ()
{
sigproc_printf ("default signal %d ignored", si.si_signo);
if (continue_now)
- SetEvent (use_tls->signal_arrived);
+ SetEvent (signal_arrived);
goto done;
}
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 611e70619..f78002801 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -130,7 +130,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
pthread_testcancel ();
/* Using IsEventSignalled like this is racy since another thread could
be waiting for signal_arrived. */
- if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED
+ if (IsEventSignalled (signal_arrived)
&& !_my_tls.call_signal_handler ())
{
set_errno (EINTR);
@@ -662,8 +662,7 @@ fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
return SOCKET_ERROR;
}
- WSAEVENT ev[2] = { wsock_evt };
- set_thread_waiting (ev[1]);
+ WSAEVENT ev[2] = { wsock_evt, signal_arrived };
switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
{
case WSA_WAIT_TIMEOUT:
@@ -1785,7 +1784,7 @@ fhandler_socket::close ()
res = -1;
break;
}
- if (cygwait (10) == WAIT_SIGNALED)
+ if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
{
set_errno (EINTR);
res = -1;
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc
index 2e936c3b1..c394d862d 100644
--- a/winsup/cygwin/fhandler_tape.cc
+++ b/winsup/cygwin/fhandler_tape.cc
@@ -1142,14 +1142,26 @@ mtinfo::initialize ()
inline bool
fhandler_dev_tape::_lock (bool cancelable)
{
+ HANDLE w4[3] = { mt_mtx, signal_arrived, NULL };
+ DWORD cnt = 2;
+ if (cancelable && (w4[2] = pthread::get_cancel_event ()) != NULL)
+ cnt = 3;
/* O_NONBLOCK is only valid in a read or write call. Only those are
cancelable. */
DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE;
restart:
- switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self))
+ switch (WaitForMultipleObjects (cnt, w4, FALSE, timeout))
{
case WAIT_OBJECT_0:
return true;
+ case WAIT_OBJECT_0 + 1:
+ if (_my_tls.call_signal_handler ())
+ goto restart;
+ set_errno (EINTR);
+ return false;
+ case WAIT_OBJECT_0 + 2:
+ pthread::static_cancel_self ();
+ /*NOTREACHED*/
case WAIT_TIMEOUT:
set_errno (EAGAIN);
return false;
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 3bfa38a6b..7fddba5b3 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -204,7 +204,7 @@ fhandler_termios::bg_check (int sig)
{
/* Don't raise a SIGTT* signal if we have already been
interrupted by another signal. */
- if (cygwait (0) != WAIT_SIGNALED)
+ if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
{
siginfo_t si = {0};
si.si_signo = sig;
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index c5f1d4618..fe7e283a9 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
goto out;
}
pthread_testcancel ();
- if (cancelable_wait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
+ if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0
&& !_my_tls.call_signal_handler ())
{
set_errno (EINTR);
diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc
index b592e3217..c89d98e16 100644
--- a/winsup/cygwin/fhandler_windows.cc
+++ b/winsup/cygwin/fhandler_windows.cc
@@ -96,8 +96,7 @@ fhandler_windows::read (void *buf, size_t& len)
return;
}
- HANDLE w4[3] = { get_handle (), };
- set_thread_waiting (w4[1]);
+ HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
DWORD cnt = 2;
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
++cnt;
diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc
index f40c1e5c6..176e4869e 100644
--- a/winsup/cygwin/flock.cc
+++ b/winsup/cygwin/flock.cc
@@ -1247,7 +1247,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
timeout = 100L;
DWORD WAIT_SIGNAL_ARRIVED = WAIT_OBJECT_0 + wait_count;
- set_thread_waiting (w4[wait_count++]);
+ w4[wait_count++] = signal_arrived;
DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
HANDLE cancel_event = pthread::get_cancel_event ();
diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc
index b427d11d6..b9d224e43 100644
--- a/winsup/cygwin/posix_ipc.cc
+++ b/winsup/cygwin/posix_ipc.cc
@@ -119,12 +119,14 @@ ipc_mutex_init (HANDLE *pmtx, const char *name)
static int
ipc_mutex_lock (HANDLE mtx)
{
- switch (cancelable_wait (mtx, NULL, cw_sig_eintr | cw_cancel | cw_cancel_self))
+ HANDLE h[2] = { mtx, signal_arrived };
+
+ switch (WaitForMultipleObjects (2, h, FALSE, INFINITE))
{
case WAIT_OBJECT_0:
case WAIT_ABANDONED_0:
return 0;
- case WAIT_SIGNALED:
+ case WAIT_OBJECT_0 + 1:
set_errno (EINTR);
return 1;
default:
@@ -172,12 +174,11 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
static int
ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
{
- HANDLE w4[4] = { evt, };
+ HANDLE w4[4] = { evt, signal_arrived, NULL, NULL };
DWORD cnt = 2;
DWORD timer_idx = 0;
int ret = 0;
- set_thread_waiting (w4[1]);
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
++cnt;
if (abstime)
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index d98e13255..0186af733 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -312,7 +312,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
select_record *s = &start;
DWORD m = 0;
- set_thread_waiting (w4[m++]);
+ w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
if ((w4[m] = pthread::get_cancel_event ()) != NULL)
m++;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 595bb01d7..a62c038cd 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -120,9 +120,12 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp,
syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec);
- int rc = cancelable_wait (NULL, &timeout, cw_sig | cw_cancel | cw_cancel_self);
- if (rc == WAIT_SIGNALED)
- res = EINTR;
+ int rc = cancelable_wait (signal_arrived, &timeout);
+ if (rc == WAIT_OBJECT_0)
+ {
+ _my_tls.call_signal_handler ();
+ res = EINTR;
+ }
/* according to POSIX, rmtp is used only if !abstime */
if (rmtp && !abstime)
@@ -562,14 +565,21 @@ extern "C" int
sigwaitinfo (const sigset_t *set, siginfo_t *info)
{
pthread_testcancel ();
+ HANDLE h;
+ h = _my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
+ if (!h)
+ {
+ __seterrno ();
+ return -1;
+ }
_my_tls.sigwait_mask = *set;
sig_dispatch_pending (true);
int res;
- switch (cancelable_wait (NULL, NULL, cw_sig | cw_cancel | cw_cancel_self))
+ switch (WaitForSingleObject (h, INFINITE))
{
- case WAIT_SIGNALED:
+ case WAIT_OBJECT_0:
if (!sigismember (set, _my_tls.infodata.si_signo))
{
set_errno (EINTR);
@@ -588,6 +598,8 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
res = -1;
}
+ _my_tls.event = NULL;
+ CloseHandle (h);
sigproc_printf ("returning signal %d", res);
return res;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 56fce1663..05d98729f 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -43,6 +43,9 @@ 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
+HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
+ // resulted in a user-specified
+ // function call
#define Static static NO_COPY
@@ -515,6 +518,17 @@ sig_dispatch_pending (bool fast)
sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
}
+void __stdcall
+create_signal_arrived ()
+{
+ if (signal_arrived)
+ return;
+ /* local event signaled when main thread has been dispatched
+ to a signal handler function. */
+ signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
+ ProtectHandle (signal_arrived);
+}
+
/* Signal thread initialization. Called from dll_crt0_1.
This routine starts the signal handling thread. */
void __stdcall
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index ba8a231b9..d980f1a6e 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -58,6 +58,7 @@ struct sigpacket
int __stdcall process () __attribute__ ((regparm (1)));
};
+extern HANDLE signal_arrived;
extern HANDLE sigCONT;
void __stdcall sig_dispatch_pending (bool fast = false);
@@ -85,6 +86,7 @@ int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attri
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_exec ();
void __stdcall sigalloc ();
+void __stdcall create_signal_arrived ();
int kill_pgrp (pid_t, siginfo_t&);
int killsys (pid_t, int);
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index c0cacac97..2077a0a3c 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2295,7 +2295,7 @@ retry:
{
debug_printf ("status %p", status);
if (status == STATUS_SHARING_VIOLATION
- && cygwait (10L) != WAIT_SIGNALED)
+ && WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
{
/* Typical BLODA problem. Some virus scanners check newly generated
files and while doing that disallow DELETE access. That's really
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 0dd9b893b..62a06f60b 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -344,9 +344,6 @@ public:
pthread_spinlock (int);
};
-#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
-#define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
-
class _cygtls;
class pthread: public verifyable_object
{