* cygwait.cc (cancelable_wait): Mimic old cygwait behavior more closely wrt
handling of call_signal_handler. * cygwait.h (WAIT_CANCELED): Move here and redefine. (WAIT_SIGNALED): Ditto. * thread.h (WAIT_CANCELED): Delete. (WAIT_SIGNALED): Ditto.
This commit is contained in:
parent
88fbcb5afd
commit
af5cd14583
|
@ -1,3 +1,12 @@
|
|||
2012-06-18 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||
|
||||
* cygwait.cc (cancelable_wait): Mimic old cygwait behavior more closely
|
||||
wrt handling of call_signal_handler.
|
||||
* cygwait.h (WAIT_CANCELED): Move here and redefine.
|
||||
(WAIT_SIGNALED): Ditto.
|
||||
* thread.h (WAIT_CANCELED): Delete.
|
||||
(WAIT_SIGNALED): Ditto.
|
||||
|
||||
2012-06-18 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygheap.cc (init_cygheap::init_installation_root): Rearrange code
|
||||
|
|
|
@ -43,7 +43,7 @@ ipc_set_proc_info (proc &blk)
|
|||
blk.gidcnt = 0;
|
||||
blk.gidlist = NULL;
|
||||
blk.is_admin = false;
|
||||
blk.signal_arrived = signal_arrived;
|
||||
blk.signal_arrived = _my_tls.signal_arrived;
|
||||
}
|
||||
#endif /* __INSIDE_CYGWIN__ */
|
||||
|
||||
|
|
|
@ -373,20 +373,16 @@ 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 = WaitForMultipleObjects (n, w4, FALSE, howlong))
|
||||
switch (res = cygwait (sigwait, howlong))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (n == 1)
|
||||
howlong = 50;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
case WAIT_SIGNALED:
|
||||
n = 1;
|
||||
if (i--)
|
||||
howlong = 50;
|
||||
|
@ -395,20 +391,7 @@ cygthread::detach (HANDLE sigwait)
|
|||
break;
|
||||
default:
|
||||
if (!exiting)
|
||||
{
|
||||
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");
|
||||
}
|
||||
api_fatal ("WFMO failed waiting for cygthread '%s', %E", __name);
|
||||
break;
|
||||
}
|
||||
/* WAIT_OBJECT_0 means that the thread successfully read something,
|
||||
|
|
|
@ -174,7 +174,8 @@ public:
|
|||
int sa_flags;
|
||||
sigset_t oldmask;
|
||||
sigset_t deltamask;
|
||||
HANDLE event;
|
||||
HANDLE signal_arrived;
|
||||
bool waiting;
|
||||
int *errno_addr;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigwait_mask;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@ 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,
|
||||
|
@ -26,7 +28,7 @@ DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
|
|||
__attribute__ ((regparm (3)));
|
||||
|
||||
static inline DWORD __attribute__ ((always_inline))
|
||||
cygwait (HANDLE h, DWORD howlong = INFINITE)
|
||||
cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
|
||||
{
|
||||
PLARGE_INTEGER pli_howlong;
|
||||
LARGE_INTEGER li_howlong;
|
||||
|
@ -37,7 +39,14 @@ cygwait (HANDLE h, DWORD howlong = INFINITE)
|
|||
li_howlong.QuadPart = 10000ULL * howlong;
|
||||
pli_howlong = &li_howlong;
|
||||
}
|
||||
return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig_eintr);
|
||||
|
||||
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))
|
||||
|
@ -45,3 +54,29 @@ 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -842,8 +842,6 @@ 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 ();
|
||||
|
|
|
@ -715,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
|
|||
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
|
||||
|
||||
pthread_testcancel ();
|
||||
cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
|
||||
cancelable_wait (NULL, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr);
|
||||
|
||||
set_sig_errno (EINTR); // Per POSIX
|
||||
|
||||
|
@ -748,8 +748,7 @@ sig_handle_tty_stop (int sig)
|
|||
sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
|
||||
HANDLE w4[2];
|
||||
w4[0] = sigCONT;
|
||||
w4[1] = signal_arrived;
|
||||
switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
|
||||
switch (cancelable_wait (sigCONT, NULL, cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
|
@ -1248,7 +1247,7 @@ sigpacket::process ()
|
|||
{
|
||||
sigproc_printf ("default signal %d ignored", si.si_signo);
|
||||
if (continue_now)
|
||||
SetEvent (signal_arrived);
|
||||
SetEvent (use_tls->signal_arrived);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 (IsEventSignalled (signal_arrived)
|
||||
if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED
|
||||
&& !_my_tls.call_signal_handler ())
|
||||
{
|
||||
set_errno (EINTR);
|
||||
|
@ -662,7 +662,8 @@ fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
|
|||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
WSAEVENT ev[2] = { wsock_evt, signal_arrived };
|
||||
WSAEVENT ev[2] = { wsock_evt };
|
||||
set_thread_waiting (ev[1]);
|
||||
switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
|
||||
{
|
||||
case WSA_WAIT_TIMEOUT:
|
||||
|
@ -1784,7 +1785,7 @@ fhandler_socket::close ()
|
|||
res = -1;
|
||||
break;
|
||||
}
|
||||
if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
|
||||
if (cygwait (10) == WAIT_SIGNALED)
|
||||
{
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
|
|
|
@ -1142,26 +1142,14 @@ 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 (WaitForMultipleObjects (cnt, w4, FALSE, timeout))
|
||||
switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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 (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
|
||||
if (cygwait (0) != WAIT_SIGNALED)
|
||||
{
|
||||
siginfo_t si = {0};
|
||||
si.si_signo = sig;
|
||||
|
|
|
@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||
goto out;
|
||||
}
|
||||
pthread_testcancel ();
|
||||
if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0
|
||||
if (cancelable_wait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
|
||||
&& !_my_tls.call_signal_handler ())
|
||||
{
|
||||
set_errno (EINTR);
|
||||
|
|
|
@ -96,7 +96,8 @@ fhandler_windows::read (void *buf, size_t& len)
|
|||
return;
|
||||
}
|
||||
|
||||
HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
|
||||
HANDLE w4[3] = { get_handle (), };
|
||||
set_thread_waiting (w4[1]);
|
||||
DWORD cnt = 2;
|
||||
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
|
||||
++cnt;
|
||||
|
|
|
@ -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;
|
||||
w4[wait_count++] = signal_arrived;
|
||||
set_thread_waiting (w4[wait_count++]);
|
||||
|
||||
DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
|
||||
HANDLE cancel_event = pthread::get_cancel_event ();
|
||||
|
|
|
@ -119,14 +119,12 @@ ipc_mutex_init (HANDLE *pmtx, const char *name)
|
|||
static int
|
||||
ipc_mutex_lock (HANDLE mtx)
|
||||
{
|
||||
HANDLE h[2] = { mtx, signal_arrived };
|
||||
|
||||
switch (WaitForMultipleObjects (2, h, FALSE, INFINITE))
|
||||
switch (cancelable_wait (mtx, NULL, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED_0:
|
||||
return 0;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return 1;
|
||||
default:
|
||||
|
@ -174,11 +172,12 @@ 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, signal_arrived, NULL, NULL };
|
||||
HANDLE w4[4] = { evt, };
|
||||
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)
|
||||
|
|
|
@ -312,7 +312,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
select_record *s = &start;
|
||||
DWORD m = 0;
|
||||
|
||||
w4[m++] = signal_arrived; /* Always wait for the arrival of a signal. */
|
||||
set_thread_waiting (w4[m++]);
|
||||
if ((w4[m] = pthread::get_cancel_event ()) != NULL)
|
||||
m++;
|
||||
|
||||
|
|
|
@ -120,12 +120,9 @@ 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 (signal_arrived, &timeout);
|
||||
if (rc == WAIT_OBJECT_0)
|
||||
{
|
||||
_my_tls.call_signal_handler ();
|
||||
int rc = cancelable_wait (NULL, &timeout, cw_sig | cw_cancel | cw_cancel_self);
|
||||
if (rc == WAIT_SIGNALED)
|
||||
res = EINTR;
|
||||
}
|
||||
|
||||
/* according to POSIX, rmtp is used only if !abstime */
|
||||
if (rmtp && !abstime)
|
||||
|
@ -565,21 +562,14 @@ 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 (WaitForSingleObject (h, INFINITE))
|
||||
switch (cancelable_wait (NULL, NULL, cw_sig | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
{
|
||||
set_errno (EINTR);
|
||||
|
@ -598,8 +588,6 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
|||
res = -1;
|
||||
}
|
||||
|
||||
_my_tls.event = NULL;
|
||||
CloseHandle (h);
|
||||
sigproc_printf ("returning signal %d", res);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -43,9 +43,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
|
||||
HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
|
||||
// resulted in a user-specified
|
||||
// function call
|
||||
|
||||
#define Static static NO_COPY
|
||||
|
||||
|
@ -518,17 +515,6 @@ 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
|
||||
|
|
|
@ -58,7 +58,6 @@ struct sigpacket
|
|||
int __stdcall process () __attribute__ ((regparm (1)));
|
||||
};
|
||||
|
||||
extern HANDLE signal_arrived;
|
||||
extern HANDLE sigCONT;
|
||||
|
||||
void __stdcall sig_dispatch_pending (bool fast = false);
|
||||
|
@ -86,7 +85,6 @@ 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);
|
||||
|
|
|
@ -2295,7 +2295,7 @@ retry:
|
|||
{
|
||||
debug_printf ("status %p", status);
|
||||
if (status == STATUS_SHARING_VIOLATION
|
||||
&& WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
|
||||
&& cygwait (10L) != WAIT_SIGNALED)
|
||||
{
|
||||
/* Typical BLODA problem. Some virus scanners check newly generated
|
||||
files and while doing that disallow DELETE access. That's really
|
||||
|
|
Loading…
Reference in New Issue