1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*============================================================ |
6 | ** |
7 | ** Source: test1.c |
8 | ** |
9 | ** Purpose: Test for WaitForMultipleObjectsEx. Call the function |
10 | ** on an array of 4 events, and ensure that it returns correct |
11 | ** results when we do so. |
12 | ** |
13 | ** |
14 | **=========================================================*/ |
15 | |
16 | #include <palsuite.h> |
17 | |
18 | /* Originally written as WaitForMultipleObjects/test1 */ |
19 | |
20 | |
21 | /* Number of events in array */ |
22 | #define MAX_EVENTS 4 |
23 | |
24 | BOOL WaitForMultipleObjectsExTest() |
25 | { |
26 | BOOL bRet = TRUE; |
27 | DWORD dwRet = 0; |
28 | DWORD i = 0, j = 0; |
29 | |
30 | LPSECURITY_ATTRIBUTES lpEventAttributes = NULL; |
31 | BOOL bManualReset = TRUE; |
32 | BOOL bInitialState = TRUE; |
33 | |
34 | HANDLE hEvent[MAX_EVENTS]; |
35 | |
36 | /* Run through this for loop and create 4 events */ |
37 | for (i = 0; i < MAX_EVENTS; i++) |
38 | { |
39 | hEvent[i] = CreateEvent( lpEventAttributes, |
40 | bManualReset, bInitialState, NULL); |
41 | |
42 | if (hEvent[i] == INVALID_HANDLE_VALUE) |
43 | { |
44 | Trace("WaitForMultipleObjectsExTest:CreateEvent %u failed (%x)\n" , i, GetLastError()); |
45 | bRet = FALSE; |
46 | break; |
47 | } |
48 | |
49 | /* Set the current event */ |
50 | bRet = SetEvent(hEvent[i]); |
51 | |
52 | if (!bRet) |
53 | { |
54 | Trace("WaitForMultipleObjectsExTest:SetEvent %u failed (%x)\n" , i, GetLastError()); |
55 | bRet = FALSE; |
56 | break; |
57 | } |
58 | |
59 | /* Ensure that this returns the correct value */ |
60 | dwRet = WaitForSingleObject(hEvent[i],0); |
61 | |
62 | if (dwRet != WAIT_OBJECT_0) |
63 | { |
64 | Trace("WaitForMultipleObjectsExTest:WaitForSingleObject %u failed (%x)\n" , i, GetLastError()); |
65 | bRet = FALSE; |
66 | break; |
67 | } |
68 | |
69 | /* Reset the event, and again ensure that the return value of |
70 | WaitForSingle is correct. |
71 | */ |
72 | bRet = ResetEvent(hEvent[i]); |
73 | |
74 | if (!bRet) |
75 | { |
76 | Trace("WaitForMultipleObjectsExTest:ResetEvent %u failed (%x)\n" , i, GetLastError()); |
77 | bRet = FALSE; |
78 | break; |
79 | } |
80 | |
81 | dwRet = WaitForSingleObject(hEvent[i],0); |
82 | |
83 | if (dwRet != WAIT_TIMEOUT) |
84 | { |
85 | Trace("WaitForMultipleObjectsExTest:WaitForSingleObject %u failed (%x)\n" , i, GetLastError()); |
86 | bRet = FALSE; |
87 | break; |
88 | } |
89 | } |
90 | |
91 | /* |
92 | * If the first section of the test passed, move on to the |
93 | * second. |
94 | */ |
95 | |
96 | if (bRet) |
97 | { |
98 | BOOL bWaitAll = TRUE; |
99 | DWORD nCount = MAX_EVENTS; |
100 | CONST HANDLE *lpHandles = &hEvent[0]; |
101 | |
102 | /* Call WaitForMultipleObjectsEx on all the events, the return |
103 | should be WAIT_TIMEOUT |
104 | */ |
105 | dwRet = WaitForMultipleObjectsEx(nCount, |
106 | lpHandles, |
107 | bWaitAll, |
108 | 0, |
109 | FALSE); |
110 | |
111 | if (dwRet != WAIT_TIMEOUT) |
112 | { |
113 | Trace("WaitForMultipleObjectsExTest: WaitForMultipleObjectsEx failed (%x)\n" , GetLastError()); |
114 | } |
115 | else |
116 | { |
117 | /* Step through each event and one at a time, set the |
118 | currect test, while reseting all the other tests |
119 | */ |
120 | |
121 | for (i = 0; i < MAX_EVENTS; i++) |
122 | { |
123 | for (j = 0; j < MAX_EVENTS; j++) |
124 | { |
125 | if (j == i) |
126 | { |
127 | |
128 | bRet = SetEvent(hEvent[j]); |
129 | |
130 | if (!bRet) |
131 | { |
132 | Trace("WaitForMultipleObjectsExTest:SetEvent %j failed (%x)\n" , j, GetLastError()); |
133 | break; |
134 | } |
135 | } |
136 | else |
137 | { |
138 | bRet = ResetEvent(hEvent[j]); |
139 | |
140 | if (!bRet) |
141 | { |
142 | Trace("WaitForMultipleObjectsExTest:ResetEvent %u failed (%x)\n" , j, GetLastError()); |
143 | } |
144 | } |
145 | } |
146 | |
147 | bWaitAll = FALSE; |
148 | |
149 | /* Check that WaitFor returns WAIT_OBJECT + i */ |
150 | dwRet = WaitForMultipleObjectsEx( nCount, |
151 | lpHandles, bWaitAll, 0, FALSE); |
152 | |
153 | if (dwRet != WAIT_OBJECT_0+i) |
154 | { |
155 | Trace("WaitForMultipleObjectsExTest: WaitForMultipleObjectsEx failed (%x)\n" , GetLastError()); |
156 | bRet = FALSE; |
157 | break; |
158 | } |
159 | } |
160 | } |
161 | |
162 | for (i = 0; i < MAX_EVENTS; i++) |
163 | { |
164 | bRet = CloseHandle(hEvent[i]); |
165 | |
166 | if (!bRet) |
167 | { |
168 | Trace("WaitForMultipleObjectsExTest:CloseHandle %u failed (%x)\n" , i, GetLastError()); |
169 | } |
170 | } |
171 | } |
172 | |
173 | return bRet; |
174 | } |
175 | |
176 | BOOL WaitMultipleDuplicateHandleTest() |
177 | { |
178 | BOOL testResult = TRUE; |
179 | const HANDLE eventHandle = CreateEvent(NULL, TRUE, TRUE, NULL); |
180 | HANDLE eventHandles[] = {eventHandle, eventHandle}; |
181 | |
182 | // WaitAny - Wait for any of the events (no error expected) |
183 | DWORD result = WaitForMultipleObjects(sizeof(eventHandles) / sizeof(eventHandles[0]), eventHandles, FALSE, 0); |
184 | if (result != WAIT_OBJECT_0) |
185 | { |
186 | Trace("WaitMultipleDuplicateHandleTest:WaitAny failed (%x)\n" , GetLastError()); |
187 | testResult = FALSE; |
188 | } |
189 | |
190 | // WaitAll - Wait for all of the events (error expected) |
191 | result = WaitForMultipleObjects(sizeof(eventHandles) / sizeof(eventHandles[0]), eventHandles, TRUE, 0); |
192 | if (result != WAIT_FAILED) |
193 | { |
194 | Trace("WaitMultipleDuplicateHandleTest:WaitAll failed: call unexpectedly succeeded\n" ); |
195 | testResult = FALSE; |
196 | } |
197 | else if (GetLastError() != ERROR_INVALID_PARAMETER) |
198 | { |
199 | Trace("WaitMultipleDuplicateHandleTest:WaitAll failed: unexpected last error (%x)\n" ); |
200 | testResult = FALSE; |
201 | } |
202 | |
203 | return testResult; |
204 | } |
205 | |
206 | int __cdecl main(int argc, char **argv) |
207 | { |
208 | |
209 | if(0 != (PAL_Initialize(argc, argv))) |
210 | { |
211 | return ( FAIL ); |
212 | } |
213 | |
214 | if(!WaitForMultipleObjectsExTest()) |
215 | { |
216 | Fail ("Test failed\n" ); |
217 | } |
218 | |
219 | if (!WaitMultipleDuplicateHandleTest()) |
220 | { |
221 | Fail("Test failed\n" ); |
222 | } |
223 | |
224 | PAL_Terminate(); |
225 | return PASS; |
226 | } |
227 | |