VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem-Zombie.cpp@ 46861

Last change on this file since 46861 was 44529, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: tstSupSem-Zombie.cpp 44529 2013-02-04 15:54:15Z vboxsync $ */
2/** @file
3 * Support Library Testcase - Ring-3 Semaphore interface - Zombie bugs.
4 */
5
6/*
7 * Copyright (C) 2009-2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <VBox/sup.h>
32
33#include <VBox/param.h>
34#include <iprt/env.h>
35#include <iprt/err.h>
36#include <iprt/initterm.h>
37#include <iprt/process.h>
38#include <iprt/stream.h>
39#include <iprt/string.h>
40#include <iprt/test.h>
41#include <iprt/time.h>
42#include <iprt/thread.h>
43
44
45/*******************************************************************************
46* Structures and Typedefs *
47*******************************************************************************/
48static PSUPDRVSESSION g_pSession;
49static RTTEST g_hTest;
50
51
52
53static DECLCALLBACK(int) tstSupSemSRETimed(RTTHREAD hSelf, void *pvUser)
54{
55 SUPSEMEVENT hEvent = (SUPSEMEVENT)pvUser;
56 RTThreadUserSignal(hSelf);
57 int rc = SUPSemEventWaitNoResume(g_pSession, hEvent, 120*1000);
58 AssertReleaseMsgFailed(("%Rrc\n", rc));
59 return rc;
60}
61
62
63static DECLCALLBACK(int) tstSupSemMRETimed(RTTHREAD hSelf, void *pvUser)
64{
65 SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)pvUser;
66 RTThreadUserSignal(hSelf);
67 int rc = SUPSemEventMultiWaitNoResume(g_pSession, hEventMulti, 120*1000);
68 AssertReleaseMsgFailed(("%Rrc\n", rc));
69 return rc;
70}
71
72
73static DECLCALLBACK(int) tstSupSemSREInf(RTTHREAD hSelf, void *pvUser)
74{
75 SUPSEMEVENT hEvent = (SUPSEMEVENT)pvUser;
76 RTThreadUserSignal(hSelf);
77 int rc = SUPSemEventWaitNoResume(g_pSession, hEvent, RT_INDEFINITE_WAIT);
78 AssertReleaseMsgFailed(("%Rrc\n", rc));
79 return rc;
80}
81
82
83static DECLCALLBACK(int) tstSupSemMREInf(RTTHREAD hSelf, void *pvUser)
84{
85 SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)pvUser;
86 RTThreadUserSignal(hSelf);
87 int rc = SUPSemEventMultiWaitNoResume(g_pSession, hEventMulti, RT_INDEFINITE_WAIT);
88 AssertReleaseMsgFailed(("%Rrc\n", rc));
89 return rc;
90}
91
92static int mainChild(void)
93{
94 /*
95 * Init.
96 */
97 int rc = RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB);
98 if (RT_FAILURE(rc))
99 {
100 RTPrintf("tstSupSem-Zombie-Child: fatal error: RTR3InitExeNoArguments failed with rc=%Rrc\n", rc);
101 return 1;
102 }
103
104 RTTEST hTest;
105 rc = RTTestCreate("tstSupSem-Zombie-Child", &hTest);
106 if (RT_FAILURE(rc))
107 {
108 RTPrintf("tstSupSem-Zombie-Child: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
109 return 1;
110 }
111 g_hTest = hTest;
112
113 PSUPDRVSESSION pSession;
114 rc = SUPR3Init(&pSession);
115 if (RT_FAILURE(rc))
116 {
117 RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
118 return RTTestSummaryAndDestroy(hTest);
119 }
120 g_pSession = pSession;
121
122 /*
123 * A semaphore of each kind and throw a bunch of threads on them.
124 */
125 SUPSEMEVENT hEvent = NIL_SUPSEMEVENT;
126 RTTESTI_CHECK_RC(rc = SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
127 if (RT_SUCCESS(rc))
128 {
129 SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT;
130 RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS);
131 if (RT_SUCCESS(rc))
132 {
133 for (uint32_t cThreads = 0; cThreads < 5; cThreads++)
134 {
135 RTTHREAD hThread;
136 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSRETimed, (void *)hEvent, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
137 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMRETimed, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
138 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemSREInf, (void *)hEvent, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntSRE"), VINF_SUCCESS);
139 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemMREInf, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, 0 /*fFlags*/, "IntMRE"), VINF_SUCCESS);
140 RTThreadSleep(2);
141 }
142 RTThreadSleep(50);
143
144 /*
145 * This is where the test really starts...
146 */
147 return 0;
148 }
149 }
150
151 return RTTestSummaryAndDestroy(hTest);
152}
153
154
155/**
156 * The parent main routine.
157 * @param argv0 The executable name (or whatever).
158 */
159static int mainParent(const char *argv0)
160{
161 /*
162 * Init.
163 */
164 RTTEST hTest;
165 int rc = RTTestInitAndCreate("tstSupSem-Zombie", &hTest);
166 if (rc)
167 return rc;
168 RTTestBanner(hTest);
169
170 /*
171 * Spin of the child process which may or may not turn into a zombie
172 */
173 for (uint32_t iPass = 0; iPass < 32; iPass++)
174 {
175 RTTestSubF(hTest, "Pass %u", iPass);
176
177 RTPROCESS hProcess;
178 const char *apszArgs[3] = { argv0, "--child", NULL };
179 RTTESTI_CHECK_RC_OK(rc = RTProcCreate(argv0, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hProcess));
180 if (RT_SUCCESS(rc))
181 {
182 /*
183 * Wait for 60 seconds then give up.
184 */
185 RTPROCSTATUS Status;
186 uint64_t StartTS = RTTimeMilliTS();
187 for (;;)
188 {
189 rc = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &Status);
190 if (RT_SUCCESS(rc))
191 break;
192 uint64_t cElapsed = RTTimeMilliTS() - StartTS;
193 if (cElapsed > 60*1000)
194 break;
195 RTThreadSleep(cElapsed < 60 ? 30 : cElapsed < 200 ? 10 : 100);
196 }
197 RTTESTI_CHECK_RC_OK(rc);
198 if ( RT_SUCCESS(rc)
199 && ( Status.enmReason != RTPROCEXITREASON_NORMAL
200 || Status.iStatus != 0))
201 {
202 RTTestIFailed("child %d (%#x) reason %d\n", Status.iStatus, Status.iStatus, Status.enmReason);
203 rc = VERR_PERMISSION_DENIED;
204 }
205 }
206 /* one zombie process is enough. */
207 if (RT_FAILURE(rc))
208 break;
209 }
210
211 return RTTestSummaryAndDestroy(hTest);
212}
213
214
215int main(int argc, char **argv)
216{
217 if ( argc == 2
218 && !strcmp(argv[1], "--child"))
219 return mainChild();
220 return mainParent(argv[0]);
221}
222
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette