Revert errneous checkin.

Check in actual change associated with ChangeLog.
This commit is contained in:
Christopher Faylor 2012-06-19 00:38:02 +00:00
parent af5cd14583
commit 2addde8cb1
20 changed files with 95 additions and 77 deletions

View File

@ -43,7 +43,7 @@ ipc_set_proc_info (proc &blk)
blk.gidcnt = 0; blk.gidcnt = 0;
blk.gidlist = NULL; blk.gidlist = NULL;
blk.is_admin = false; blk.is_admin = false;
blk.signal_arrived = _my_tls.signal_arrived; blk.signal_arrived = signal_arrived;
} }
#endif /* __INSIDE_CYGWIN__ */ #endif /* __INSIDE_CYGWIN__ */

View File

@ -373,16 +373,20 @@ cygthread::detach (HANDLE sigwait)
LONG prio = GetThreadPriority (hth); LONG prio = GetThreadPriority (hth);
::SetThreadPriority (hth, THREAD_PRIORITY_BELOW_NORMAL); ::SetThreadPriority (hth, THREAD_PRIORITY_BELOW_NORMAL);
HANDLE w4[2];
unsigned n = 2;
DWORD howlong = INFINITE; DWORD howlong = INFINITE;
w4[0] = sigwait;
w4[1] = signal_arrived;
/* For a description of the below loop see the end of this file */ /* For a description of the below loop see the end of this file */
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
switch (res = cygwait (sigwait, howlong)) switch (res = WaitForMultipleObjects (n, w4, FALSE, howlong))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
if (n == 1) if (n == 1)
howlong = 50; howlong = 50;
break; break;
case WAIT_SIGNALED: case WAIT_OBJECT_0 + 1:
n = 1; n = 1;
if (i--) if (i--)
howlong = 50; howlong = 50;
@ -391,7 +395,20 @@ cygthread::detach (HANDLE sigwait)
break; break;
default: default:
if (!exiting) 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; break;
} }
/* WAIT_OBJECT_0 means that the thread successfully read something, /* WAIT_OBJECT_0 means that the thread successfully read something,

View File

@ -174,8 +174,7 @@ public:
int sa_flags; int sa_flags;
sigset_t oldmask; sigset_t oldmask;
sigset_t deltamask; sigset_t deltamask;
HANDLE signal_arrived; HANDLE event;
bool waiting;
int *errno_addr; int *errno_addr;
sigset_t sigmask; sigset_t sigmask;
sigset_t sigwait_mask; sigset_t sigwait_mask;

View File

@ -21,8 +21,6 @@
#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr)) #define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
TIMER_BASIC_INFORMATION cw_nowait;
DWORD DWORD
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
{ {
@ -85,11 +83,8 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
/* all set */; /* all set */;
else if (is_cw_sig_eintr) else if (is_cw_sig_eintr)
res = WAIT_SIGNALED; res = WAIT_SIGNALED;
else else if (_my_tls.call_signal_handler () || &_my_tls != _main_tls)
{ continue;
_my_tls.call_signal_handler ();
continue;
}
break; break;
} }

View File

@ -11,6 +11,9 @@
#pragma once #pragma once
#define WAIT_CANCELED (WAIT_OBJECT_0 + 2)
#define WAIT_SIGNALED (WAIT_OBJECT_0 + 1)
enum cw_wait_mask enum cw_wait_mask
{ {
cw_cancel = 0x0001, cw_cancel = 0x0001,
@ -19,8 +22,6 @@ enum cw_wait_mask
cw_sig_eintr = 0x0008 cw_sig_eintr = 0x0008
}; };
extern TIMER_BASIC_INFORMATION cw_nowait;
const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig; const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL, DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
@ -28,7 +29,7 @@ DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
__attribute__ ((regparm (3))); __attribute__ ((regparm (3)));
static inline DWORD __attribute__ ((always_inline)) static inline DWORD __attribute__ ((always_inline))
cancelable_wait (HANDLE h, DWORD howlong, unsigned mask) cygwait (HANDLE h, DWORD howlong = INFINITE)
{ {
PLARGE_INTEGER pli_howlong; PLARGE_INTEGER pli_howlong;
LARGE_INTEGER li_howlong; LARGE_INTEGER li_howlong;
@ -39,14 +40,7 @@ cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
li_howlong.QuadPart = 10000ULL * howlong; li_howlong.QuadPart = 10000ULL * howlong;
pli_howlong = &li_howlong; pli_howlong = &li_howlong;
} }
return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig);
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);
} }
static inline DWORD __attribute__ ((always_inline)) static inline DWORD __attribute__ ((always_inline))
@ -54,29 +48,3 @@ cygwait (DWORD howlong)
{ {
return cygwait ((HANDLE) NULL, 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);
}
}
};

