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: child6.c |
8 | ** |
9 | ** Purpose: Test for WaitForMultipleObjectsEx in multiple |
10 | ** scenarios - child process |
11 | ** |
12 | ** |
13 | **=========================================================*/ |
14 | |
15 | #include <palsuite.h> |
16 | |
17 | int __cdecl main(int argc, char **argv) |
18 | { |
19 | int i, iRet; |
20 | BOOL bRet; |
21 | BOOL bNamedEvent = 0; |
22 | BOOL bMutex = 0; |
23 | BOOL bMutexAndNamedEvent = 0; |
24 | BOOL bSemaphore = 0; |
25 | DWORD dwRet; |
26 | HANDLE hNamedEvent; |
27 | HANDLE hMutex; |
28 | char szTestName[256]; |
29 | WCHAR wszTestName[256] = { 0 }; |
30 | char szEventName[128] = { 0 }; |
31 | char szMutexName[128] = { 0 }; |
32 | char szSemName[128] = { 0 }; |
33 | WCHAR wszEventName[128]; |
34 | WCHAR wszMutexName[128]; |
35 | WCHAR wszSemName[128]; |
36 | DWORD iExitCode = 0; |
37 | HANDLE hSemaphore; |
38 | |
39 | if(0 != (PAL_Initialize(argc, argv))) |
40 | { |
41 | return ( FAIL ); |
42 | } |
43 | |
44 | Trace("[child] Starting\n" ); |
45 | |
46 | for (i=1; i<argc; i++) |
47 | { |
48 | if (0 == strcmp(argv[i],"-event" )) |
49 | { |
50 | bNamedEvent = 1; |
51 | } |
52 | else if (0 == strcmp(argv[i],"-mutex" )) |
53 | { |
54 | bMutex = 1; |
55 | } |
56 | else if (0 == strcmp(argv[i],"-mutex_and_named_event" )) |
57 | { |
58 | bMutexAndNamedEvent = 1; |
59 | } |
60 | else if (0 == strcmp(argv[i],"-semaphore" )) |
61 | { |
62 | bSemaphore = 1; |
63 | } |
64 | else if (0 == strcmp(argv[i],"-exitcode" ) && i < argc-1 ) |
65 | { |
66 | i++; |
67 | iExitCode = atoi(argv[i]); |
68 | Trace("[child] My exit code is %d\n" , iExitCode); |
69 | } |
70 | |
71 | else if ('-' != *argv[i]) |
72 | { |
73 | strncpy(szTestName, argv[i], 256); |
74 | szTestName[255] = 0; |
75 | iRet = MultiByteToWideChar(CP_ACP, 0, szTestName, strlen(szTestName)+1, wszTestName, 256); |
76 | if (0 == iRet) |
77 | { |
78 | Fail("Failed to convert test string\n" ); |
79 | } |
80 | } |
81 | } |
82 | |
83 | sprintf_s(szEventName, 128, "%s_Event" , szTestName); |
84 | szEventName[127] = 0; |
85 | sprintf_s(szMutexName, 128, "%s_Mutex" , szTestName); |
86 | szMutexName[127] = 0; |
87 | sprintf_s(szSemName, 128, "%s_Semaphore" , szTestName); |
88 | szSemName[127] = 0; |
89 | |
90 | iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128); |
91 | iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128); |
92 | iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128); |
93 | if (0 == iRet) |
94 | { |
95 | Fail("[child] Failed to convert strings\n" ); |
96 | } |
97 | |
98 | Trace("[child] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n" , |
99 | szTestName, wszEventName, wszMutexName, wszSemName); |
100 | |
101 | hNamedEvent = OpenEventW(0, FALSE, wszEventName); |
102 | if (NULL == hNamedEvent) |
103 | { |
104 | Fail("[child] OpenEventW failed [szEventName=%s GetLastError()=%u]\n" , |
105 | szEventName, GetLastError()); |
106 | } |
107 | hMutex = OpenMutexW(0, FALSE, wszMutexName); |
108 | if (NULL == hMutex) |
109 | { |
110 | Fail("[child] OpenMutexW failed [GetLastError()=%u]\n" , |
111 | GetLastError()); |
112 | } |
113 | hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName); |
114 | if (NULL == hSemaphore) |
115 | { |
116 | Fail("[child] CreateSemaphore failed [GetLastError()=%u]\n" , |
117 | GetLastError()); |
118 | } |
119 | |
120 | |
121 | if (bMutex) |
122 | { |
123 | Trace("[child] Going to wait on mutex %s\n" , szMutexName); |
124 | dwRet = WaitForSingleObject(hMutex, INFINITE); |
125 | if (WAIT_FAILED == dwRet) |
126 | { |
127 | Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n" , |
128 | GetLastError()); |
129 | } |
130 | |
131 | Trace("[child] Setting event %s\n" , szEventName); |
132 | bRet = SetEvent(hNamedEvent); |
133 | if (FALSE == bRet) |
134 | { |
135 | Fail("[child] SetEvent failed [GetLastError()=%u]\n" , |
136 | GetLastError()); |
137 | } |
138 | |
139 | // mutex will be abandoned |
140 | } |
141 | else if (bMutexAndNamedEvent) |
142 | { |
143 | dwRet = WaitForSingleObject(hMutex, INFINITE); |
144 | if (WAIT_FAILED == dwRet) |
145 | { |
146 | Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n" , |
147 | GetLastError()); |
148 | } |
149 | |
150 | Sleep(2000); |
151 | |
152 | bRet = ReleaseMutex(hMutex); |
153 | if (FALSE == bRet) |
154 | { |
155 | Fail("[child] ReleaseMutex failed [GetLastError()=%u]\n" , |
156 | GetLastError()); |
157 | } |
158 | |
159 | Sleep(1000); |
160 | |
161 | bRet = SetEvent(hNamedEvent); |
162 | if (FALSE == bRet) |
163 | { |
164 | Fail("[child] SetEvent failed [GetLastError()=%u]\n" , |
165 | GetLastError()); |
166 | } |
167 | } |
168 | else if (bSemaphore) |
169 | { |
170 | LONG lPrevCount = 42; |
171 | |
172 | |
173 | Trace("[child] Going to wait on event %s\n" , szEventName); |
174 | dwRet = WaitForSingleObject(hNamedEvent, INFINITE); |
175 | if (WAIT_FAILED == dwRet) |
176 | { |
177 | Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n" , |
178 | GetLastError()); |
179 | } |
180 | |
181 | Trace("[child] Releasing semaphore %s\n" , szSemName); |
182 | bRet = ReleaseSemaphore(hSemaphore, 10, &lPrevCount); |
183 | if (FALSE == bRet) |
184 | { |
185 | Fail("ReleaseMutex failed [GetLastError()=%u]\n" , |
186 | GetLastError()); |
187 | } |
188 | if (0 != lPrevCount) |
189 | { |
190 | Fail("Previous count from semaphore=%d, expected 0\n" , lPrevCount); |
191 | } |
192 | } |
193 | else if (bNamedEvent) |
194 | { |
195 | Sleep(1000); |
196 | |
197 | bRet = SetEvent(hNamedEvent); |
198 | if (FALSE == bRet) |
199 | { |
200 | Fail("[child] SetEvent failed [GetLastError()=%u]\n" , |
201 | GetLastError()); |
202 | } |
203 | } |
204 | |
205 | Sleep(1000); |
206 | |
207 | Trace("[child] Done\n" ); |
208 | |
209 | PAL_TerminateEx(iExitCode); |
210 | return iExitCode; |
211 | } |
212 | |