Changeset 83286 in vbox
- Timestamp:
- Mar 13, 2020 3:35:35 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 136442
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h
r82968 r83286 179 179 * (VBOXSERVICECTRLPROCESS). */ 180 180 RTLISTANCHOR lstProcesses; 181 /** Number of guest processes in the process list. */ 182 uint32_t cProcesses; 181 183 /** List of guest control files (VBOXSERVICECTRLFILE). */ 182 184 RTLISTANCHOR lstFiles; 185 /** Number of guest files in the file list. */ 186 uint32_t cFiles; 183 187 /** The session's critical section. */ 184 188 RTCRITSECT CritSect; … … 278 282 RTPIPE hPipeStdOutR; 279 283 /** StdOut pipe for addressing reads from 280 * guest process' std out.*/284 * guest process' stderr.*/ 281 285 RTPIPE hPipeStdErrR; 282 286 … … 317 321 extern int VGSvcGstCtrlSessionProcessAdd(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess); 318 322 extern int VGSvcGstCtrlSessionProcessRemove(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess); 319 extern int VGSvcGstCtrlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *p bAllowed);323 extern int VGSvcGstCtrlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pfAllowed); 320 324 extern int VGSvcGstCtrlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession); 321 325 /** @} */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r83272 r83286 136 136 * @return IPRT status code. 137 137 * @param pProcess Guest process to free. 138 * The pointer will not be valid anymore after return. 138 139 */ 139 140 int VGSvcGstCtrlProcessFree(PVBOXSERVICECTRLPROCESS pProcess) … … 141 142 AssertPtrReturn(pProcess, VERR_INVALID_POINTER); 142 143 143 VGSvcVerbose(3, "[PID %RU32]: Freeing (cRefs=%RU32)...\n", pProcess->uPID, pProcess->cRefs); 144 Assert(pProcess->cRefs == 0); 145 146 /* 147 * Destroy other thread data. 148 */ 149 if (RTCritSectIsInitialized(&pProcess->CritSect)) 144 int rc = RTCritSectEnter(&pProcess->CritSect); 145 if (RT_SUCCESS(rc)) 146 { 147 VGSvcVerbose(3, "[PID %RU32]: Freeing (cRefs=%RU32)...\n", pProcess->uPID, pProcess->cRefs); 148 149 AssertReturn(pProcess->cRefs == 0, VERR_WRONG_ORDER); 150 AssertReturn(pProcess->fStopped, VERR_WRONG_ORDER); 151 AssertReturn(pProcess->fShutdown, VERR_WRONG_ORDER); 152 153 /* 154 * Destroy other thread data. 155 */ 156 int rc = RTPollSetDestroy(pProcess->hPollSet); 157 AssertRC(rc); 158 159 rc = RTReqQueueDestroy(pProcess->hReqQueue); 160 AssertRC(rc); 161 162 rc = RTPipeClose(pProcess->hNotificationPipeR); 163 AssertRC(rc); 164 rc = RTPipeClose(pProcess->hNotificationPipeW); 165 AssertRC(rc); 166 167 rc = RTPipeClose(pProcess->hPipeStdInW); 168 AssertRC(rc); 169 rc = RTPipeClose(pProcess->hPipeStdErrR); 170 AssertRC(rc); 171 rc = RTPipeClose(pProcess->hPipeStdOutR); 172 AssertRC(rc); 173 174 rc = RTCritSectLeave(&pProcess->CritSect); 175 AssertRC(rc); 176 150 177 RTCritSectDelete(&pProcess->CritSect); 151 178 152 int rc = RTReqQueueDestroy(pProcess->hReqQueue); 153 AssertRC(rc); 154 155 /* 156 * Remove from list. 157 */ 158 AssertPtr(pProcess->pSession); 159 rc = VGSvcGstCtrlSessionProcessRemove(pProcess->pSession, pProcess); 160 AssertRC(rc); 161 162 /* 163 * Destroy thread structure as final step. 164 */ 165 RTMemFree(pProcess); 166 pProcess = NULL; 167 168 return VINF_SUCCESS; 179 /* 180 * Destroy thread structure as final step. 181 */ 182 RTMemFree(pProcess); 183 pProcess = NULL; 184 } 185 186 return rc; 169 187 } 170 188 … … 193 211 * Releases a previously acquired guest process (decreases the refcount). 194 212 * 195 * @param pProcess Process to unlock.213 * @param pProcess Process to release. 196 214 */ 197 215 void VGSvcGstCtrlProcessRelease(PVBOXSERVICECTRLPROCESS pProcess) … … 199 217 AssertPtrReturnVoid(pProcess); 200 218 201 bool fShutdown = false; 202 203 int rc = RTCritSectEnter(&pProcess->CritSect); 204 if (RT_SUCCESS(rc)) 205 { 206 Assert(pProcess->cRefs); 219 int rc2 = RTCritSectEnter(&pProcess->CritSect); 220 if (RT_SUCCESS(rc2)) 221 { 222 AssertReturnVoid(pProcess->cRefs); 207 223 pProcess->cRefs--; 208 fShutdown = pProcess->fStopped; /* Has the process' thread been stopped? */ 209 210 rc = RTCritSectLeave(&pProcess->CritSect); 211 AssertRC(rc); 212 } 213 214 if (fShutdown) 215 VGSvcGstCtrlProcessFree(pProcess); 224 225 VGSvcVerbose(3, "[PID %RU32]: cRefs=%RU32, fShutdown=%RTbool, fStopped=%RTbool\n", 226 pProcess->uPID, pProcess->cRefs, pProcess->fShutdown, pProcess->fStopped); 227 228 rc2 = RTCritSectLeave(&pProcess->CritSect); 229 AssertRC(rc2); 230 } 216 231 } 217 232 … … 232 247 233 248 int rc = vgsvcGstCtrlProcessLock(pProcess); 234 if (RT_SUCCESS(rc)) 249 if ( RT_SUCCESS(rc) 250 && pProcess->Thread != NIL_RTTHREAD) /* Is there a thread we can wait for? */ 235 251 { 236 252 VGSvcVerbose(2, "[PID %RU32]: Waiting for shutdown (%RU32ms) ...\n", pProcess->uPID, msTimeout); … … 240 256 pProcess, pProcess->uPID), VERR_INVALID_PARAMETER); 241 257 242 /* Guest process already has been stopped, no need to wait. */ 243 if (!pProcess->fStopped) 244 { 245 /* Unlock process before waiting. */ 246 rc = vgsvcGstCtrlProcessUnlock(pProcess); 247 AssertRC(rc); 248 249 /* Do the actual waiting. */ 250 int rcThread; 251 Assert(pProcess->Thread != NIL_RTTHREAD); 252 rc = RTThreadWait(pProcess->Thread, msTimeout, &rcThread); 253 if (RT_SUCCESS(rc)) 254 { 255 pProcess->Thread = NIL_RTTHREAD; 256 VGSvcVerbose(3, "[PID %RU32]: Thread shutdown complete, thread rc=%Rrc\n", pProcess->uPID, rcThread); 257 if (prc) 258 *prc = rcThread; 259 } 260 else 261 VGSvcError("[PID %RU32]: Waiting for shutting down thread returned error rc=%Rrc\n", pProcess->uPID, rc); 258 /* Unlock process before waiting. */ 259 rc = vgsvcGstCtrlProcessUnlock(pProcess); 260 AssertRC(rc); 261 262 /* Do the actual waiting. */ 263 int rcThread; 264 Assert(pProcess->Thread != NIL_RTTHREAD); 265 rc = RTThreadWait(pProcess->Thread, msTimeout, &rcThread); 266 267 int rc2 = vgsvcGstCtrlProcessLock(pProcess); 268 AssertRC(rc2); 269 270 if (RT_SUCCESS(rc)) 271 { 272 pProcess->Thread = NIL_RTTHREAD; 273 VGSvcVerbose(3, "[PID %RU32]: Thread shutdown complete, thread rc=%Rrc\n", pProcess->uPID, rcThread); 274 if (prc) 275 *prc = rcThread; 262 276 } 263 277 else 264 { 265 VGSvcVerbose(3, "[PID %RU32]: Thread already shut down, no waiting needed\n", pProcess->uPID); 266 267 int rc2 = vgsvcGstCtrlProcessUnlock(pProcess); 268 AssertRC(rc2); 269 } 278 VGSvcError("[PID %RU32]: Waiting for shutting down thread returned error rc=%Rrc\n", pProcess->uPID, rc); 279 280 rc2 = vgsvcGstCtrlProcessUnlock(pProcess); 281 AssertRC(rc2); 270 282 } 271 283 … … 1454 1466 if (RT_FAILURE(rc)) 1455 1467 { 1456 VGSvcError("Error while adding guest process '%s' (%p) to session process list, rc=%Rrc\n",1468 VGSvcError("Error while adding guest process '%s' (%p) to session process list, rc=%Rrc\n", 1457 1469 pProcess->StartupInfo.szCmd, pProcess, rc); 1458 1470 RTThreadUserSignal(RTThreadSelf()); … … 1610 1622 * So, NIL the handles to avoid closing them again. 1611 1623 */ 1612 /** @todo r=bird: Can't see how hNotificationPipeR could be closed here! Found (and fixed)1613 * confused comments documenting hNotificationPipeW, probably related. */1614 1624 if (RT_FAILURE(RTPollSetQueryHandle(pProcess->hPollSet, 1615 1625 VBOXSERVICECTRLPIPEID_IPC_NOTIFY, NULL))) 1616 {1617 pProcess->hNotificationPipeR = NIL_RTPIPE;1618 1626 pProcess->hNotificationPipeW = NIL_RTPIPE; 1619 }1620 1627 if (RT_FAILURE(RTPollSetQueryHandle(pProcess->hPollSet, 1621 1628 VBOXSERVICECTRLPIPEID_STDERR, NULL))) … … 1630 1637 } 1631 1638 RTPollSetDestroy(pProcess->hPollSet); 1639 pProcess->hPollSet = NIL_RTPOLLSET; 1632 1640 1633 1641 RTPipeClose(pProcess->hNotificationPipeR); … … 1638 1646 RTPipeClose(pProcess->hPipeStdErrR); 1639 1647 pProcess->hPipeStdErrR = NIL_RTPIPE; 1640 RTHandleClose( phStdErr);1648 RTHandleClose(&hStdErr); 1641 1649 if (phStdErr) 1642 1650 RTHandleClose(phStdErr); … … 1650 1658 RTPipeClose(pProcess->hPipeStdInW); 1651 1659 pProcess->hPipeStdInW = NIL_RTPIPE; 1652 RTHandleClose(phStdIn); 1660 RTHandleClose(&hStdIn); 1661 if (phStdIn) 1662 RTHandleClose(phStdIn); 1653 1663 } 1654 1664 } … … 1669 1679 } 1670 1680 1681 /* Update stopped status. */ 1682 ASMAtomicWriteBool(&pProcess->fStopped, true); 1683 1671 1684 if (cArgs) 1672 1685 RTGetOptArgvFree(papszArgs); … … 1676 1689 * forever on this thread. 1677 1690 */ 1678 if (RT_FAILURE(rc) && !fSignalled) 1691 if ( RT_FAILURE(rc) 1692 && !fSignalled) 1693 { 1679 1694 RTThreadUserSignal(RTThreadSelf()); 1680 1681 VGSvcVerbose(3, "[PID %RU32]: Thread of process '%s' ended with rc=%Rrc\n", 1682 pProcess->uPID, pProcess->StartupInfo.szCmd, rc); 1683 1684 /* Finally, update stopped status. */ 1685 ASMAtomicWriteBool(&pProcess->fStopped, true); 1695 } 1696 1697 /* Set shut down flag in case we've forgotten it. */ 1686 1698 ASMAtomicWriteBool(&pProcess->fShutdown, true); 1699 1700 VGSvcVerbose(3, "[PID %RU32]: Thread of process '%s' ended with rc=%Rrc (fSignalled=%RTbool)\n", 1701 pProcess->uPID, pProcess->StartupInfo.szCmd, rc, fSignalled); 1687 1702 1688 1703 return rc; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r82968 r83286 60 60 VBOXSERVICESESSIONOPT_THREAD_ID 61 61 }; 62 63 64 static int vgsvcGstCtrlSessionCleanupProcesses(const PVBOXSERVICECTRLSESSION pSession); 62 65 63 66 … … 1054 1057 if (RT_SUCCESS(rc)) 1055 1058 { 1059 vgsvcGstCtrlSessionCleanupProcesses(pSession); 1060 1056 1061 if (fStartAllowed) 1057 1062 rc = VGSvcGstCtrlProcessStart(pSession, &startupInfo, pHostCtx->uContextID); … … 1226 1231 { 1227 1232 rc = VGSvcGstCtrlProcessHandleTerm(pProcess); 1233 if (RT_FAILURE(rc)) 1234 VGSvcError("Error terminating PID=%RU32, rc=%Rrc\n", uPID, rc); 1228 1235 1229 1236 VGSvcGstCtrlProcessRelease(pProcess); … … 1233 1240 VGSvcError("Could not find PID %u for termination.\n", uPID); 1234 1241 rc = VERR_PROCESS_NOT_FOUND; 1235 /** @todo r=bird:1236 *1237 * No way to report status status code for output requests?1238 *1239 */1240 1242 } 1241 1243 } … … 1838 1840 1839 1841 /* Signal all guest processes in the active list that we want to shutdown. */ 1840 size_t cProcesses = 0;1841 1842 PVBOXSERVICECTRLPROCESS pProcess; 1842 1843 RTListForEach(&pSession->lstProcesses, pProcess, VBOXSERVICECTRLPROCESS, Node) 1843 {1844 1844 VGSvcGstCtrlProcessStop(pProcess); 1845 cProcesses++; 1846 } 1847 1848 VGSvcVerbose(1, "%zu guest processes were signalled to stop\n", cProcesses); 1845 1846 VGSvcVerbose(1, "%RU32 guest processes were signalled to stop\n", pSession->cProcesses); 1849 1847 1850 1848 /* Wait for all active threads to shutdown and destroy the active thread list. */ … … 1947 1945 RTListInit(&pSession->lstFiles); 1948 1946 1947 pSession->cProcesses = 0; 1948 pSession->cFiles = 0; 1949 1949 1950 pSession->fFlags = fFlags; 1950 1951 … … 1972 1973 if (RT_SUCCESS(rc)) 1973 1974 { 1974 VGSvcVerbose( 1975 VGSvcVerbose(3, "Adding process (PID %RU32) to session ID=%RU32\n", pProcess->uPID, pSession->StartupInfo.uSessionID); 1975 1976 1976 1977 /* Add process to session list. */ 1977 1978 RTListAppend(&pSession->lstProcesses, &pProcess->Node); 1979 1980 pSession->cProcesses++; 1981 VGSvcVerbose(3, "Now session ID=%RU32 has %RU32 processes total\n", 1982 pSession->StartupInfo.uSessionID, pSession->cProcesses); 1978 1983 1979 1984 int rc2 = RTCritSectLeave(&pSession->CritSect); … … 2002 2007 { 2003 2008 VGSvcVerbose(3, "Removing process (PID %RU32) from session ID=%RU32\n", pProcess->uPID, pSession->StartupInfo.uSessionID); 2004 Assert (pProcess->cRefs == 0);2009 AssertReturn(pProcess->cRefs == 0, VERR_WRONG_ORDER); 2005 2010 2006 2011 RTListNodeRemove(&pProcess->Node); 2012 2013 AssertReturn(pSession->cProcesses, VERR_WRONG_ORDER); 2014 pSession->cProcesses--; 2015 VGSvcVerbose(3, "Now session ID=%RU32 has %RU32 processes total\n", 2016 pSession->StartupInfo.uSessionID, pSession->cProcesses); 2007 2017 2008 2018 int rc2 = RTCritSectLeave(&pSession->CritSect); … … 2011 2021 } 2012 2022 2013 return VINF_SUCCESS;2023 return rc; 2014 2024 } 2015 2025 … … 2021 2031 * @return VBox status code. 2022 2032 * @param pSession The guest session. 2023 * @param p bAllowedTrue if starting (another) guest process2024 * is allowed, false if not.2033 * @param pfAllowed \c True if starting (another) guest process 2034 * is allowed, \c false if not. 2025 2035 */ 2026 int VGSvcGstCtrlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *p bAllowed)2036 int VGSvcGstCtrlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pfAllowed) 2027 2037 { 2028 2038 AssertPtrReturn(pSession, VERR_INVALID_POINTER); 2029 AssertPtrReturn(p bAllowed, VERR_INVALID_POINTER);2039 AssertPtrReturn(pfAllowed, VERR_INVALID_POINTER); 2030 2040 2031 2041 int rc = RTCritSectEnter(&pSession->CritSect); … … 2039 2049 if (pSession->uProcsMaxKept) /* If we allow unlimited processes (=0), take a shortcut. */ 2040 2050 { 2041 uint32_t uProcsRunning = 0; 2042 PVBOXSERVICECTRLPROCESS pProcess; 2043 RTListForEach(&pSession->lstProcesses, pProcess, VBOXSERVICECTRLPROCESS, Node) 2044 uProcsRunning++; 2045 2046 VGSvcVerbose(3, "Maximum served guest processes set to %u, running=%u\n", pSession->uProcsMaxKept, uProcsRunning); 2047 2048 int32_t iProcsLeft = (pSession->uProcsMaxKept - uProcsRunning - 1); 2051 VGSvcVerbose(3, "Maximum kept guest processes set to %RU32, acurrent=%RU32\n", 2052 pSession->uProcsMaxKept, pSession->cProcesses); 2053 2054 int32_t iProcsLeft = (pSession->uProcsMaxKept - pSession->cProcesses - 1); 2049 2055 if (iProcsLeft < 0) 2050 2056 { 2051 VGSvcVerbose(3, "Maximum running guest processes reached (% u)\n", pSession->uProcsMaxKept);2057 VGSvcVerbose(3, "Maximum running guest processes reached (%RU32)\n", pSession->uProcsMaxKept); 2052 2058 fLimitReached = true; 2053 2059 } 2054 2060 } 2055 2061 2056 *p bAllowed = !fLimitReached;2062 *pfAllowed = !fLimitReached; 2057 2063 2058 2064 int rc2 = RTCritSectLeave(&pSession->CritSect); … … 2060 2066 rc = rc2; 2061 2067 } 2068 2069 return rc; 2070 } 2071 2072 2073 /** 2074 * Cleans up stopped and no longer used processes. 2075 * 2076 * This will free and remove processes from the session's process list. 2077 * 2078 * @returns VBox status code. 2079 * @param pSession Session to clean up processes for. 2080 */ 2081 static int vgsvcGstCtrlSessionCleanupProcesses(const PVBOXSERVICECTRLSESSION pSession) 2082 { 2083 AssertPtrReturn(pSession, VERR_INVALID_POINTER); 2084 2085 VGSvcVerbose(3, "Cleaning up stopped processes for session %RU32 ...\n", pSession->StartupInfo.uSessionID); 2086 2087 int rc2 = RTCritSectEnter(&pSession->CritSect); 2088 AssertRC(rc2); 2089 2090 int rc = VINF_SUCCESS; 2091 2092 PVBOXSERVICECTRLPROCESS pCurProcess, pNextProcess; 2093 RTListForEachSafe(&pSession->lstProcesses, pCurProcess, pNextProcess, VBOXSERVICECTRLPROCESS, Node) 2094 { 2095 if (ASMAtomicReadBool(&pCurProcess->fStopped)) 2096 { 2097 rc2 = RTCritSectLeave(&pSession->CritSect); 2098 AssertRC(rc2); 2099 2100 rc = VGSvcGstCtrlProcessWait(pCurProcess, 30 * 1000 /* Wait 30 seconds max. */, NULL /* rc */); 2101 if (RT_SUCCESS(rc)) 2102 { 2103 VGSvcGstCtrlSessionProcessRemove(pSession, pCurProcess); 2104 VGSvcGstCtrlProcessFree(pCurProcess); 2105 } 2106 2107 rc2 = RTCritSectEnter(&pSession->CritSect); 2108 AssertRC(rc2); 2109 2110 /* If failed, try next time we're being called. */ 2111 } 2112 } 2113 2114 rc2 = RTCritSectLeave(&pSession->CritSect); 2115 AssertRC(rc2); 2116 2117 if (RT_FAILURE(rc)) 2118 VGSvcError("Cleaning up stopped processes for session %RU32 failed with %Rrc\n", pSession->StartupInfo.uSessionID, rc); 2062 2119 2063 2120 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.