]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/cygwait.cc
Revert errneous checkin.
[newlib-cygwin.git] / winsup / cygwin / cygwait.cc
1 /* cygwait.h
2
3 Copyright 2011, 2012 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include "sigproc.h"
13 #include "cygwait.h"
14 #include "ntdll.h"
15
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)
21
22 #define is_cw_sig_handle (mask & (is_cw_sig | is_cw_sig_eintr))
23
24 DWORD
25 cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
26 {
27 DWORD res;
28 DWORD num = 0;
29 HANDLE wait_objects[4];
30 pthread_t thread = pthread::self ();
31
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. */
36 if (object)
37 wait_objects[num++] = object;
38
39 DWORD sig_n;
40 if (!is_cw_sig_handle)
41 sig_n = WAIT_TIMEOUT + 1;
42 else
43 {
44 sig_n = WAIT_OBJECT_0 + num++;
45 wait_objects[sig_n] = signal_arrived;
46 }
47
48 DWORD cancel_n;
49 if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
50 thread->cancelstate == PTHREAD_CANCEL_DISABLE)
51 cancel_n = WAIT_TIMEOUT + 1;
52 else
53 {
54 cancel_n = WAIT_OBJECT_0 + num++;
55 wait_objects[cancel_n] = thread->cancel_event;
56 }
57
58 DWORD timeout_n;
59 if (!timeout)
60 timeout_n = WAIT_TIMEOUT + 1;
61 else
62 {
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,
66 NotificationTimer);
67 NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
68 wait_objects[timeout_n] = _my_tls.locals.cw_timer;
69 }
70
71 while (1)
72 {
73 res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
74 if (res == cancel_n)
75 {
76 if (is_cw_cancel_self)
77 pthread::static_cancel_self ();
78 res = WAIT_CANCELED;
79 }
80 else if (res == timeout_n)
81 res = WAIT_TIMEOUT;
82 else if (res != sig_n)
83 /* all set */;
84 else if (is_cw_sig_eintr)
85 res = WAIT_SIGNALED;
86 else if (_my_tls.call_signal_handler () || &_my_tls != _main_tls)
87 continue;
88 break;
89 }
90
91 if (timeout)
92 {
93 TIMER_BASIC_INFORMATION tbi;
94
95 NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
96 sizeof tbi, NULL);
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);
102 }
103
104 return res;
105 }
This page took 0.038021 seconds and 5 git commands to generate.