summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/cygwait.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-06-17 20:50:24 +0000
committerChristopher Faylor <me@cgf.cx>2012-06-17 20:50:24 +0000
commit4ae63783821bd2114246166957d25b2acd26c875 (patch)
tree0b7972e9330fa3a3f863621afd18643e485a151f /winsup/cygwin/cygwait.cc
parentd66ef282c2473d7df911e6d7d6ef1fc778777097 (diff)
downloadcygnal-4ae63783821bd2114246166957d25b2acd26c875.tar.gz
cygnal-4ae63783821bd2114246166957d25b2acd26c875.tar.bz2
cygnal-4ae63783821bd2114246166957d25b2acd26c875.zip
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.
Diffstat (limited to 'winsup/cygwin/cygwait.cc')
-rw-r--r--winsup/cygwin/cygwait.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc
new file mode 100644
index 000000000..6e0610da0
--- /dev/null
+++ b/winsup/cygwin/cygwait.cc
@@ -0,0 +1,108 @@
+/* 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;
+}