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
21BOOL 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
173BOOL 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
203int __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