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
17int __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