* DevNotes: Add entry cgf-000012.
* Makefile.in (DLL_OFILES): Add cygwait.o.
* sigproc.h: Remove cygwait definitions.
* cygwait.h: New file. Define/declare Cygwin waitfor functions.
* cygwait.cc: Ditto.
* exceptions.cc: Include cygwait.h.
(handle_sigsuspend): Accommodate change in cancelable_wait arguments.
(sigpacket::process): Display thread tls in debugging output.
* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic names
for signal and cancel return.
* fhandler_console.cc (fhandler_console::read): Ditto.
(fhandler_dev_dsp::Audio_out::waitforspace): Ditto.
fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
* fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
* fhandler_tty.cc (fhandler_pty_slave::read): Ditto.
* select.cc (cygwin_select): Ditto.
* wait.cc (wait4): Ditto.
* thread.cc (cancelable_wait): Move definition to cygwait.h.
(pthread_cond::wait): Accommodate change in cancelable_wait arguments.
(pthread_mutex::lock): Ditto.
(pthread_spinlock::lock): Ditto.
(pthread::join): Ditto.
(pthread::thread_init_wrapper): Display tls in debugging output.
(semaphore::_timedwait): Ditto.
* thread.h (cw_sig_wait): Move to cygwait.h.
(cw_cancel_action): Delete.
(cancelable_wait): Move declaration to cygwait.h.
+2012-06-17 Christopher Faylor <me.cygwin2012@cgf.cx>
+
+ Add '#include "cygwait.h"' throughout, where appropriate.
+ * DevNotes: Add entry cgf-000012.
+ * Makefile.in (DLL_OFILES): Add cygwait.o.
+ * sigproc.h: Remove cygwait definitions.
+ * cygwait.h: New file. Define/declare Cygwin waitfor functions.
+ * cygwait.cc: Ditto.
+ * exceptions.cc: Include cygwait.h.
+ (handle_sigsuspend): Accommodate change in cancelable_wait arguments.
+ (sigpacket::process): Display thread tls in debugging output.
+ * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic
+ names for signal and cancel return.
+ * fhandler_console.cc (fhandler_console::read): Ditto.
+ (fhandler_dev_dsp::Audio_out::waitforspace): Ditto.
+ fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
+ * fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
+ * fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
+ * fhandler_tty.cc (fhandler_pty_slave::read): Ditto.
+ * select.cc (cygwin_select): Ditto.
+ * wait.cc (wait4): Ditto.
+ * thread.cc (cancelable_wait): Move definition to cygwait.h.
+ (pthread_cond::wait): Accommodate change in cancelable_wait arguments.
+ (pthread_mutex::lock): Ditto.
+ (pthread_spinlock::lock): Ditto.
+ (pthread::join): Ditto.
+ (pthread::thread_init_wrapper): Display tls in debugging output.
+ (semaphore::_timedwait): Ditto.
+ * thread.h (cw_sig_wait): Move to cygwait.h.
+ (cw_cancel_action): Delete.
+ (cancelable_wait): Move declaration to cygwait.h.
+
2012-06-11 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
* regex/regcomp.c (p_ere): Allow vertical-line following
+2012-06-12 cgf-000012
+
+These changes are the preliminary for redoing the way threads wait for
+signals. The problems are shown by the test case mentioned here:
+
+http://cygwin.com/ml/cygwin/2012-05/msg00434.html
+
+I've known that the signal handling in threads wasn't quite right for
+some time. I lost all of my thread signal tests in the great "rm -r"
+debacle of a few years ago and have been less than enthusiastic about
+redoing everything (I had PCTS tests and everyting). But it really is
+time to redo this signal handling to make it more like it is supposed to
+be.
+
+This change should not introduce any new behavior. Things should
+continue to behave as before. The major differences are a change in the
+arguments to cancelable_wait and cygwait now uses cancelable_wait and,
+so, the returns from cygwait now mirror cancelable_wait.
+
+The next change will consolidate cygwait and cancelable_wait into one
+cygwait function.
+
2012-06-02 cgf-000011
The refcnt handling was tricky to get right but I had convinced myself
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a
MT_SAFE_OBJECTS:=
-# Please maintain this list in sorted order, with maximum files per 86 col line
#
DLL_OFILES:=advapi32.o assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o \
- cygthread.o cygtls.o cygxdr.o dcrt0.o debug.o devices.o dir.o dlfcn.o \
- dll_init.o dtable.o environ.o errno.o exceptions.o exec.o external.o \
- fcntl.o fenv.o fhandler.o fhandler_clipboard.o fhandler_console.o \
- fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o fhandler_fifo.o \
- fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o fhandler_netdrive.o \
- fhandler_nodevice.o fhandler_proc.o fhandler_process.o fhandler_procnet.o \
- fhandler_procsys.o fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
+ cygthread.o cygtls.o cygwait.o cygxdr.o dcrt0.o debug.o devices.o \
+ dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \
+ exec.o external.o fcntl.o fenv.o fhandler.o fhandler_clipboard.o \
+ fhandler_console.o fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o \
+ fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o \
+ fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
+ fhandler_process.o fhandler_procnet.o fhandler_procsys.o \
+ fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
--- /dev/null
+/* cygwait.h
+
+ Copyright 2011, 2012 Red Hat, Inc.
+
+ This file is part of Cygwin.
+
+ This software is a copyrighted work licensed under the terms of the
+ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+ details. */
+
+#include "winsup.h"
+#include "sigproc.h"
+#include "cygwait.h"
+#include "ntdll.h"
+
+#define is_cw_cancel (mask & cw_cancel)
+#define is_cw_cancel_self (mask & cw_cancel_self)
+#define is_cw_sig (mask & cw_sig)
+#define is_cw_sig_eintr (mask & cw_sig_eintr)
+#define is_cw_sig_return (mask & cw_sig_return)
+
+#define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
+
+DWORD
+cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
+{
+ DWORD res;
+ DWORD num = 0;
+ HANDLE wait_objects[4];
+ pthread_t thread = pthread::self ();
+
+ /* Do not change the wait order.
+ The object must have higher priority than the cancel event,
+ because WaitForMultipleObjects will return the smallest index
+ if both objects are signaled. */
+ if (object)
+ wait_objects[num++] = object;
+
+ DWORD sig_n;
+ if (!is_cw_sig_handle)
+ sig_n = WAIT_TIMEOUT + 1;
+ else
+ {
+ sig_n = WAIT_OBJECT_0 + num++;
+ wait_objects[sig_n] = signal_arrived;
+ }
+
+ DWORD cancel_n;
+ if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
+ thread->cancelstate == PTHREAD_CANCEL_DISABLE)
+ cancel_n = WAIT_TIMEOUT + 1;
+ else
+ {
+ cancel_n = WAIT_OBJECT_0 + num++;
+ wait_objects[cancel_n] = thread->cancel_event;
+ }
+
+ DWORD timeout_n;
+ if (!timeout)
+ timeout_n = WAIT_TIMEOUT + 1;
+ else
+ {
+ timeout_n = WAIT_OBJECT_0 + num++;
+ if (!_my_tls.locals.cw_timer)
+ NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
+ NotificationTimer);
+ NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
+ wait_objects[timeout_n] = _my_tls.locals.cw_timer;
+ }
+
+ while (1)
+ {
+ res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
+ if (res == cancel_n)
+ {
+ if (is_cw_cancel_self)
+ pthread::static_cancel_self ();
+ res = WAIT_CANCELED;
+ }
+ else if (res == timeout_n)
+ res = WAIT_TIMEOUT;
+ else if (res != sig_n)
+ /* all set */;
+ else if (is_cw_sig_eintr)
+ res = WAIT_SIGNALED;
+ else
+ {
+ _my_tls.call_signal_handler ();
+ continue;
+ }
+ break;
+ }
+
+ if (timeout)
+ {
+ TIMER_BASIC_INFORMATION tbi;
+
+ NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
+ sizeof tbi, NULL);
+ /* if timer expired, TimeRemaining is negative and represents the
+ system uptime when signalled */
+ if (timeout->QuadPart < 0LL)
+ timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
+ NtCancelTimer (_my_tls.locals.cw_timer, NULL);
+ }
+
+ return res;
+}
--- /dev/null
+/* cygwait.h
+
+ Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Red Hat, Inc.
+
+ This file is part of Cygwin.
+
+ This software is a copyrighted work licensed under the terms of the
+ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+ details. */
+
+#pragma once
+
+enum cw_wait_mask
+{
+ cw_cancel = 0x0001,
+ cw_cancel_self = 0x0002,
+ cw_sig = 0x0004,
+ cw_sig_eintr = 0x0008
+};
+
+const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
+
+DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
+ unsigned = cw_std_mask)
+ __attribute__ ((regparm (3)));
+
+static inline DWORD __attribute__ ((always_inline))
+cygwait (HANDLE h, DWORD howlong = INFINITE)
+{
+ PLARGE_INTEGER pli_howlong;
+ LARGE_INTEGER li_howlong;
+ if (howlong == INFINITE)
+ pli_howlong = NULL;
+ else
+ {
+ li_howlong.QuadPart = 10000ULL * howlong;
+ pli_howlong = &li_howlong;
+ }
+ return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig_eintr);
+}
+
+static inline DWORD __attribute__ ((always_inline))
+cygwait (DWORD howlong)
+{
+ return cygwait ((HANDLE) NULL, howlong);
+}
#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
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
pthread_testcancel ();
- cancelable_wait (signal_arrived);
+ cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
set_sig_errno (EINTR); // Per POSIX
handler = NULL;
_cygtls *use_tls = tls ?: _main_tls;
+ sigproc_printf ("tls %p, use_tls %p", tls, use_tls);
if (si.si_signo == SIGKILL)
goto exit_sig;
#include "sigproc.h"
#include "shared_info.h"
#include <asm/socket.h>
+#include "cygwait.h"
#define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
#define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
case WAIT_OBJECT_0:
err = ERROR_INVALID_HANDLE;
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
err = ERROR_INVALID_AT_INTERRUPT_TIME;
break;
default:
#include <asm/socket.h>
#include "sync.h"
#include "child_info.h"
+#include "cygwait.h"
/* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer
is allocated using tmp_pathbuf!!! */
{
case WAIT_OBJECT_0:
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
goto sig_exit;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_CANCELED:
process_state.pop ();
pthread::static_cancel_self ();
/*NOTREACHED*/
#include "dtable.h"
#include "cygheap.h"
#include "sigproc.h"
+#include "cygwait.h"
/*------------------------------------------------------------------------
Simple encapsulation of the win32 audio device.
debug_printf ("100ms");
switch (cygwait (100))
{
- case WAIT_OBJECT_0:
+ case WAIT_SIGNALED:
if (!_my_tls.call_signal_handler ())
{
set_errno (EINTR);
return false;
}
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_CANCELED:
pthread::static_cancel_self ();
/*NOTREACHED*/
default:
debug_printf ("100ms");
switch (cygwait (100))
{
- case WAIT_OBJECT_0:
+ case WAIT_SIGNALED:
if (!_my_tls.call_signal_handler ())
{
set_errno (EINTR);
return false;
}
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_CANCELED:
pthread::static_cancel_self ();
/*NOTREACHED*/
default:
#include "cygtls.h"
#include "shared_info.h"
#include "ntdll.h"
+#include "cygwait.h"
fhandler_fifo::fhandler_fifo ():
fhandler_base_overlapped (),
case WAIT_OBJECT_0:
debug_only_printf ("successfully waited for %s", what);
return true;
+ case WAIT_SIGNALED:
+ debug_only_printf ("interrupted by signal while waiting for %s", what);
+ set_errno (EINTR);
+ return false;
+ case WAIT_CANCELED:
+ debug_only_printf ("cancellable interruption while waiting for %s", what);
+ pthread::static_cancel_self (); /* never returns */
+ break;
case WAIT_TIMEOUT:
if (h == write_ready)
{
return false;
}
break;
- case WAIT_OBJECT_0 + 1:
- debug_only_printf ("interrupted by signal while waiting for %s", what);
- set_errno (EINTR);
- return false;
- case WAIT_OBJECT_0 + 2:
- debug_only_printf ("cancellable interruption while waiting for %s", what);
- pthread::static_cancel_self (); /* never returns */
- break;
default:
debug_only_printf ("unknown error while waiting for %s", what);
__seterrno ();
#include "pinfo.h"
#include <asm/socket.h>
#include <ddk/ntddser.h>
+#include "cygwait.h"
/**********************************************************************/
/* fhandler_serial */
goto err;
debug_printf ("n %d, ev %x", n, ev);
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
tot = -1;
PurgeComm (get_handle (), PURGE_RXABORT);
overlapped_armed = 0;
set_sig_errno (EINTR);
goto out;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_CANCELED:
PurgeComm (get_handle (), PURGE_RXABORT);
overlapped_armed = 0;
pthread::static_cancel_self ();
{
case WAIT_OBJECT_0:
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
PurgeComm (get_handle (), PURGE_TXABORT);
set_sig_errno (EINTR);
ForceCloseHandle (write_status.hEvent);
return -1;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_CANCELED:
PurgeComm (get_handle (), PURGE_TXABORT);
pthread::static_cancel_self ();
/*NOTREACHED*/
#include "cygthread.h"
#include "child_info.h"
#include <asm/socket.h>
+#include "cygwait.h"
#define close_maybe(h) \
do { \
goto out;
}
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
if (totalread > 0)
goto out;
termios_printf ("wait catched signal");
set_sig_errno (EINTR);
totalread = -1;
goto out;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_CANCELED:
process_state.pop ();
pthread::static_cancel_self ();
/*NOTREACHED*/
case WAIT_OBJECT_0:
case WAIT_ABANDONED_0:
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_SIGNALED:
if (totalread > 0)
goto out;
- termios_printf ("wait for mutex catched signal");
+ termios_printf ("wait for mutex caught signal");
set_sig_errno (EINTR);
totalread = -1;
goto out;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_CANCELED:
process_state.pop ();
pthread::static_cancel_self ();
/*NOTREACHED*/
#include "pinfo.h"
#include "sigproc.h"
#include "cygtls.h"
+#include "cygwait.h"
/*
* All these defines below should be in sys/types.h
if (sel.start.next == NULL)
switch (cygwait (ms))
{
- case WAIT_OBJECT_0:
+ case WAIT_SIGNALED:
select_printf ("signal received");
_my_tls.call_signal_handler ();
if (!sel.return_on_signal)
res = select_stuff::select_error;
}
break;
- case WAIT_OBJECT_0 + 1:
+ case WAIT_CANCELED:
sel.destroy ();
pthread::static_cancel_self ();
/*NOTREACHED*/
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
+#include "cygwait.h"
#define _SA_NORESTART 0x8000
void __stdcall sigproc_init ();
#ifdef __INSIDE_CYGWIN__
void __stdcall sigproc_terminate (enum exit_states);
-
-static inline DWORD __attribute__ ((always_inline))
-cygwait (HANDLE h, DWORD howlong = INFINITE)
-{
- HANDLE w4[3];
- DWORD n = 0;
- DWORD wait_signal;
- if ((w4[n] = h) != NULL)
- wait_signal = WAIT_OBJECT_0 + ++n;
- else
- wait_signal = WAIT_OBJECT_0 + 15; /* Arbitrary. Don't call signal
- handler if only waiting for signal */
- w4[n++] = signal_arrived;
- if ((w4[n] = pthread::get_cancel_event ()) != NULL)
- n++;
- DWORD res;
- while ((res = WaitForMultipleObjects (n, w4, FALSE, howlong)) == wait_signal
- && (_my_tls.call_signal_handler () || &_my_tls != _main_tls))
- continue;
- return res;
-}
-
-static inline DWORD __attribute__ ((always_inline))
-cygwait (DWORD wait)
-{
- return cygwait ((HANDLE) NULL, wait);
-}
#endif
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "cygwait.h"
extern "C" void __fp_lock_all ();
extern "C" void __fp_unlock_all ();
pthread::self ()->cancel_self ();
}
-DWORD
-cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
- const cw_cancel_action cancel_action,
- const enum cw_sig_wait sig_wait)
-{
- DWORD res;
- DWORD num = 0;
- HANDLE wait_objects[4];
- pthread_t thread = pthread::self ();
-
- /* Do not change the wait order.
- The object must have higher priority than the cancel event,
- because WaitForMultipleObjects will return the smallest index
- if both objects are signaled. */
- wait_objects[num++] = object;
- DWORD cancel_n;
- if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
- thread->cancelstate == PTHREAD_CANCEL_DISABLE)
- cancel_n = WAIT_TIMEOUT + 1;
- else
- {
- cancel_n = WAIT_OBJECT_0 + num++;
- wait_objects[cancel_n] = thread->cancel_event;
- }
-
- DWORD sig_n;
- if (sig_wait == cw_sig_nosig)
- sig_n = WAIT_TIMEOUT + 1;
- else
- {
- sig_n = WAIT_OBJECT_0 + num++;
- wait_objects[sig_n] = signal_arrived;
- }
-
- DWORD timeout_n;
- if (!timeout)
- timeout_n = WAIT_TIMEOUT + 1;
- else
- {
- timeout_n = WAIT_OBJECT_0 + num++;
- if (!_my_tls.locals.cw_timer)
- NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
- NotificationTimer);
- NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
- wait_objects[timeout_n] = _my_tls.locals.cw_timer;
- }
-
- while (1)
- {
- res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
- if (res == cancel_n)
- {
- if (cancel_action == cw_cancel_self)
- pthread::static_cancel_self ();
- res = WAIT_CANCELED;
- }
- else if (res == timeout_n)
- res = WAIT_TIMEOUT;
- else if (res != sig_n)
- /* all set */;
- else if (sig_wait == cw_sig_eintr)
- res = WAIT_SIGNALED;
- else
- {
- _my_tls.call_signal_handler ();
- continue;
- }
- break;
- }
-
- if (timeout)
- {
- TIMER_BASIC_INFORMATION tbi;
-
- NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
- sizeof tbi, NULL);
- /* if timer expired, TimeRemaining is negative and represents the
- system uptime when signalled */
- if (timeout->QuadPart < 0LL)
- timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
- NtCancelTimer (_my_tls.locals.cw_timer, NULL);
- }
-
- return res;
-}
-
int
pthread::setcancelstate (int state, int *oldstate)
{
++mutex->condwaits;
mutex->unlock ();
- rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
+ rv = cancelable_wait (sem_wait, timeout, cw_cancel | cw_sig_eintr);
mtx_out.lock ();
else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
|| !pthread::equal (owner, self))
{
- cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
+ /* FIXME: no cancel? */
+ cancelable_wait (win32_obj_id, NULL, cw_sig);
set_owner (self);
}
else
/* Minimal timeout to minimize CPU usage while still spinning. */
LARGE_INTEGER timeout;
timeout.QuadPart = -10000LL;
- cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
+ /* FIXME: no cancel? */
+ cancelable_wait (win32_obj_id, &timeout, cw_sig);
}
}
while (result == -1);
_my_tls.sigmask = thread->parent_sigmask;
thread->mutex.unlock ();
+ debug_printf ("tid %p", &_my_tls);
thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
_impure_ptr, thread, thread->function, thread->arg);
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
(*thread)->mutex.unlock ();
- switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
+ switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_sig | cw_cancel))
{
case WAIT_OBJECT_0:
if (return_val)
timeout.QuadPart = abstime->tv_sec * NSPERSEC
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
- switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
+ switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
{
case WAIT_OBJECT_0:
currentvalue--;
int
semaphore::_wait ()
{
- switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
+ switch (cancelable_wait (win32_obj_id, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr))
{
case WAIT_OBJECT_0:
currentvalue--;
#include "security.h"
#include <errno.h>
#include "cygerrno.h"
-
-enum cw_sig_wait
-{
- cw_sig_nosig,
- cw_sig_eintr,
- cw_sig_resume
-};
-
-enum cw_cancel_action
-{
- cw_cancel_self,
- cw_no_cancel_self,
- cw_no_cancel
-};
-
-DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
- const cw_cancel_action = cw_cancel_self,
- const enum cw_sig_wait = cw_sig_nosig)
- __attribute__ ((regparm (3)));
+#include "cygwait.h"
class fast_mutex
{
void lock ()
{
if (InterlockedIncrement ((long *) &lock_counter) != 1)
- cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
+ cancelable_wait (win32_obj_id, NULL, cw_sig);
}
void unlock ()
/* wait.cc: Posix wait routines.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2009, 2011 Red Hat, Inc.
+ 2005, 2009, 2011, 2012 Red Hat, Inc.
This file is part of Cygwin.
#include "sigproc.h"
#include "thread.h"
#include "cygtls.h"
+#include "cygwait.h"
/* This is called _wait and not wait because the real wait is defined
in libc/syscalls/syswait.c. It calls us. */
if ((waitfor = w->ev) == NULL)
goto nochildren;
- res = cancelable_wait (waitfor);
+ res = cancelable_wait (waitfor, NULL, cw_cancel | cw_cancel_self);
sigproc_printf ("%d = cancelable_wait (...)", res);