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.
This commit is contained in:
108
winsup/cygwin/cygwait.cc
Normal file
108
winsup/cygwin/cygwait.cc
Normal file
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user