View File

@ -842,6 +842,8 @@ dll_crt0_1 (void *)
strace.microseconds (); strace.microseconds ();
#endif #endif
create_signal_arrived (); /* FIXME: move into wait_sig? */
/* Initialize debug muto, if DLL is built with --enable-debugging. /* Initialize debug muto, if DLL is built with --enable-debugging.
Need to do this before any helper threads start. */ Need to do this before any helper threads start. */
debug_init (); debug_init ();

View File

@ -715,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
pthread_testcancel (); 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 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); sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
HANDLE w4[2]; HANDLE w4[2];
w4[0] = sigCONT; 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:
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
@ -1247,7 +1248,7 @@ sigpacket::process ()
{ {
sigproc_printf ("default signal %d ignored", si.si_signo); sigproc_printf ("default signal %d ignored", si.si_signo);
if (continue_now) if (continue_now)
SetEvent (use_tls->signal_arrived); SetEvent (signal_arrived);
goto done; goto done;
} }

View File

@ -130,7 +130,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
pthread_testcancel (); pthread_testcancel ();
/* Using IsEventSignalled like this is racy since another thread could /* Using IsEventSignalled like this is racy since another thread could
be waiting for signal_arrived. */ 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 ()) && !_my_tls.call_signal_handler ())
{ {
set_errno (EINTR); set_errno (EINTR);
@ -662,8 +662,7 @@ fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
return SOCKET_ERROR; return SOCKET_ERROR;
} }
WSAEVENT ev[2] = { wsock_evt }; WSAEVENT ev[2] = { wsock_evt, signal_arrived };
set_thread_waiting (ev[1]);
switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE)) switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
{ {
case WSA_WAIT_TIMEOUT: case WSA_WAIT_TIMEOUT:
@ -1785,7 +1784,7 @@ fhandler_socket::close ()
res = -1; res = -1;
break; break;
} }
if (cygwait (10) == WAIT_SIGNALED) if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
{ {
set_errno (EINTR); set_errno (EINTR);
res = -1; res = -1;

View File

@ -1142,14 +1142,26 @@ mtinfo::initialize ()
inline bool inline bool
fhandler_dev_tape::_lock (bool cancelable) 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 /* O_NONBLOCK is only valid in a read or write call. Only those are
cancelable. */ cancelable. */
DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE; DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE;
restart: restart:
switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self)) switch (WaitForMultipleObjects (cnt, w4, FALSE, timeout))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
return true; 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: case WAIT_TIMEOUT:
set_errno (EAGAIN); set_errno (EAGAIN);
return false; return false;

View File

@ -204,7 +204,7 @@ fhandler_termios::bg_check (int sig)
{ {
/* Don't raise a SIGTT* signal if we have already been /* Don't raise a SIGTT* signal if we have already been
interrupted by another signal. */ interrupted by another signal. */
if (cygwait (0) != WAIT_SIGNALED) if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
{ {
siginfo_t si = {0}; siginfo_t si = {0};
si.si_signo = sig; si.si_signo = sig;

View File

@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
goto out; goto out;
} }
pthread_testcancel (); 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 ()) && !_my_tls.call_signal_handler ())
{ {
set_errno (EINTR); set_errno (EINTR);

View File

@ -96,8 +96,7 @@ fhandler_windows::read (void *buf, size_t& len)
return; return;
} }
HANDLE w4[3] = { get_handle (), }; HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
set_thread_waiting (w4[1]);
DWORD cnt = 2; DWORD cnt = 2;
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL) if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
++cnt; ++cnt;

View File

