- Timestamp:
- Apr 18, 2013 12:21:20 PM (12 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h
r45415 r45604 50 50 /** Unknown request. */ 51 51 VBOXSERVICECTRLREQUEST_UNKNOWN = 0, 52 /** Main control thread asked used to quit. */53 VBOXSERVICECTRLREQUEST_QUIT = 1,54 52 /** Performs reading from stdout. */ 55 53 VBOXSERVICECTRLREQUEST_PROC_STDOUT = 50, … … 99 97 /** Event semaphore to serialize access. */ 100 98 RTSEMEVENTMULTI Event; 99 /** Flag indicating if this request is asynchronous or not. */ 100 bool fAsync; 101 101 /** The request type to handle. */ 102 102 VBOXSERVICECTRLREQUESTTYPE enmType; … … 321 321 * needs (or is asked) to shutdown. */ 322 322 bool volatile fShutdown; 323 /** Indicator set by the service thread exiting. */ 323 /** Whether the guest process thread already was 324 * stopped or not. */ 324 325 bool volatile fStopped; 325 /** Whether the service was started or not. */ 326 /** Whether the guest process thread was started 327 * or not. */ 326 328 bool fStarted; 327 329 /** Client ID. */ … … 382 384 extern int GstCntlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession); 383 385 /* Per-thread guest process functions. */ 384 extern int GstCntlProcessPerform(PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest );386 extern int GstCntlProcessPerform(PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest, bool fAsync); 385 387 extern int GstCntlProcessStart(const PVBOXSERVICECTRLSESSION pSession, const PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo, uint32_t uContext); 386 388 extern int GstCntlProcessStop(PVBOXSERVICECTRLPROCESS pProcess); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r45415 r45604 155 155 rc = gstcntlProcessRequestCancel(pProcess->pRequest); 156 156 if (RT_FAILURE(rc)) 157 VBoxServiceError("[PID %RU32]: Signalling request event failed, rc=%Rrc\n",157 VBoxServiceError("[PID %RU32]: Cancelling current request failed, rc=%Rrc\n", 158 158 pProcess->uPID, rc); 159 159 } … … 163 163 164 164 PVBOXSERVICECTRLREQUEST pRequest; 165 rc = GstCntlProcessRequestAlloc(&pRequest, VBOXSERVICECTRLREQUEST_ QUIT);165 rc = GstCntlProcessRequestAlloc(&pRequest, VBOXSERVICECTRLREQUEST_PROC_TERM); 166 166 if (RT_SUCCESS(rc)) 167 167 { 168 rc = GstCntlProcessPerform(pProcess, pRequest); 168 rc = GstCntlProcessPerform(pProcess, pRequest, 169 true /* Async */); 169 170 if (RT_FAILURE(rc)) 170 VBoxServiceVerbose(3, "[PID %RU32]: Sending quitrequest failed with rc=%Rrc\n",171 VBoxServiceVerbose(3, "[PID %RU32]: Sending termination request failed with rc=%Rrc\n", 171 172 pProcess->uPID, rc); 172 173 GstCntlProcessRequestFree(pRequest); 173 /* Deletion of pRequest will be done on request completion. */ 174 174 } 175 175 … … 211 211 /* pRc is optional. */ 212 212 213 int rc = VINF_SUCCESS; 214 if ( pProcess->Thread != NIL_RTTHREAD 215 && ASMAtomicReadBool(&pProcess->fStarted)) 216 { 217 VBoxServiceVerbose(2, "[PID %RU32]: Waiting for shutdown (%RU32ms) ...\n", 218 pProcess->uPID, msTimeout); 219 220 /* Wait a bit ... */ 221 int rcThread; 222 rc = RTThreadWait(pProcess->Thread, msTimeout, &rcThread); 223 if (RT_FAILURE(rc)) 224 { 225 VBoxServiceError("[PID %RU32]: Waiting for shutting down thread returned error rc=%Rrc\n", 226 pProcess->uPID, rc); 227 } 228 else 229 { 230 VBoxServiceVerbose(3, "[PID %RU32]: Thread reported exit code=%Rrc\n", 231 pProcess->uPID, rcThread); 232 if (pRc) 233 *pRc = rcThread; 234 } 213 AssertMsgReturn(ASMAtomicReadBool(&pProcess->fStarted), 214 ("Tried to wait on guest process=%p which has not been started yet\n", 215 pProcess), VERR_INVALID_PARAMETER); 216 217 /* Guest process already has been stopped, no need to wait. */ 218 if (ASMAtomicReadBool(&pProcess->fStopped)) 219 return VINF_SUCCESS; 220 221 VBoxServiceVerbose(2, "[PID %RU32]: Waiting for shutdown (%RU32ms) ...\n", 222 pProcess->uPID, msTimeout); 223 224 /* Wait a bit ... */ 225 int rcThread; 226 Assert(pProcess->Thread != NIL_RTTHREAD); 227 int rc = RTThreadWait(pProcess->Thread, msTimeout, &rcThread); 228 if (RT_FAILURE(rc)) 229 { 230 VBoxServiceError("[PID %RU32]: Waiting for shutting down thread returned error rc=%Rrc\n", 231 pProcess->uPID, rc); 232 } 233 else 234 { 235 VBoxServiceVerbose(3, "[PID %RU32]: Thread reported exit code=%Rrc\n", 236 pProcess->uPID, rcThread); 237 if (pRc) 238 *pRc = rcThread; 235 239 } 236 240 … … 392 396 393 397 /** 394 * Signals the given request. 398 * Completes the given request. After returning pRequest won't be valid 399 * anymore! 395 400 * 396 401 * @return IPRT status code. … … 398 403 * @param rc rc to set request result to. 399 404 */ 400 static int gstcntlProcess SignalRequest(PVBOXSERVICECTRLREQUEST pRequest, int rc)405 static int gstcntlProcessRequestComplete(PVBOXSERVICECTRLREQUEST pRequest, int rc) 401 406 { 402 407 AssertPtrReturn(pRequest, VERR_INVALID_POINTER); 403 408 404 /* Assign overall result. */ 405 pRequest->rc = rc; 409 int rc2; 410 if (!pRequest->fAsync) 411 { 412 /* Assign overall result. */ 413 pRequest->rc = rc; 406 414 407 415 #ifdef DEBUG_andy 408 VBoxServiceVerbose(4, "Handled req=%RU32, CID=%RU32, rc=%Rrc, cbData=%RU32, pvData=%p\n",409 pRequest->enmType, pRequest->uCID, pRequest->rc,410 pRequest->cbData, pRequest->pvData);416 VBoxServiceVerbose(4, "Handled req=%RU32, CID=%RU32, rc=%Rrc, cbData=%RU32, pvData=%p\n", 417 pRequest->enmType, pRequest->uCID, pRequest->rc, 418 pRequest->cbData, pRequest->pvData); 411 419 #endif 412 413 /* In any case, regardless of the result, we notify 414 * the main guest control to unblock it. */ 415 int rc2 = RTSemEventMultiSignal(pRequest->Event); 416 AssertRC(rc2); 420 /* Signal waiters. */ 421 rc2 = RTSemEventMultiSignal(pRequest->Event); 422 AssertRC(rc2); 423 424 pRequest = NULL; 425 } 426 else 427 { 428 #ifdef DEBUG_andy 429 VBoxServiceVerbose(4, "Deleting async req=%RU32, CID=%RU32, rc=%Rrc, cbData=%RU32, pvData=%p\n", 430 pRequest->enmType, pRequest->uCID, pRequest->rc, 431 pRequest->cbData, pRequest->pvData); 432 #endif 433 GstCntlProcessRequestFree(pRequest); 434 rc2 = VINF_SUCCESS; 435 } 417 436 418 437 return rc2; … … 420 439 421 440 422 static int gstcntlProcess HandleRequest(RTPOLLSET hPollSet, uint32_t fPollEvt,441 static int gstcntlProcessRequestHandle(RTPOLLSET hPollSet, uint32_t fPollEvt, 423 442 PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR, 424 443 PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest) … … 445 464 switch (pRequest->enmType) 446 465 { 447 case VBOXSERVICECTRLREQUEST_QUIT: /* Main control asked us to quit. */448 {449 /** @todo Check for some conditions to check to450 * veto quitting. */451 ASMAtomicXchgBool(&pProcess->fShutdown, true);452 rcReq = VERR_CANCELLED;453 break;454 }455 456 466 case VBOXSERVICECTRLREQUEST_PROC_STDIN: 457 467 case VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF: … … 532 542 || !fDefer) 533 543 { 534 rc = gstcntlProcessSignalRequest(pRequest, 535 RT_SUCCESS(rc) ? rcReq : rc); 536 537 /* No access to pRequest here anymore -- could be out of scope 538 * or modified already! */ 539 pProcess->pRequest = pRequest = NULL; 544 rc = gstcntlProcessRequestComplete(pRequest, 545 RT_SUCCESS(rc) ? rcReq : rc); 540 546 } 541 547 else /* Completing the request defered. */ … … 641 647 case VBOXSERVICECTRLPIPEID_IPC_NOTIFY: 642 648 pReq = pProcess->pRequest; /** @todo Implement request queue. */ 643 rc = gstcntlProcess HandleRequest(hPollSet, fPollEvt,649 rc = gstcntlProcessRequestHandle(hPollSet, fPollEvt, 644 650 phStdInW, phStdOutR, phStdErrR, 645 651 pProcess, pReq); 646 if (rc != VINF_AIO_TASK_PENDING) 647 pReq = NULL; 652 if (rc == VINF_AIO_TASK_PENDING) 653 VBoxServiceVerbose(4, "[PID %RU32]: pRequest=%p will be handled deferred\n", 654 pProcess->uPID, pReq); 648 655 break; 649 656 … … 660 667 pProcess->uPID, rc2, RTPollSetGetCount(hPollSet), idPollHnd, rc, fProcessAlive, pProcess->fShutdown); 661 668 #endif 662 663 669 if (RT_UNLIKELY(pProcess->fShutdown)) 664 670 break; /* We were asked to shutdown. */ … … 791 797 && pReq->enmType == VBOXSERVICECTRLREQUEST_PROC_TERM) 792 798 { 793 rc2 = gstcntlProcess SignalRequest(pReq,794 fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING);795 pReq = NULL;799 rc2 = gstcntlProcessRequestComplete(pReq, 800 fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING); 801 AssertRC(rc2); 796 802 } 797 803 else if (pReq) … … 878 884 VBoxServiceError("[PID %RU32]: Error reporting final status to host; rc=%Rrc\n", 879 885 pProcess->uPID, rc2); 880 if (RT_SUCCESS(rc))881 rc = rc2;882 886 } 883 887 else 884 888 VBoxServiceVerbose(3, "[PID %RU32]: Was started detached, no final status sent to host\n", 885 889 pProcess->uPID); 886 887 VBoxServiceVerbose(3, "[PID %RU32]: Process loop ended with rc=%Rrc\n", 888 pProcess->uPID, rc); 889 } 890 else 891 VBoxServiceError("[PID %RU32]: Loop failed with rc=%Rrc\n", 892 pProcess->uPID, rc); 890 } 891 892 VBoxServiceVerbose(3, "[PID %RU32]: Process loop ended with rc=%Rrc\n", 893 pProcess->uPID, rc); 893 894 return rc; 894 895 } … … 934 935 AssertPtrReturn(ppReq, VERR_INVALID_POINTER); 935 936 936 PVBOXSERVICECTRLREQUEST pReq = (PVBOXSERVICECTRLREQUEST)RTMemAlloc(sizeof(VBOXSERVICECTRLREQUEST)); 937 PVBOXSERVICECTRLREQUEST pReq = 938 (PVBOXSERVICECTRLREQUEST)RTMemAlloc(sizeof(VBOXSERVICECTRLREQUEST)); 937 939 AssertPtrReturn(pReq, VERR_NO_MEMORY); 938 940 939 941 RT_ZERO(*pReq); 942 pReq->fAsync = false; 940 943 pReq->enmType = enmType; 941 944 pReq->uCID = uCID; … … 1656 1659 VBoxServiceError("Error starting process, rc=%Rrc\n", rc); 1657 1660 /* 1658 * Tell the controlthread that it can continue1659 * spawning services. This needs to be done after the new1661 * Tell the session thread that it can continue 1662 * spawning guest processes. This needs to be done after the new 1660 1663 * process has been started because otherwise signal handling 1661 1664 * on (Open) Solaris does not work correctly (see @bugref{5068}). … … 1729 1732 1730 1733 /* Move thread to stopped thread list. */ 1731 int rc2 = GstCntlSessionListSet(pProcess->pSession,1734 /*int rc2 = GstCntlSessionListSet(pProcess->pSession, 1732 1735 pProcess, VBOXSERVICECTRLTHREADLIST_STOPPED); 1733 AssertRC(rc2); 1736 AssertRC(rc2);*/ 1734 1737 1735 1738 if (pProcess->uClientID) … … 1738 1741 { 1739 1742 VBGLR3GUESTCTRLCMDCTX ctx = { pProcess->uClientID, pProcess->uContextID }; 1740 rc2 = VbglR3GuestCtrlProcCbStatus(&ctx,1741 pProcess->uPID, PROC_STS_ERROR, rc,1742 NULL /* pvData */, 0 /* cbData */);1743 int rc2 = VbglR3GuestCtrlProcCbStatus(&ctx, 1744 pProcess->uPID, PROC_STS_ERROR, rc, 1745 NULL /* pvData */, 0 /* cbData */); 1743 1746 if (RT_FAILURE(rc2)) 1744 1747 VBoxServiceError("Could not report process failure error; rc=%Rrc (process error %Rrc)\n", … … 1754 1757 } 1755 1758 1756 VBoxServiceVerbose(3, "[PID %RU32]: Thread of process \"%s\" ended with rc=%Rrc\n",1757 pProcess->uPID, pProcess->StartupInfo.szCmd, rc);1758 1759 1759 /* Free argument + environment variable lists. */ 1760 1760 if (uNumEnvVars) … … 1767 1767 RTGetOptArgvFree(papszArgs); 1768 1768 1769 /* Update st arted/stopped status. */1769 /* Update stopped status. */ 1770 1770 ASMAtomicXchgBool(&pProcess->fStopped, true); 1771 ASMAtomicXchgBool(&pProcess->fStarted, false);1772 1771 1773 1772 /* … … 1778 1777 RTThreadUserSignal(RTThreadSelf()); 1779 1778 1780 VBoxServiceVerbose(3, "[PID %RU32]: Thread returned with rc=%Rrc\n",1781 pProcess->uPID, rc);1779 VBoxServiceVerbose(3, "[PID %RU32]: Thread of process \"%s\" ended with rc=%Rrc\n", 1780 pProcess->uPID, pProcess->StartupInfo.szCmd, rc); 1782 1781 return rc; 1783 1782 } … … 1875 1874 */ 1876 1875 int GstCntlProcessPerform(PVBOXSERVICECTRLPROCESS pProcess, 1877 PVBOXSERVICECTRLREQUEST pRequest) 1876 PVBOXSERVICECTRLREQUEST pRequest, 1877 bool fAsync) 1878 1878 { 1879 1879 AssertPtrReturn(pProcess, VERR_INVALID_POINTER); … … 1883 1883 1884 1884 int rc = VINF_SUCCESS; 1885 1886 AssertMsgReturn(pProcess->pRequest == NULL, 1887 ("Another request still is in progress (%p)\n", pProcess->pRequest), 1888 VERR_ACCESS_DENIED); 1885 1889 1886 1890 if (ASMAtomicReadBool(&pProcess->fShutdown)) … … 1908 1912 { 1909 1913 Assert(cbWritten); 1910 VBoxServiceVerbose(3, "[PID %RU32]: Waiting for response on pRequest=%p, enmType=%u, pvData=0x%p, cbData=%u\n", 1911 pProcess->uPID, pRequest, pRequest->enmType, pRequest->pvData, pRequest->cbData); 1912 1913 rc = GstCntlProcessRequestWait(pRequest); 1914 if (!fAsync) 1915 { 1916 VBoxServiceVerbose(3, "[PID %RU32]: Waiting for response on pRequest=%p, enmType=%u, pvData=0x%p, cbData=%u\n", 1917 pProcess->uPID, pRequest, pRequest->enmType, pRequest->pvData, pRequest->cbData); 1918 1919 rc = GstCntlProcessRequestWait(pRequest); 1920 if (RT_SUCCESS(rc)) 1921 pProcess->pRequest = NULL; 1922 } 1914 1923 } 1915 1924 } -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r45415 r45604 820 820 if (pProcess) 821 821 { 822 rc = GstCntlProcessPerform(pProcess, pRequest );822 rc = GstCntlProcessPerform(pProcess, pRequest, false /* Async */); 823 823 GstCntlProcessRelease(pProcess); 824 824 } … … 855 855 if (pProcess) 856 856 { 857 rc = GstCntlProcessPerform(pProcess, pRequest );857 rc = GstCntlProcessPerform(pProcess, pRequest, false /* Async */); 858 858 GstCntlProcessRelease(pProcess); 859 859 } … … 1024 1024 if (RT_SUCCESS(rc)) 1025 1025 { 1026 uint32_t uTimeoutsMS = 30 * 1000; /** @todo Make this configurable. Later. */1026 uint32_t uTimeoutsMS = 5 * 60 * 1000; /** @todo Make this configurable. Later. */ 1027 1027 uint64_t u64TimeoutStart = 0; 1028 1028 … … 1304 1304 * Close all guest processes. 1305 1305 */ 1306 VBoxServiceVerbose(0, "Stopping all guest processes ...\n"); 1306 1307 1307 1308 /* Signal all guest processes in the active list that we want to shutdown. */ … … 1310 1311 GstCntlProcessStop(pProcess); 1311 1312 1313 VBoxServiceVerbose(1, "All guest processes signalled to stop\n"); 1314 1312 1315 /* Wait for all active threads to shutdown and destroy the active thread list. */ 1313 1316 pProcess = RTListGetFirst(&pSession->lstProcessesActive, VBOXSERVICECTRLPROCESS, Node); … … 1328 1331 } 1329 1332 1333 RTListNodeRemove(&pProcess->Node); 1334 1330 1335 rc2 = GstCntlProcessFree(pProcess); 1331 1336 if (RT_FAILURE(rc2)) … … 1337 1342 } 1338 1343 1339 RTListNodeRemove(&pProcess->Node);1340 1341 1344 if (fLast) 1342 1345 break; … … 1357 1360 * Close all left guest files. 1358 1361 */ 1362 VBoxServiceVerbose(0, "Closing all guest files ...\n"); 1363 1359 1364 PVBOXSERVICECTRLFILE pFile; 1360 1365 pFile = RTListGetFirst(&pSession->lstFiles, VBOXSERVICECTRLFILE, Node); … … 1427 1432 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1428 1433 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1429 AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);1434 /* pcbRead is optional. */ 1430 1435 1431 1436 int rc = VINF_SUCCESS; … … 1456 1461 if (pProcess) 1457 1462 { 1458 rc = GstCntlProcessPerform(pProcess, pRequest );1463 rc = GstCntlProcessPerform(pProcess, pRequest, false /* Async */); 1459 1464 GstCntlProcessRelease(pProcess); 1460 1465 } … … 1700 1705 if (pProcess) 1701 1706 { 1702 rc = GstCntlProcessPerform(pProcess, pRequest );1707 rc = GstCntlProcessPerform(pProcess, pRequest, false /* Async */); 1703 1708 GstCntlProcessRelease(pProcess); 1704 1709 } … … 2090 2095 /* 2091 2096 * The fork should have received the same closing request, 2092 * so just wait 30s for the process to close. On timeout kill 2093 * it in a not so gentle manner. 2097 * so just wait for the process to close. 2094 2098 */ 2095 2099 if (ASMAtomicReadBool(&pThread->fStarted)) … … 2129 2133 2130 2134 int rc = GstCntlSessionThreadWait(pThread, 2131 30 * 1000 /* 30s timeout */, uFlags);2135 5 * 60 * 1000 /* 5 minutes timeout */, uFlags); 2132 2136 /** @todo Kill session process if still around? */ 2133 2137
Note:
See TracChangeset
for help on using the changeset viewer.