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
24BOOL 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
176BOOL 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
206int __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