VirtualBox

Ignore:
Timestamp:
May 12, 2010 9:50:16 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
61556
Message:

Guest Control/VBoxService: Added support for cancel pending (blocking) calls; added support for properly stopping + shutting down main thread.

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r29345 r29438  
    358358        VBoxServiceVerbose(1, "Starting '%s' in the main thread\n", g_aServices[iMain].pDesc->pszName);
    359359        rc = g_aServices[iMain].pDesc->pfnWorker(&g_fShutdown);
    360         if (rc != VINF_SUCCESS) /* Only complain if service returned an error. Otherwise the service is a one-timer. */
    361         {
    362             VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc);
    363         }
     360        if (RT_SUCCESS(rc))
     361            VBoxServiceVerbose(1, "Main service '%s' successfully stopped.\n", g_aServices[iMain].pDesc->pszName);
     362        else /* Only complain if service returned an error. Otherwise the service is a one-timer. */
     363            VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc);           
     364        g_aServices[iMain].pDesc->pfnTerm();
    364365    }
    365366    return rc;
     
    376377{
    377378    int rc = VINF_SUCCESS;
     379    int iMain = VBoxServiceGetStartedServices();
    378380
    379381    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
     
    381383    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    382384        if (g_aServices[j].fStarted)
     385        {
     386            VBoxServiceVerbose(3, "Calling stop function for service '%s' ...\n", g_aServices[j].pDesc->pszName);
    383387            g_aServices[j].pDesc->pfnStop();
    384     for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    385         if (g_aServices[j].fEnabled)
     388        }
     389    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
     390
     391        if (    !g_aServices[j].fEnabled /* Only stop services which were started before. */
     392            ||  j == iMain)              /* Don't call the termination function for main service yet. */
     393        {
     394            continue;
     395        }
     396        else
    386397        {
    387398            if (g_aServices[j].Thread != NIL_RTTHREAD)
     
    405416        }
    406417
     418#ifdef RT_OS_WINDOWS
     419    /*
     420     * As we're now done terminating all service threads,
     421     * we have to stop the main thread as well (if defined). Note that the termination
     422     * function will be called in a later context (when the main thread returns from the worker
     423     * function).
     424     */
     425    if (iMain != ~0U)
     426    {
     427        VBoxServiceVerbose(3, "Stopping main service '%s' (%d) ...\n", g_aServices[iMain].pDesc->pszName, iMain);
     428
     429        ASMAtomicXchgBool(&g_fShutdown, true);
     430        g_aServices[iMain].pDesc->pfnStop();                     
     431    }
     432#endif
     433   
    407434    VBoxServiceVerbose(2, "Stopping services returned: rc=%Rrc\n", rc);
    408435    return rc;
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r29345 r29438  
    247247        uint32_t uNumParms;
    248248        VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n");
    249         rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms, 1000 /* 1s timeout */);
     249        rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms);
    250250        if (RT_FAILURE(rc))
    251251        {
     
    264264            switch(uMsg)
    265265            {
     266                case GETHOSTMSG_EXEC_HOST_CANCEL_WAIT:
     267                    VBoxServiceVerbose(3, "Control: Host asked us to quit ...\n");
     268                    break;
     269
    266270                case GETHOSTMSG_EXEC_START_PROCESS:
    267271                    rc = VBoxServiceControlHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms);
     
    283287
    284288        /* Do we need to shutdown? */
    285         if (*pfShutdown)
    286         {
    287             rc = 0;
     289        if (   *pfShutdown
     290            || uMsg == GETHOSTMSG_EXEC_HOST_CANCEL_WAIT)
     291        {
     292            rc = VINF_SUCCESS;
    288293            break;
    289294        }
     
    302307static DECLCALLBACK(void) VBoxServiceControlStop(void)
    303308{
     309    VBoxServiceVerbose(3, "Control: Stopping ...\n");
     310
    304311    /** @todo Later, figure what to do if we're in RTProcWait(). it's a very
    305312     *        annoying call since doesn't support timeouts in the posix world. */
    306313    RTSemEventMultiSignal(g_hControlEvent);
     314
     315    /*
     316     * Ask the host service to cancel all pending requests so that we can
     317     * shutdown properly here.
     318     */
     319    if (g_GuestControlSvcClientID)
     320    {
     321        int rc = VbglR3GuestCtrlCancelPendingWaits(g_GuestControlSvcClientID);
     322        if (RT_FAILURE(rc))
     323            VBoxServiceError("Control: Cancelling pending waits failed; rc=%Rrc\n", rc);
     324    }
    307325}
    308326
     
    311329static DECLCALLBACK(void) VBoxServiceControlTerm(void)
    312330{
     331    VBoxServiceVerbose(3, "Control: Terminating ...\n");
     332
    313333    /* Signal all threads that we want to shutdown. */
    314334    PVBOXSERVICECTRLTHREAD pNode;
     
    321341        if (pNode->Thread != NIL_RTTHREAD)
    322342        {
     343            /* Wait a bit ... */
    323344            int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL);
    324345            if (RT_FAILURE(rc2))
Note: See TracChangeset for help on using the changeset viewer.

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