VirtualBox

Changeset 29762 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
May 24, 2010 4:21:41 PM (15 years ago)
Author:
vboxsync
Message:

VBoxService / Windows guests: Don't use a service as main thread but simply wait in an event semaphore

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

Legend:

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

    r28800 r29762  
    3131DWORD                 g_rcWinService = 0;
    3232SERVICE_STATUS_HANDLE g_hWinServiceStatus = NULL;
     33/** The semaphore for the dummy Windows service. */
     34static RTSEMEVENT     g_WindowsEvent = NIL_RTSEMEVENT;
    3335
    3436void WINAPI VBoxServiceWinMain (DWORD argc, LPTSTR *argv);
     
    331333        VBoxServiceWinSetStatus (SERVICE_RUNNING, 0);
    332334
    333         /*
    334          * Check that at least one service is enabled.
    335          */
    336         unsigned iMain = VBoxServiceGetStartedServices();
    337         rc = VBoxServiceStartServices(iMain); /* Start all the services. */
    338 
     335        rc = VBoxServiceStartServices();
    339336        if (RT_FAILURE(rc))
    340337            VBoxServiceWinSetStatus (SERVICE_STOPPED, 0);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r29761 r29762  
    3535#include <iprt/initterm.h>
    3636#include <iprt/path.h>
     37#include <iprt/semaphore.h>
    3738#include <iprt/string.h>
    3839#include <iprt/stream.h>
     
    5455/** The default service interval (the -i | --interval) option). */
    5556uint32_t g_DefaultInterval = 0;
    56 /** Shutdown the main thread. (later, for signals.) */
    57 bool volatile g_fShutdown;
     57#ifdef RT_OS_WINDOWS
     58/** Signal shutdown to the Windows service thread. */
     59bool volatile g_WindowsServiceShutdown;
     60/** Event the Windows service thread waits for shutdown. */
     61RTSEMEVENT g_WindowsServiceEvent;
     62#endif
    5863
    5964/**
     
    276281
    277282
    278 unsigned VBoxServiceGetStartedServices(void)
    279 {
    280     unsigned iMain = ~0U;
     283/**
     284 * Check if at least one service should be started.
     285 */
     286static bool VBoxServiceCheckStartedServices(void)
     287{
    281288    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    282289        if (g_aServices[j].fEnabled)
    283         {
    284             iMain = j;
    285             break;
    286         }
    287 
    288    return iMain; /* Return the index of the main service (must always come last!). */
     290            return true;
     291
     292   return false;
    289293}
    290294
     
    294298 *
    295299 * @returns VBox status code, errors are fully bitched.
    296  *
    297  * @param   iMain           The index of the service that belongs to the main
    298  *                          thread. Pass ~0U if none does.
    299  */
    300 int VBoxServiceStartServices(unsigned iMain)
     300 */
     301int VBoxServiceStartServices(void)
    301302{
    302303    int rc;
     
    307308    VBoxServiceVerbose(2, "Initializing services ...\n");
    308309    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
     310    {
    309311        if (g_aServices[j].fEnabled)
    310312        {
     
    324326            }
    325327        }
     328    }
    326329
    327330    /*
     
    332335    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    333336    {
    334         if (    !g_aServices[j].fEnabled
    335             ||  j == iMain)
     337        if (!g_aServices[j].fEnabled)
    336338            continue;
    337339
     
    354356        }
    355357    }
    356     if (   RT_SUCCESS(rc)
    357         && iMain != ~0U)
    358     {
    359         /* The final service runs in the main thread. */
    360         VBoxServiceVerbose(1, "Starting '%s' in the main thread\n", g_aServices[iMain].pDesc->pszName);
    361         rc = g_aServices[iMain].pDesc->pfnWorker(&g_fShutdown);
    362         if (RT_SUCCESS(rc))
    363             VBoxServiceVerbose(1, "Main service '%s' successfully stopped.\n", g_aServices[iMain].pDesc->pszName);
    364         else /* Only complain if service returned an error. Otherwise the service is a one-timer. */
    365             VBoxServiceError("Service '%s' stopped unexpected; rc=%Rrc\n", g_aServices[iMain].pDesc->pszName, rc);
    366         g_aServices[iMain].pDesc->pfnTerm();
    367     }
     358
     359#ifdef RT_OS_WINDOWS
     360    if (RT_SUCCESS(rc))
     361    {
     362        /* Block the main thread. */
     363        VBoxServiceVerbose(1, "Waiting in main thread\n");
     364        int rc = RTSemEventCreate(&g_WindowsServiceEvent);
     365        AssertRC(rc);
     366        for (;;)
     367        {
     368            if (g_WindowsServiceShutdown)
     369                break;
     370            rc = RTSemEventWait(g_WindowsServiceEvent, RT_INDEFINITE_WAIT);
     371            AssertRC(rc);
     372        }
     373        RTSemEventDestroy(g_WindowsServiceEvent);
     374        g_WindowsServiceEvent = NIL_RTSEMEVENT;
     375    }
     376#endif
    368377    return rc;
    369378}
     
    379388{
    380389    int rc = VINF_SUCCESS;
    381     unsigned iMain = VBoxServiceGetStartedServices();
    382390
    383391    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
     
    390398        }
    391399    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    392 
    393         if (    !g_aServices[j].fEnabled /* Only stop services which were started before. */
    394             ||  j == iMain)              /* Don't call the termination function for main service yet. */
     400    {
     401        if (!g_aServices[j].fEnabled) /* Only stop services which were started before. */
     402            continue;
     403        if (g_aServices[j].Thread != NIL_RTTHREAD)
    395404        {
    396             continue;
     405            VBoxServiceVerbose(2, "Waiting for service '%s' to stop ...\n", g_aServices[j].pDesc->pszName);
     406            for (int i = 0; i < 30; i++) /* Wait 30 seconds in total */
     407            {
     408                rc = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL);
     409                if (RT_SUCCESS(rc))
     410                    break;
     411#ifdef RT_OS_WINDOWS
     412                /* Notify SCM that it takes a bit longer ... */
     413                VBoxServiceWinSetStatus(SERVICE_STOP_PENDING, i);
     414#endif
     415            }
     416            if (RT_FAILURE(rc))
     417                VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc);
    397418        }
    398         else
    399         {
    400             if (g_aServices[j].Thread != NIL_RTTHREAD)
    401             {
    402                 VBoxServiceVerbose(2, "Waiting for service '%s' to stop ...\n", g_aServices[j].pDesc->pszName);
    403                 for (int i = 0; i < 30; i++) /* Wait 30 seconds in total */
    404                 {
    405                     rc = RTThreadWait(g_aServices[j].Thread, 1000 /* Wait 1 second */, NULL);
    406                     if (RT_SUCCESS(rc))
    407                         break;
    408 #ifdef RT_OS_WINDOWS
    409                     /* Notify SCM that it takes a bit longer ... */
    410                     VBoxServiceWinSetStatus(SERVICE_STOP_PENDING, i);
    411 #endif
    412                 }
    413                 if (RT_FAILURE(rc))
    414                     VBoxServiceError("Service '%s' failed to stop. (%Rrc)\n", g_aServices[j].pDesc->pszName, rc);
    415             }
    416             VBoxServiceVerbose(3, "Terminating service '%s' (%d) ...\n", g_aServices[j].pDesc->pszName, j);
    417             g_aServices[j].pDesc->pfnTerm();
    418         }
     419        VBoxServiceVerbose(3, "Terminating service '%s' (%d) ...\n", g_aServices[j].pDesc->pszName, j);
     420        g_aServices[j].pDesc->pfnTerm();
     421    }
    419422
    420423#ifdef RT_OS_WINDOWS
     
    425428     * function).
    426429     */
    427     if (iMain != ~0U)
    428     {
    429         VBoxServiceVerbose(3, "Stopping main service '%s' (%d) ...\n", g_aServices[iMain].pDesc->pszName, iMain);
    430 
    431         ASMAtomicXchgBool(&g_fShutdown, true);
    432         g_aServices[iMain].pDesc->pfnStop();
     430    if (g_WindowsServiceEvent != NIL_RTSEMEVENT)
     431    {
     432        VBoxServiceVerbose(3, "Stopping the main thread...\n");
     433        ASMAtomicXchgBool(&g_WindowsServiceShutdown, true);
     434        rc = RTSemEventSignal(g_WindowsServiceEvent);
     435        AssertRC(rc);
    433436    }
    434437#endif
     
    641644     * Check that at least one service is enabled.
    642645     */
    643     unsigned iMain = VBoxServiceGetStartedServices();
    644     if (iMain == ~0U)
     646    if (!VBoxServiceCheckStartedServices())
    645647        return VBoxServiceSyntax("At least one service must be enabled.\n");
    646 
    647 #ifndef RT_OS_WINDOWS
    648     /*
    649      * POSIX: No main service thread.
    650      */
    651     iMain = ~0U;
    652 #endif
    653648
    654649    VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n",
     
    698693         *          and return immediately.
    699694         */
    700         rc = VBoxServiceStartServices(iMain);
     695        rc = VBoxServiceStartServices();
    701696#ifndef RT_OS_WINDOWS
    702697        if (RT_SUCCESS(rc))
     
    720715    return RT_SUCCESS(rc) ? 0 : 1;
    721716}
    722 
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp

    r29627 r29762  
    253253    bool                        fProcessTimedOut    = false;
    254254    uint64_t                    MsProcessKilled     = UINT64_MAX;
    255     bool const                  fHavePipes          = hStdInW    != NIL_RTPIPE
    256                                                       || hStdOutR   != NIL_RTPIPE
    257                                                       || hStdErrR   != NIL_RTPIPE;
    258255    RTMSINTERVAL const          cMsPollBase         = hStdInW != NIL_RTPIPE
    259256                                                      ? 100   /* need to poll for input */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r29516 r29762  
    261261extern void VBoxServiceVerbose(int iLevel, const char *pszFormat, ...);
    262262extern int VBoxServiceArgUInt32(int argc, char **argv, const char *psz, int *pi, uint32_t *pu32, uint32_t u32Min, uint32_t u32Max);
    263 extern unsigned VBoxServiceGetStartedServices(void);
    264 extern int VBoxServiceStartServices(unsigned iMain);
     263extern int VBoxServiceStartServices(void);
    265264extern int VBoxServiceStopServices(void);
    266265
Note: See TracChangeset for help on using the changeset viewer.

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