Cygwin: cygtls: rename sig to current_sig
[newlib-cygwin.git] / winsup / cygwin / cygwait.cc
blob80c0e971c77dc270cfb450f64382e5cc9824a2b7
1 /* cygwait.h
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #include "winsup.h"
10 #include "sigproc.h"
11 #include "cygwait.h"
12 #include "ntdll.h"
14 #define is_cw_cancel (mask & cw_cancel)
15 #define is_cw_cancel_self (mask & cw_cancel_self)
16 #define is_cw_sig (mask & cw_sig)
17 #define is_cw_sig_eintr (mask & cw_sig_eintr)
18 #define is_cw_sig_cont (mask & cw_sig_cont)
19 #define is_cw_sig_restart (mask & cw_sig_restart)
21 #define is_cw_sig_handle (mask & (cw_sig | cw_sig_eintr \
22 | cw_sig_cont | cw_sig_restart))
24 LARGE_INTEGER cw_nowait_storage;
26 DWORD
27 cygwait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
29 DWORD res;
30 DWORD num = 0;
31 HANDLE wait_objects[4];
32 pthread_t thread = pthread::self ();
34 /* Do not change the wait order.
35 The object must have higher priority than the cancel event,
36 because WaitForMultipleObjects will return the smallest index
37 if both objects are signaled. */
38 if (object)
39 wait_objects[num++] = object;
41 wait_signal_arrived thread_waiting (is_cw_sig_handle, wait_objects[num]);
42 debug_only_printf ("object %p, thread waiting %d, signal_arrived %p",
43 object, (int) thread_waiting, _my_tls.signal_arrived);
44 DWORD sig_n;
45 if (!thread_waiting)
46 sig_n = WAIT_TIMEOUT + 1;
47 else
48 sig_n = WAIT_OBJECT_0 + num++;
50 DWORD cancel_n;
51 if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
52 thread->cancelstate == PTHREAD_CANCEL_DISABLE)
53 cancel_n = WAIT_TIMEOUT + 1;
54 else
56 cancel_n = WAIT_OBJECT_0 + num++;
57 wait_objects[cancel_n] = thread->cancel_event;
60 DWORD timeout_n;
61 if (!timeout)
62 timeout_n = WAIT_TIMEOUT + 1;
63 else
65 timeout_n = WAIT_OBJECT_0 + num++;
66 if (!_my_tls.locals.cw_timer)
67 NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
68 NotificationTimer);
69 NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
70 wait_objects[timeout_n] = _my_tls.locals.cw_timer;
73 while (1)
75 res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
76 debug_only_printf ("res %d", res);
77 if (res == cancel_n)
78 res = WAIT_CANCELED;
79 else if (res == timeout_n)
80 res = WAIT_TIMEOUT;
81 else if (res != sig_n)
82 /* all set */;
83 else
85 int sig = _my_tls.current_sig;
86 if (is_cw_sig_cont && sig == SIGCONT)
87 _my_tls.current_sig = 0;
88 if (!sig)
89 continue;
90 if (is_cw_sig_eintr || (is_cw_sig_cont && sig == SIGCONT))
92 else if (_my_tls.call_signal_handler () || is_cw_sig_restart)
93 continue;
94 res = WAIT_SIGNALED; /* caller will deal with signals */
96 break;
99 if (timeout)
101 TIMER_BASIC_INFORMATION tbi;
103 NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
104 sizeof tbi, NULL);
105 /* if timer expired, TimeRemaining is negative and represents the
106 system uptime when signalled */
107 if (timeout->QuadPart < 0LL) {
108 timeout->QuadPart = tbi.SignalState || tbi.TimeRemaining.QuadPart < 0LL
109 ? 0LL : tbi.TimeRemaining.QuadPart;
111 NtCancelTimer (_my_tls.locals.cw_timer, NULL);
114 if (res == WAIT_CANCELED && is_cw_cancel_self)
115 pthread::static_cancel_self ();
117 return res;