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