diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0b70e2079..85f889852 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,90 @@ +2012-07-21 Christopher Faylor + + * DevNotes: Add entry cgf-000013. + * cygserver_ipc.h (ipc_set_proc_info): Use _cygtls::ipc_set_proc_info + to set per-thread signal arrived value. + * cygthread.cc (cygthread::detach): Use per-thread signal_arrived via + set_thread_waiting. + * fork.cc (_cygtls::fixup_after_fork): Clear signal_arrived. + (_cygtls::remove): Close any signal_arrived handle when thread exists. + (_cygtls::find_tls): Remove unneeded function. + * cygtls.h: Update copyright. + (class _cygtls): Reorganize to help avoid rebuilding newlib when + structure changes. + (_cygtls::event): Delete. + (_cygtls::threadkill): Ditto. + (_cygtls::signal_waiting): Declare new bool. + (_cygtls::find_tls): Delete declaration. + (_cygtls::set_threadkill): Ditto. + (_cygtls::reset_threadkill): Ditto. + (_cygtls::set_signal_arrived): Declare new function. + (class set_thread_waiting): Declare new class. + * cygwait.cc (cw_nowait_storage): Define. + (cygwait): Set per-thread signal_arrived via set_thread_waiting. Don't + special-case _main_tls. + * cygwait.h (cw_nowait): Define. + (cw_infinite): Ditto. + (cygwait): Redefine pathological wait-only case. + * dcrt0.cc (dll_crt0_0): Remove call to now-defunct events_init(). + (dll_crt0_1): Remove call to now-defunct create_signal_arrived(). + * exceptions.cc: Reflect set_signal_mask() argument reordering + throughout. Remove signal mask synchronization throughout. + (events_init): Delete definition. + (mask_sync): Delete now-unneeded mask synchronization. + (set_signal_mask): Reverse order of arguments to "standard" to, from + layout. Rename "newmask" argument to "setmask". Remove debugging. + (sig_handle_tty_stop): Use cancelable_wait rather than WFMO. + (_cygtls::interrupt_setup): Don't treat "threadkill" events specially. + Conditionally set signal_arrived depending on whether the thread has + created it or not. + (sigpacket::process): Reorganize to reflect thread-specific sending of + signals which is more in line with the way it was actually supposed to + work. + * fhandler_socket.cc (get_inet_addr): Use cancelable_wait rather than + IsEventSignalled to avoid potential race. + (fhandler_socket::wait_for_events): Set signal_arrived event using + set_thread_waiting(). + (fhandler_socket::close): Use cygwait for the case of just + waiting 10 ms for a signal. + * fhandler_tape.cc (fhandler_dev_tape::_lock): Use cancelable_wait + rather than WFMO. Redo switch/case tests accordingly. + * fhandler_termios.cc (fhandler_termios::bg_check): Use cygwait for + case of just waiting 0 ms for a potential signal. + * fhandler_tty.cc (fhandler_pty_master::process_slave_output): Use + cancelable_wait rather than WFSO. + * fhandler_windows.cc (fhandler_windows::read): Set per-thread + signal_arrived via set_thread_waiting(). + * flock.cc (lf_setlock): Ditto. + * select.cc (pselect): Ditto. Set per-thread signal_arrived using + set_thread_waiting(). + * gendef: Don't special case handling of _cygtls::sig for threads. + * gentls_offsets: Use #pragma once in tlsoffsets.h. + * ntdll.h: Use #pragma once. + * poll.cc: Reflect set_signal_mask() argument reordering. + * posix_ipc.cc (ipc_mutex_lock): Use cancelable_wait rather than WFMO. + (ipc_cond_timedwait): Set perl-thread signal arrived using + set_thread_waiting(). + * security.h: Use #pragma once. + * signal.cc (abort): Reflect set_signal_mask() argument reordering. + (clock_nanosleep): Ditto. Change call to cancelable_wait to properly + specify handling of cancel and interrupt. + (sigwaitinfo): Remove handling of per-thread event in favor of + per-thread signal_arrived. Use cancelable_wait rather than WFSO. + * sigproc.cc (signal_arrived): Delete definition. + (create_signal_arrived): Ditto. + * sigproc.h (signal_arrived): Delete declaration. + (set_signal_mask): Avoid defining as a "C" function. Don't + conditionally declare. + (create_signal_arrived): Delete declaration. + * syscalls.cc (rename): Use cygwait() rather than WFSO. + * thread.h (fast_mutex::lock): Use cw_infinite rather than LARGE_NULL. + * wait.cc (wait4): Ditto. + * thread.cc (pthread_mutex::lock): Ditto. + (pthread::join): Ditto. + (semaphore::_wait): Ditto. + (pthread_kill): Remove set_threadkill() accommodation. + * tlsoffsets.h: Regenerate. + 2012-07-21 Christopher Faylor * include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 17. diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes index 8e517bf84..cd8caf886 100644 --- a/winsup/cygwin/DevNotes +++ b/winsup/cygwin/DevNotes @@ -1,3 +1,24 @@ +2012-07-21 cgf-000013 + +These changes reflect a revamp of the "wait for signal" functionality +which has existed in Cygwin through several signal massages. + +We now create a signal event only when a thread is waiting for a signal +and arm it only for that thread. The "set_thread_waiting" function is +used to establish the event and set it in a location referencable by +the caller. + +I still do not handle all of the race conditions. What happens when +a signal comes in just after a WF?O succeeds for some other purpose? I +suspect that it will arm the next WF?O call and the subsequent call to +call_signal_handler could cause a function to get an EINTR when possibly +it shouldn't have. + +I haven't yet checked all of the test cases for the URL listed in the +previous entry. + +Baby steps. + 2012-06-12 cgf-000012 These changes are the preliminary for redoing the way threads wait for diff --git a/winsup/cygwin/cygserver_ipc.h b/winsup/cygwin/cygserver_ipc.h index 2f7c3531f..4dbc8212f 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 = signal_arrived; + _my_tls.set_signal_arrived (true, blk.signal_arrived); } #endif /* __INSIDE_CYGWIN__ */ diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 4cbd3b064..a9d36ff4a 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -377,7 +377,7 @@ cygthread::detach (HANDLE sigwait) unsigned n = 2; DWORD howlong = INFINITE; w4[0] = sigwait; - w4[1] = signal_arrived; + set_thread_waiting here (w4[1]); /* 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)) diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 1c8ec3348..da48622f1 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -190,6 +190,7 @@ _cygtls::fixup_after_fork () sig = 0; } stacklock = spinning = 0; + signal_arrived = NULL; locals.select.sockevt = NULL; locals.cw_timer = NULL; wq.thread_ev = NULL; @@ -214,6 +215,13 @@ _cygtls::remove (DWORD wait) /* FIXME: Need some sort of atthreadexit function to allow things like select to control this themselves. */ + if (signal_arrived) + { + HANDLE h = signal_arrived; + signal_arrived = NULL; + CloseHandle (h); + } + /* Close handle and free memory used by select. */ if (locals.select.sockevt) { @@ -254,31 +262,6 @@ _cygtls::push (__stack_t addr) *stackptr++ = (__stack_t) addr; } - -_cygtls * -_cygtls::find_tls (int sig) -{ - static int NO_COPY threadlist_ix; - - debug_printf ("signal %d\n", sig); - sentry here (INFINITE); - - _cygtls *res = NULL; - threadlist_ix = -1; - - myfault efault; - if (efault.faulted ()) - cygheap->threadlist[threadlist_ix]->remove (INFINITE); - - while (++threadlist_ix < (int) nthreads) - if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig)) - { - res = cygheap->threadlist[threadlist_ix]; - break; - } - return res; -} - void _cygtls::set_siginfo (sigpacket *pack) { diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 40c6151c2..03e44dcc2 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -1,13 +1,12 @@ /* cygtls.h - Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011 Red Hat, Inc. + Copyright 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifndef _CYGTLS_H -#define _CYGTLS_H +#pragma once #include #include @@ -158,6 +157,7 @@ typedef struct struct_waitq /*gentls_offsets*/ #include "cygerrno.h" +#include "security.h" extern "C" int __sjfault (jmp_buf); extern "C" int __ljfault (jmp_buf, int); @@ -169,27 +169,29 @@ typedef __uint32_t __stack_t; class _cygtls { public: - void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/; - int saved_errno; - int sa_flags; - sigset_t oldmask; - sigset_t deltamask; - HANDLE event; - int *errno_addr; - sigset_t sigmask; - sigset_t sigwait_mask; - siginfo_t *sigwait_info; - struct ucontext thread_context; - DWORD thread_id; - unsigned threadkill; - siginfo_t infodata; - struct pthread *tid; + /* Please keep these two declarations first */ + struct _local_storage locals; union { struct _reent local_clib; char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)]; }; - struct _local_storage locals; + /**/ + void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/; + int saved_errno; + int sa_flags; + sigset_t oldmask; + sigset_t deltamask; + int *errno_addr; + sigset_t sigmask; + sigset_t sigwait_mask; + siginfo_t *sigwait_info; + HANDLE signal_arrived; + bool signal_waiting; + struct ucontext thread_context; + DWORD thread_id; + siginfo_t infodata; + struct pthread *tid; class cygthread *_ctinfo; class san *andreas; waitq wq; @@ -205,7 +207,6 @@ public: static void init (); void init_thread (void *, DWORD (*) (void *, void *)); static void call (DWORD (*) (void *, void *), void *); - static struct _cygtls *find_tls (int sig); void remove (DWORD); void push (__stack_t) __attribute__ ((regparm (2))); __stack_t pop () __attribute__ ((regparm (1))); @@ -229,14 +230,24 @@ public: operator HANDLE () const {return tid->win32_obj_id;} #endif void set_siginfo (struct sigpacket *) __attribute__ ((regparm (3))); - void set_threadkill () {threadkill = true;} - void reset_threadkill () {threadkill = false;} int call_signal_handler () __attribute__ ((regparm (1))); void remove_wq (DWORD) __attribute__ ((regparm (1))); void fixup_after_fork () __attribute__ ((regparm (1))); void lock () __attribute__ ((regparm (1))); void unlock () __attribute__ ((regparm (1))); bool locked () __attribute__ ((regparm (1))); + void set_signal_arrived (bool setit, HANDLE& h) + { + if (!setit) + signal_waiting = false; + else + { + if (!signal_arrived) + signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL); + h = signal_arrived; + signal_waiting = true; + } + } private: void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3))); /*gentls_offsets*/ @@ -304,6 +315,15 @@ public: } }; -#define __getreent() (&_my_tls.local_clib) +class set_thread_waiting +{ +public: + set_thread_waiting (bool setit, HANDLE& h) { _my_tls.set_signal_arrived (setit, h); } + set_thread_waiting (HANDLE& h) { _my_tls.set_signal_arrived (true, h); } -#endif /*_CYGTLS_H*/ /*gentls_offsets*/ + operator int () const {return _my_tls.signal_waiting;} + ~set_thread_waiting () { _my_tls.signal_waiting = false; } +}; + +#define __getreent() (&_my_tls.local_clib) +/*gentls_offsets*/ diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc index f6eb0a3a7..c48e1e1bd 100644 --- a/winsup/cygwin/cygwait.cc +++ b/winsup/cygwin/cygwait.cc @@ -21,6 +21,8 @@ #define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr)) +LARGE_INTEGER cw_nowait_storage; + DWORD cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) { @@ -36,14 +38,13 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) if (object) wait_objects[num++] = object; + set_thread_waiting thread_waiting (is_cw_sig_handle, wait_objects[num]); +debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_tls.signal_arrived); DWORD sig_n; - if (!is_cw_sig_handle) + if (!thread_waiting) sig_n = WAIT_TIMEOUT + 1; else - { - sig_n = WAIT_OBJECT_0 + num++; - wait_objects[sig_n] = signal_arrived; - } + sig_n = WAIT_OBJECT_0 + num++; DWORD cancel_n; if (!is_cw_cancel || !pthread::is_good_object (&thread) || @@ -79,7 +80,7 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) /* all set */; else if (is_cw_sig_eintr) res = WAIT_SIGNALED; /* caller will deal with signals */ - else if (_my_tls.call_signal_handler () || &_my_tls != _main_tls) + else if (_my_tls.call_signal_handler ()) continue; break; } diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h index 0303ec3b6..d52a145ae 100644 --- a/winsup/cygwin/cygwait.h +++ b/winsup/cygwin/cygwait.h @@ -22,7 +22,10 @@ enum cw_wait_mask cw_sig_eintr = 0x0008 }; -#define LARGE_NULL ((PLARGE_INTEGER) NULL) +extern LARGE_INTEGER cw_nowait_storage; +#define cw_nowait (&cw_nowait_storage) +#define cw_infinite ((PLARGE_INTEGER) NULL) + const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig; DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL, @@ -53,5 +56,5 @@ cygwait (HANDLE h, DWORD howlong = INFINITE) static inline DWORD __attribute__ ((always_inline)) cygwait (DWORD howlong) { - return cancelable_wait (NULL, howlong, cw_cancel | cw_sig_eintr); + return cygwait (NULL, howlong); } diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 70b962889..c1df0a2f6 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -774,9 +774,6 @@ dll_crt0_0 () user_data->threadinterface->Init (); _cygtls::init (); - - /* Initialize events */ - events_init (); tty_list::init_session (); _main_tls = &_my_tls; @@ -843,8 +840,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 (); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 5ace52b5b..91517fd58 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -19,8 +19,8 @@ details. */ #include #include -#include "pinfo.h" #include "cygtls.h" +#include "pinfo.h" #include "sigproc.h" #include "shared_info.h" #include "perprocess.h" @@ -31,7 +31,6 @@ details. */ #include "child_info.h" #include "ntdll.h" #include "exception.h" -#include "cygwait.h" #define CALL_HANDLER_RETRY_OUTER 10 #define CALL_HANDLER_RETRY_INNER 10 @@ -47,7 +46,6 @@ static BOOL WINAPI ctrl_c_handler (DWORD); /* This is set to indicate that we have already exited. */ static NO_COPY int exit_already = 0; -static muto NO_COPY mask_sync; NO_COPY static struct { @@ -710,11 +708,11 @@ handle_sigsuspend (sigset_t tempmask) { sigset_t oldmask = _my_tls.sigmask; // Remember for restoration - set_signal_mask (tempmask, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, tempmask); sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); pthread_testcancel (); - cancelable_wait (signal_arrived, LARGE_NULL, cw_cancel | cw_cancel_self); + cancelable_wait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr); set_sig_errno (EINTR); // Per POSIX @@ -747,8 +745,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, cw_infinite, cw_sig_eintr)) { case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: @@ -804,20 +801,11 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) this->sig = sig; // Should always be last thing set to avoid a race - if (!event) - threadkill = false; - else - { - HANDLE h = event; - event = NULL; - SetEvent (h); - } + if (signal_arrived) + SetEvent (signal_arrived); - /* Clear any waiting threads prior to dispatching to handler function */ - int res = SetEvent (signal_arrived); // For an EINTR case proc_subproc (PROC_CLEARWAIT, 1); - sigproc_printf ("armed signal_arrived %p, signal %d, res %d", signal_arrived, - sig, res); + sigproc_printf ("armed signal_arrived %p, signal %d", signal_arrived, sig); } extern "C" void __stdcall @@ -1021,7 +1009,7 @@ ctrl_c_handler (DWORD type) extern "C" void __stdcall set_process_mask (sigset_t newmask) { - set_signal_mask (newmask, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, newmask); } extern "C" int @@ -1034,11 +1022,9 @@ sighold (int sig) syscall_printf ("signal %d out of range", sig); return -1; } - mask_sync.acquire (INFINITE); sigset_t mask = _my_tls.sigmask; sigaddset (&mask, sig); - set_signal_mask (mask, _my_tls.sigmask); - mask_sync.release (); + set_signal_mask (_my_tls.sigmask, mask); return 0; } @@ -1052,11 +1038,9 @@ sigrelse (int sig) syscall_printf ("signal %d out of range", sig); return -1; } - mask_sync.acquire (INFINITE); sigset_t mask = _my_tls.sigmask; sigdelset (&mask, sig); - set_signal_mask (mask, _my_tls.sigmask); - mask_sync.release (); + set_signal_mask (_my_tls.sigmask, mask); return 0; } @@ -1074,7 +1058,6 @@ sigset (int sig, _sig_func_ptr func) return (_sig_func_ptr) SIG_ERR; } - mask_sync.acquire (INFINITE); sigset_t mask = _my_tls.sigmask; /* If sig was in the signal mask return SIG_HOLD, otherwise return the previous disposition. */ @@ -1093,8 +1076,7 @@ sigset (int sig, _sig_func_ptr func) signal (sig, func); sigdelset (&mask, sig); } - set_signal_mask (mask, _my_tls.sigmask); - mask_sync.release (); + set_signal_mask (_my_tls.sigmask, mask); return prev; } @@ -1109,7 +1091,6 @@ sigignore (int sig) extern "C" sigset_t set_process_mask_delta () { - mask_sync.acquire (INFINITE); sigset_t newmask, oldmask; if (_my_tls.deltamask & SIG_NONMASKABLE) @@ -1120,28 +1101,22 @@ set_process_mask_delta () sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask, _my_tls.deltamask); _my_tls.sigmask = newmask; - mask_sync.release (); return oldmask; } /* Set the signal mask for this process. Note that some signals are unmaskable, as in UNIX. */ -extern "C" void __stdcall -set_signal_mask (sigset_t newmask, sigset_t& oldmask) + +void +set_signal_mask (sigset_t& setmask, sigset_t newmask) { -#ifdef CGF - if (&_my_tls == _sig_tls) - small_printf ("********* waiting in signal thread\n"); -#endif - mask_sync.acquire (INFINITE); newmask &= ~SIG_NONMASKABLE; - sigset_t mask_bits = oldmask & ~newmask; - sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask, + sigset_t mask_bits = setmask & ~newmask; + sigproc_printf ("setmask %p, newmask %p, mask_bits %p", setmask, newmask, mask_bits); - oldmask = newmask; + setmask = newmask; if (mask_bits) sig_dispatch_pending (true); - mask_sync.release (); } int __stdcall @@ -1184,17 +1159,23 @@ sigpacket::process () myself->rusage_self.ru_nsignals++; - bool masked; - void *handler; - if (!have_execed || (void *) thissig.sa_handler == (void *) SIG_IGN) - handler = (void *) thissig.sa_handler; - else if (tls) - return 1; - else + void *handler = (void *) thissig.sa_handler; + if (handler == SIG_IGN) + { + sigproc_printf ("signal %d ignored", si.si_signo); + goto done; + } + + if (have_execed) handler = NULL; - _cygtls *use_tls = tls ?: _main_tls; - sigproc_printf ("tls %p, use_tls %p", tls, use_tls); + if (tls) + sigproc_printf ("using tls %p", tls); + else + { + tls = _main_tls; + sigproc_printf ("using main tls %p", _main_tls); + } if (si.si_signo == SIGKILL) goto exit_sig; @@ -1204,30 +1185,12 @@ sigpacket::process () goto stop; } - bool insigwait_mask; - if ((masked = ISSTATE (myself, PID_STOPPED))) - insigwait_mask = false; - else if (tls) - insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo); - else if (!(tls = _cygtls::find_tls (si.si_signo))) - insigwait_mask = false; - else + if (sigismember (&tls->sigwait_mask, si.si_signo)) { - use_tls = tls; - insigwait_mask = true; + tls->sigwait_mask = 0; + goto dosig; } - - if (insigwait_mask) - goto thread_specific; - - if (masked) - /* nothing to do */; - else if (sigismember (mask, si.si_signo)) - masked = true; - else if (tls) - masked = sigismember (&tls->sigmask, si.si_signo); - - if (masked) + if (sigismember (&tls->sigmask, si.si_signo) || ISSTATE (myself, PID_STOPPED)) { sigproc_printf ("signal %d blocked", si.si_signo); rc = -1; @@ -1240,14 +1203,12 @@ sigpacket::process () if (handler == (void *) SIG_DFL) { - if (insigwait_mask) - goto thread_specific; if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH || si.si_signo == SIGURG) { sigproc_printf ("default signal %d ignored", si.si_signo); if (continue_now) - SetEvent (signal_arrived); + SetEvent (tls->signal_arrived); goto done; } @@ -1257,16 +1218,9 @@ sigpacket::process () goto exit_sig; } - if (handler == (void *) SIG_IGN) - { - sigproc_printf ("signal %d ignored", si.si_signo); - goto done; - } - if (handler == (void *) SIG_ERR) goto exit_sig; - use_tls->set_siginfo (this); goto dosig; stop: @@ -1277,33 +1231,19 @@ stop: thissig = dummy; dosig: + tls->set_siginfo (this); /* Dispatch to the appropriate function. */ - sigproc_printf ("signal %d, about to call %p", si.si_signo, handler); - rc = setup_handler (si.si_signo, handler, thissig, use_tls); + sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); + rc = setup_handler (si.si_signo, handler, thissig, tls); done: - tls = use_tls; if (continue_now) SetEvent (sigCONT); sigproc_printf ("returning %d", rc); return rc; -thread_specific: - use_tls->sig = si.si_signo; - use_tls->set_siginfo (this); - use_tls->func = NULL; - sigproc_printf ("releasing sigwait for thread"); - SetEvent (use_tls->event); - goto done; - exit_sig: - use_tls->signal_exit (si.si_signo); /* never returns */ -} - -void -events_init () -{ - mask_sync.init ("mask_sync"); + tls->signal_exit (si.si_signo); /* never returns */ } void @@ -1321,23 +1261,7 @@ _cygtls::call_signal_handler () lock (); if (sig) pop (); - else if (this != _main_tls) - { - _main_tls->lock (); - if (_main_tls->sig && _main_tls->incyg) - { - paranoid_printf ("Redirecting to main_tls signal %d", _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) + else break; debug_only_printf ("dealing with signal %d", sig); @@ -1364,7 +1288,7 @@ _cygtls::call_signal_handler () sigact (thissig, &thissi, NULL); } incyg = true; - set_signal_mask (this_oldmask, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, this_oldmask); if (this_errno >= 0) set_errno (this_errno); } diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index cb6d376fd..971df6896 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -125,9 +125,7 @@ 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) + if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED && !_my_tls.call_signal_handler ()) { set_errno (EINTR); @@ -659,7 +657,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 here (ev[1]); switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE)) { case WSA_WAIT_TIMEOUT: @@ -1778,7 +1777,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; diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index da2458217..855fd5dfd 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -1147,26 +1147,13 @@ 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; diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 7fddba5b3..690f08fa2 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 (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0) + if (cygwait ((DWORD) 0) != WAIT_SIGNALED) { siginfo_t si = {0}; si.si_signo = sig; diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 519558a3d..c29d36594 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 (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); diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc index c89d98e16..11fb6c0a0 100644 --- a/winsup/cygwin/fhandler_windows.cc +++ b/winsup/cygwin/fhandler_windows.cc @@ -96,43 +96,47 @@ 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 here (w4[1]); DWORD cnt = 2; if ((w4[cnt] = pthread::get_cancel_event ()) != NULL) ++cnt; -restart: - switch (MsgWaitForMultipleObjectsEx (cnt, w4, - is_nonblocking () ? 0 : INFINITE, - QS_ALLINPUT | QS_ALLPOSTMESSAGE, - MWMO_INPUTAVAILABLE)) + for (;;) { - case WAIT_OBJECT_0: - if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE)) + switch (MsgWaitForMultipleObjectsEx (cnt, w4, + is_nonblocking () ? 0 : INFINITE, + QS_ALLINPUT | QS_ALLPOSTMESSAGE, + MWMO_INPUTAVAILABLE)) { + case WAIT_OBJECT_0: + if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE)) + { + len = (size_t) -1; + __seterrno (); + } + else if (ptr->message == WM_QUIT) + len = 0; + else + len = sizeof (MSG); + break; + case WAIT_OBJECT_0 + 1: + if (_my_tls.call_signal_handler ()) + continue; + len = (size_t) -1; + set_errno (EINTR); + break; + case WAIT_OBJECT_0 + 2: + pthread::static_cancel_self (); + break; + case WAIT_TIMEOUT: + len = (size_t) -1; + set_errno (EAGAIN); + break; + default: len = (size_t) -1; __seterrno (); + break; } - else if (ptr->message == WM_QUIT) - len = 0; - else - len = sizeof (MSG); - break; - case WAIT_OBJECT_0 + 1: - if (_my_tls.call_signal_handler ()) - goto restart; - len = (size_t) -1; - set_errno (EINTR); - break; - case WAIT_OBJECT_0 + 2: - pthread::static_cancel_self (); - break; - case WAIT_TIMEOUT: - len = (size_t) -1; - set_errno (EAGAIN); - break; - default: - len = (size_t) -1; - __seterrno (); break; } } diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index 0a4bdf0d1..9a5c8dae6 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; - w4[wait_count++] = signal_arrived; + set_thread_waiting here (w4[wait_count++]); DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1; HANDLE cancel_event = pthread::get_cancel_event (); diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index a76711279..3dcea174a 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -202,8 +202,6 @@ _sigdelayed: pushl \$_sigreturn # where to return pushl $tls::func(%ebx) # user-supplied signal func - cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal? - jnz 4f # yes. callee clears signal number movl \$0,$tls::sig(%ebx) # zero the signal number as a # flag to the signal handler thread # that it is ok to set up sigsave diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets index 2c96487d4..17deb41fd 100755 --- a/winsup/cygwin/gentls_offsets +++ b/winsup/cygwin/gentls_offsets @@ -14,10 +14,10 @@ my $struct = ''; my @fields = (); my $def = ''; $tls = join('', ); +$tls =~ s/\A.*\n#pragma once\n//os; $tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os; my $pre = $`; substr($tls, 0, length($pre)) = ''; -$pre =~ s/\n#ifndef _[^\n]+\n/\n/os; $pre .= "\n//*/"; $tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs; foreach ($tls =~ /^.*\n/mg) { diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index dda3c2d20..2ca6a5ab3 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -9,8 +9,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifndef _NTDLL_H -#define _NTDLL_H 1 +#pragma once #ifndef __MINGW64_VERSION_MAJOR # include @@ -1425,4 +1424,3 @@ extern "C" } } #endif -#endif /*_NTDLL_H*/ diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc index ea86ab5aa..cbb68bf04 100644 --- a/winsup/cygwin/poll.cc +++ b/winsup/cygwin/poll.cc @@ -152,9 +152,9 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, ? -1 : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); if (sigmask) - set_signal_mask (*sigmask, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, *sigmask); int ret = poll (fds, nfds, timeout); if (sigmask) - set_signal_mask (oldset, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, oldset); return ret; } diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index b9d224e43..a8141f10c 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -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, cw_infinite, 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 here (w4[1]); if ((w4[cnt] = pthread::get_cancel_event ()) != NULL) ++cnt; if (abstime) diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index f80dcfbd7..2ac101a69 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -9,8 +9,7 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifndef _SECURITY_H -#define _SECURITY_H +#pragma once #include @@ -513,5 +512,3 @@ sec_user (SECURITY_ATTRIBUTES *sa_buf, PSID sid1, PSID sid2 = NULL, { return __sec_user (sa_buf, sid1, sid2, access2, TRUE); } - -#endif /*_SECURITY_H*/ diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 6d1250cf4..bab2c01d3 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -100,20 +100,28 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_printf ("select(%d, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to); pthread_testcancel (); - - /* Convert to milliseconds or INFINITE if to == NULL */ - DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE; - if (ms == 0 && to->tv_usec) - ms = 1; /* At least 1 ms granularity */ - - if (to) - select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms); + int res; + if (maxfds < 0) + { + set_errno (EINVAL); + res = -1; + } else - select_printf ("to NULL, ms %x", ms); + { + /* Convert to milliseconds or INFINITE if to == NULL */ + DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE; + if (ms == 0 && to->tv_usec) + ms = 1; /* At least 1 ms granularity */ - int res = select (maxfds, readfds ?: allocfd_set (maxfds), + if (to) + select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms); + else + select_printf ("to NULL, ms %x", ms); + + res = select (maxfds, readfds ?: allocfd_set (maxfds), writefds ?: allocfd_set (maxfds), exceptfds ?: allocfd_set (maxfds), ms); + } syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds, writefds, exceptfds, to); return res; @@ -179,6 +187,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, else res = sel.wait (r, w, e, ms); /* wait for an fd to become become active or time out */ + select_printf ("res %d", res); if (res >= 0) { copyfd_set (readfds, r, maxfds); @@ -197,7 +206,10 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_printf ("recalculating ms"); LONGLONG now = gtod.msecs (); if (now > (start_time + ms)) - select_printf ("timed out after verification"); + { + select_printf ("timed out after verification"); + res = select_stuff::select_error; + } else { ms -= (now - start_time); @@ -228,11 +240,11 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, tv.tv_usec = ts->tv_nsec / 1000; } if (set) - set_signal_mask (*set, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, *set); int ret = cygwin_select (maxfds, readfds, writefds, exceptfds, ts ? &tv : NULL); if (set) - set_signal_mask (oldset, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, oldset); return ret; } @@ -320,7 +332,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 here (w4[m++]); if ((w4[m] = pthread::get_cancel_event ()) != NULL) m++; diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 3fac7cbb0..8590b32df 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -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 (); - res = EINTR; - } + 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) @@ -226,7 +223,7 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op newmask = *set; break; } - set_signal_mask (newmask, opmask); + set_signal_mask (opmask, newmask); } return 0; } @@ -379,7 +376,7 @@ abort (void) sigset_t sig_mask; sigfillset (&sig_mask); sigdelset (&sig_mask, SIGABRT); - set_signal_mask (sig_mask, _my_tls.sigmask); + set_signal_mask (_my_tls.sigmask, sig_mask); raise (SIGABRT); _my_tls.call_signal_handler (); /* Call any signal handler */ @@ -568,21 +565,18 @@ 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; + myfault efault; + if (efault.faulted (EFAULT)) + return EFAULT; + + set_signal_mask (_my_tls.sigwait_mask, *set); sig_dispatch_pending (true); int res; - switch (WaitForSingleObject (h, INFINITE)) + switch (cancelable_wait (NULL, cw_infinite, 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); @@ -593,6 +587,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) if (info) *info = _my_tls.infodata; res = _my_tls.infodata.si_signo; + /* FIXME: Is this right? */ InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0); } break; @@ -601,8 +596,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; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 05d98729f..dcfbcbc55 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -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 @@ -1233,7 +1219,7 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child) int might_match; waitq *w = parent_w->next; - sigproc_printf ("considering pid %d", child->pid); + sigproc_printf ("considering pid %d, pgid %d, w->pid %d", child->pid, child->pgid, w->pid); if (w->pid == -1) might_match = 1; else if (w->pid == 0) diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index d980f1a6e..1374e9bea 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -58,13 +58,11 @@ struct sigpacket int __stdcall process () __attribute__ ((regparm (1))); }; -extern HANDLE signal_arrived; extern HANDLE sigCONT; -void __stdcall sig_dispatch_pending (bool fast = false); -#ifdef EXITCODE_SET -extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t&); -#endif +void __stdcall sig_dispatch_pending (bool fast = false) + __attribute__ ((regparm (1))); +void set_signal_mask (sigset_t&, sigset_t) __attribute__ ((regparm (2))); int __stdcall handle_sigprocmask (int sig, const sigset_t *set, sigset_t *oldset, sigset_t& opmask) __attribute__ ((regparm (3))); @@ -86,7 +84,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); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 2077a0a3c..c0cacac97 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 - && 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 diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 5caf5ca73..aefab24cd 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1744,7 +1744,7 @@ pthread_mutex::lock () || !pthread::equal (owner, self)) { /* FIXME: no cancel? */ - cancelable_wait (win32_obj_id, LARGE_NULL, cw_sig); + cancelable_wait (win32_obj_id, cw_infinite, cw_sig); set_owner (self); } else @@ -2364,7 +2364,7 @@ pthread::join (pthread_t *thread, void **return_val) (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED; (*thread)->mutex.unlock (); - switch (cancelable_wait ((*thread)->win32_obj_id, LARGE_NULL, cw_sig | cw_cancel)) + switch (cancelable_wait ((*thread)->win32_obj_id, cw_infinite, cw_sig | cw_cancel)) { case WAIT_OBJECT_0: if (return_val) @@ -3015,10 +3015,7 @@ pthread_kill (pthread_t thread, int sig) if (!thread->valid) rval = ESRCH; else if (sig) - { - thread->cygtls->set_threadkill (); - rval = sig_send (NULL, si, thread->cygtls); - } + rval = sig_send (NULL, si, thread->cygtls); else switch (WaitForSingleObject (thread->win32_obj_id, 0)) { @@ -3501,7 +3498,7 @@ semaphore::_timedwait (const struct timespec *abstime) int semaphore::_wait () { - switch (cancelable_wait (win32_obj_id, LARGE_NULL, cw_cancel | cw_cancel_self | cw_sig_eintr)) + switch (cancelable_wait (win32_obj_id, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr)) { case WAIT_OBJECT_0: currentvalue--; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index a4f5a952c..141100714 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -60,7 +60,7 @@ public: void lock () { if (InterlockedIncrement ((long *) &lock_counter) != 1) - cancelable_wait (win32_obj_id, LARGE_NULL, cw_sig); + cancelable_wait (win32_obj_id, cw_infinite, cw_sig); } void unlock () diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 18057742c..3acd27a19 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -1,42 +1,42 @@ //;# autogenerated: Do not edit. //; $tls::sizeof__cygtls = 4048; -//; $tls::func = -12700; -//; $tls::pfunc = 0; -//; $tls::saved_errno = -12696; -//; $tls::psaved_errno = 4; -//; $tls::sa_flags = -12692; -//; $tls::psa_flags = 8; -//; $tls::oldmask = -12688; -//; $tls::poldmask = 12; -//; $tls::deltamask = -12684; -//; $tls::pdeltamask = 16; -//; $tls::event = -12680; -//; $tls::pevent = 20; -//; $tls::errno_addr = -12676; -//; $tls::perrno_addr = 24; -//; $tls::sigmask = -12672; -//; $tls::psigmask = 28; -//; $tls::sigwait_mask = -12668; -//; $tls::psigwait_mask = 32; -//; $tls::sigwait_info = -12664; -//; $tls::psigwait_info = 36; -//; $tls::thread_context = -12660; -//; $tls::pthread_context = 40; -//; $tls::thread_id = -12448; -//; $tls::pthread_id = 252; -//; $tls::threadkill = -12444; -//; $tls::pthreadkill = 256; -//; $tls::infodata = -12440; -//; $tls::pinfodata = 260; -//; $tls::tid = -12292; -//; $tls::ptid = 408; -//; $tls::local_clib = -12288; -//; $tls::plocal_clib = 412; -//; $tls::__dontuse = -12288; -//; $tls::p__dontuse = 412; -//; $tls::locals = -11200; -//; $tls::plocals = 1500; +//; $tls::locals = -12700; +//; $tls::plocals = 0; +//; $tls::local_clib = -11236; +//; $tls::plocal_clib = 1464; +//; $tls::__dontuse = -11236; +//; $tls::p__dontuse = 1464; +//; $tls::func = -10148; +//; $tls::pfunc = 2552; +//; $tls::saved_errno = -10144; +//; $tls::psaved_errno = 2556; +//; $tls::sa_flags = -10140; +//; $tls::psa_flags = 2560; +//; $tls::oldmask = -10136; +//; $tls::poldmask = 2564; +//; $tls::deltamask = -10132; +//; $tls::pdeltamask = 2568; +//; $tls::errno_addr = -10128; +//; $tls::perrno_addr = 2572; +//; $tls::sigmask = -10124; +//; $tls::psigmask = 2576; +//; $tls::sigwait_mask = -10120; +//; $tls::psigwait_mask = 2580; +//; $tls::sigwait_info = -10116; +//; $tls::psigwait_info = 2584; +//; $tls::signal_arrived = -10112; +//; $tls::psignal_arrived = 2588; +//; $tls::signal_waiting = -10108; +//; $tls::psignal_waiting = 2592; +//; $tls::thread_context = -10104; +//; $tls::pthread_context = 2596; +//; $tls::thread_id = -9892; +//; $tls::pthread_id = 2808; +//; $tls::infodata = -9888; +//; $tls::pinfodata = 2812; +//; $tls::tid = -9740; +//; $tls::ptid = 2960; //; $tls::_ctinfo = -9736; //; $tls::p_ctinfo = 2964; //; $tls::andreas = -9732; @@ -59,42 +59,42 @@ //; $tls::pinitialized = 4044; //; __DATA__ -#define tls_func (-12700) -#define tls_pfunc (0) -#define tls_saved_errno (-12696) -#define tls_psaved_errno (4) -#define tls_sa_flags (-12692) -#define tls_psa_flags (8) -#define tls_oldmask (-12688) -#define tls_poldmask (12) -#define tls_deltamask (-12684) -#define tls_pdeltamask (16) -#define tls_event (-12680) -#define tls_pevent (20) -#define tls_errno_addr (-12676) -#define tls_perrno_addr (24) -#define tls_sigmask (-12672) -#define tls_psigmask (28) -#define tls_sigwait_mask (-12668) -#define tls_psigwait_mask (32) -#define tls_sigwait_info (-12664) -#define tls_psigwait_info (36) -#define tls_thread_context (-12660) -#define tls_pthread_context (40) -#define tls_thread_id (-12448) -#define tls_pthread_id (252) -#define tls_threadkill (-12444) -#define tls_pthreadkill (256) -#define tls_infodata (-12440) -#define tls_pinfodata (260) -#define tls_tid (-12292) -#define tls_ptid (408) -#define tls_local_clib (-12288) -#define tls_plocal_clib (412) -#define tls___dontuse (-12288) -#define tls_p__dontuse (412) -#define tls_locals (-11200) -#define tls_plocals (1500) +#define tls_locals (-12700) +#define tls_plocals (0) +#define tls_local_clib (-11236) +#define tls_plocal_clib (1464) +#define tls___dontuse (-11236) +#define tls_p__dontuse (1464) +#define tls_func (-10148) +#define tls_pfunc (2552) +#define tls_saved_errno (-10144) +#define tls_psaved_errno (2556) +#define tls_sa_flags (-10140) +#define tls_psa_flags (2560) +#define tls_oldmask (-10136) +#define tls_poldmask (2564) +#define tls_deltamask (-10132) +#define tls_pdeltamask (2568) +#define tls_errno_addr (-10128) +#define tls_perrno_addr (2572) +#define tls_sigmask (-10124) +#define tls_psigmask (2576) +#define tls_sigwait_mask (-10120) +#define tls_psigwait_mask (2580) +#define tls_sigwait_info (-10116) +#define tls_psigwait_info (2584) +#define tls_signal_arrived (-10112) +#define tls_psignal_arrived (2588) +#define tls_signal_waiting (-10108) +#define tls_psignal_waiting (2592) +#define tls_thread_context (-10104) +#define tls_pthread_context (2596) +#define tls_thread_id (-9892) +#define tls_pthread_id (2808) +#define tls_infodata (-9888) +#define tls_pinfodata (2812) +#define tls_tid (-9740) +#define tls_ptid (2960) #define tls__ctinfo (-9736) #define tls_p_ctinfo (2964) #define tls_andreas (-9732) diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc index 714a9e26e..ae0403194 100644 --- a/winsup/cygwin/wait.cc +++ b/winsup/cygwin/wait.cc @@ -80,7 +80,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r) if ((waitfor = w->ev) == NULL) goto nochildren; - res = cancelable_wait (waitfor, LARGE_NULL, cw_cancel | cw_cancel_self); + res = cancelable_wait (waitfor, cw_infinite, cw_cancel | cw_cancel_self); sigproc_printf ("%d = cancelable_wait (...)", res);