@ -1247,7 +1247,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
timeout = 100L; timeout = 100L;
DWORD WAIT_SIGNAL_ARRIVED = WAIT_OBJECT_0 + wait_count; 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; DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
HANDLE cancel_event = pthread::get_cancel_event (); HANDLE cancel_event = pthread::get_cancel_event ();

View File

@ -119,12 +119,14 @@ ipc_mutex_init (HANDLE *pmtx, const char *name)
static int static int
ipc_mutex_lock (HANDLE mtx) 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_OBJECT_0:
case WAIT_ABANDONED_0: case WAIT_ABANDONED_0:
return 0; return 0;
case WAIT_SIGNALED: case WAIT_OBJECT_0 + 1:
set_errno (EINTR); set_errno (EINTR);
return 1; return 1;
default: default:
@ -172,12 +174,11 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
static int static int
ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime) 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 cnt = 2;
DWORD timer_idx = 0; DWORD timer_idx = 0;
int ret = 0; int ret = 0;
set_thread_waiting (w4[1]);
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL) if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
++cnt; ++cnt;
if (abstime) if (abstime)

View File

@ -312,7 +312,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
select_record *s = &start; select_record *s = &start;
DWORD m = 0; 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) if ((w4[m] = pthread::get_cancel_event ()) != NULL)
m++; m++;

View File

@ -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); 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); int rc = cancelable_wait (signal_arrived, &timeout);
if (rc == WAIT_SIGNALED) if (rc == WAIT_OBJECT_0)
res = EINTR; {
_my_tls.call_signal_handler ();
res = EINTR;
}
/* according to POSIX, rmtp is used only if !abstime */ /* according to POSIX, rmtp is used only if !abstime */
if (rmtp && !abstime) if (rmtp && !abstime)
@ -562,14 +565,21 @@ extern "C" int
sigwaitinfo (const sigset_t *set, siginfo_t *info) sigwaitinfo (const sigset_t *set, siginfo_t *info)
{ {
pthread_testcancel (); 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; _my_tls.sigwait_mask = *set;
sig_dispatch_pending (true); sig_dispatch_pending (true);
int res; 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)) if (!sigismember (set, _my_tls.infodata.si_signo))
{ {
set_errno (EINTR); set_errno (EINTR);
@ -588,6 +598,8 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
res = -1; res = -1;
} }
_my_tls.event = NULL;
CloseHandle (h);
sigproc_printf ("returning signal %d", res); sigproc_printf ("returning signal %d", res);
return res; return res;
} }

View File

@ -43,6 +43,9 @@ int __sp_ln;
char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
// current process but no wait is required // 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 #define Static static NO_COPY
@ -515,6 +518,17 @@ sig_dispatch_pending (bool fast)
sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH); 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. /* Signal thread initialization. Called from dll_crt0_1.
This routine starts the signal handling thread. */ This routine starts the signal handling thread. */
void __stdcall void __stdcall

View File

@ -58,6 +58,7 @@ struct sigpacket
int __stdcall process () __attribute__ ((regparm (1))); int __stdcall process () __attribute__ ((regparm (1)));
}; };
extern HANDLE signal_arrived;
extern HANDLE sigCONT; extern HANDLE sigCONT;
void __stdcall sig_dispatch_pending (bool fast = false); 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))); int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_exec (); void __stdcall signal_fixup_after_exec ();
void __stdcall sigalloc (); void __stdcall sigalloc ();
void __stdcall create_signal_arrived ();
int kill_pgrp (pid_t, siginfo_t&); int kill_pgrp (pid_t, siginfo_t&);
int killsys (pid_t, int); int killsys (pid_t, int);

View File

@ -2295,7 +2295,7 @@ retry:
{ {
debug_printf ("status %p", status); debug_printf ("status %p", status);
if (status == STATUS_SHARING_VIOLATION 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 /* Typical BLODA problem. Some virus scanners check newly generated
files and while doing that disallow DELETE access. That's really files and while doing that disallow DELETE access. That's really

View File

@ -344,9 +344,6 @@ public:
pthread_spinlock (int); pthread_spinlock (int);
}; };
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
#define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
class _cygtls; class _cygtls;
class pthread: public verifyable_object class pthread: public verifyable_object
{ {