3 Copyright 2011, 2012 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
16 #define is_cw_cancel (mask & cw_cancel)
17 #define is_cw_cancel_self (mask & cw_cancel_self)
18 #define is_cw_sig (mask & cw_sig)
19 #define is_cw_sig_eintr (mask & cw_sig_eintr)
20 #define is_cw_sig_return (mask & cw_sig_return)
22 #define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
25 cancelable_wait (HANDLE object
, PLARGE_INTEGER timeout
, unsigned mask
)
29 HANDLE wait_objects
[4];
30 pthread_t thread
= pthread::self ();
32 /* Do not change the wait order.
33 The object must have higher priority than the cancel event,
34 because WaitForMultipleObjects will return the smallest index
35 if both objects are signaled. */
37 wait_objects
[num
++] = object
;
40 if (!is_cw_sig_handle
)
41 sig_n
= WAIT_TIMEOUT
+ 1;
44 sig_n
= WAIT_OBJECT_0
+ num
++;
45 wait_objects
[sig_n
] = signal_arrived
;
49 if (!is_cw_cancel
|| !pthread::is_good_object (&thread
) ||
50 thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
51 cancel_n
= WAIT_TIMEOUT
+ 1;
54 cancel_n
= WAIT_OBJECT_0
+ num
++;
55 wait_objects
[cancel_n
] = thread
->cancel_event
;
60 timeout_n
= WAIT_TIMEOUT
+ 1;
63 timeout_n
= WAIT_OBJECT_0
+ num
++;
64 if (!_my_tls
.locals
.cw_timer
)
65 NtCreateTimer (&_my_tls
.locals
.cw_timer
, TIMER_ALL_ACCESS
, NULL
,
67 NtSetTimer (_my_tls
.locals
.cw_timer
, timeout
, NULL
, NULL
, FALSE
, 0, NULL
);
68 wait_objects
[timeout_n
] = _my_tls
.locals
.cw_timer
;
73 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, INFINITE
);
76 if (is_cw_cancel_self
)
77 pthread::static_cancel_self ();
80 else if (res
== timeout_n
)
82 else if (res
!= sig_n
)
84 else if (is_cw_sig_eintr
)
86 else if (_my_tls
.call_signal_handler () || &_my_tls
!= _main_tls
)
93 TIMER_BASIC_INFORMATION tbi
;
95 NtQueryTimer (_my_tls
.locals
.cw_timer
, TimerBasicInformation
, &tbi
,
97 /* if timer expired, TimeRemaining is negative and represents the
98 system uptime when signalled */
99 if (timeout
->QuadPart
< 0LL)
100 timeout
->QuadPart
= tbi
.SignalState
? 0LL : tbi
.TimeRemaining
.QuadPart
;
101 NtCancelTimer (_my_tls
.locals
.cw_timer
, NULL
);