VirtualBox

Ignore:
Timestamp:
May 26, 2010 1:54:41 PM (15 years ago)
Author:
vboxsync
Message:

VBoxService: Some cleanup - started with reviewing r61961, but got carried away...

File:
1 edited

Legend:

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

    r29776 r29817  
    5757#ifdef RT_OS_WINDOWS
    5858/** Signal shutdown to the Windows service thread. */
    59 bool volatile g_WindowsServiceShutdown;
     59static bool volatile g_fWindowsServiceShutdown;
    6060/** Event the Windows service thread waits for shutdown. */
    61 RTSEMEVENT g_WindowsServiceEvent;
     61static RTSEMEVENT g_hEvtWindowsService;
    6262#endif
    6363
     
    155155 * Displays a syntax error message.
    156156 *
    157  * @returns 1
     157 * @returns RTEXITCODE_SYNTAX.
    158158 * @param   pszFormat   The message text.
    159159 * @param   ...         Format arguments.
    160160 */
    161 int VBoxServiceSyntax(const char *pszFormat, ...)
     161RTEXITCODE VBoxServiceSyntax(const char *pszFormat, ...)
    162162{
    163163    RTStrmPrintf(g_pStdErr, "%s: syntax error: ", g_pszProgName);
     
    168168    va_end(va);
    169169
    170     return 1;
     170    return RTEXITCODE_SYNTAX;
    171171}
    172172
     
    175175 * Displays an error message.
    176176 *
    177  * @returns 1
     177 * @returns RTEXITCODE_FAILURE.
    178178 * @param   pszFormat   The message text.
    179179 * @param   ...         Format arguments.
    180180 */
    181 int VBoxServiceError(const char *pszFormat, ...)
     181RTEXITCODE VBoxServiceError(const char *pszFormat, ...)
    182182{
    183183    RTStrmPrintf(g_pStdErr, "%s: error: ", g_pszProgName);
     
    192192    va_end(va);
    193193
    194     return 1;
     194    return RTEXITCODE_FAILURE;
    195195}
    196196
     
    308308    VBoxServiceVerbose(2, "Initializing services ...\n");
    309309    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    310     {
    311310        if (g_aServices[j].fEnabled)
    312311        {
     
    326325            }
    327326        }
    328     }
    329327
    330328    /*
     
    357355    }
    358356
    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
    377357    return rc;
    378358}
     
    389369    int rc = VINF_SUCCESS;
    390370
    391     for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    392         ASMAtomicXchgBool(&g_aServices[j].fShutdown, true);
     371    /*
     372     * Signal all the services.
     373     */
     374    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
     375        ASMAtomicWriteBool(&g_aServices[j].fShutdown, true);
     376
     377    /*
     378     * Do the pfnStop callback on all running services.
     379     */
    393380    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    394381        if (g_aServices[j].fStarted)
     
    397384            g_aServices[j].pDesc->pfnStop();
    398385        }
     386
     387    /*
     388     * Wait for all the service threads to complete.
     389     */
    399390    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
    400391    {
     
    411402#ifdef RT_OS_WINDOWS
    412403                /* Notify SCM that it takes a bit longer ... */
    413                 VBoxServiceWinSetStatus(SERVICE_STOP_PENDING, i);
     404                VBoxServiceWinSetStopPendingStatus(i + j*32);
    414405#endif
    415406            }
     
    423414#ifdef RT_OS_WINDOWS
    424415    /*
    425      * As we're now done terminating all service threads,
    426      * we have to stop the main thread as well (if defined). Note that the termination
    427      * function will be called in a later context (when the main thread returns from the worker
    428      * function).
    429      */
    430     if (g_WindowsServiceEvent != NIL_RTSEMEVENT)
     416     * Wake up and tell the main() thread that we're shutting down (it's
     417     * sleeping in VBoxServiceMainWait).
     418     */
     419    if (g_hEvtWindowsService != NIL_RTSEMEVENT)
    431420    {
    432421        VBoxServiceVerbose(3, "Stopping the main thread...\n");
    433         ASMAtomicXchgBool(&g_WindowsServiceShutdown, true);
    434         rc = RTSemEventSignal(g_WindowsServiceEvent);
     422        ASMAtomicWriteBool(&g_fWindowsServiceShutdown, true);
     423        rc = RTSemEventSignal(g_hEvtWindowsService);
    435424        AssertRC(rc);
    436425    }
     
    442431
    443432
    444 #ifndef RT_OS_WINDOWS
    445 /**
    446  * Block all important signals, then explicitly wait until one of these
    447  * signal arrives.
    448  */
    449 static void VBoxServiceWaitSignal(void)
    450 {
     433/**
     434 * Block the main thread until the service shuts down.
     435 */
     436void VBoxServiceMainWait(void)
     437{
     438    int rc;
     439
     440#ifdef RT_OS_WINDOWS
     441    /*
     442     * Wait for the semaphore to be signalled.
     443     */
     444    VBoxServiceVerbose(1, "Waiting in main thread\n");
     445    rc = RTSemEventCreate(&g_hEvtWindowsService);
     446    AssertRC(rc);
     447    while (!ASMAtomicReadBool(&g_fWindowsServiceShutdown))
     448    {
     449        rc = RTSemEventWait(g_hEvtWindowsService, RT_INDEFINITE_WAIT);
     450        AssertRC(rc);
     451    }
     452    RTSemEventDestroy(g_hEvtWindowsService);
     453    g_hEvtWindowsService = NIL_RTSEMEVENT;
     454
     455#else
     456    /*
     457     * Wait explicitly for a HUP, INT, QUIT, ABRT or TERM signal, blocking
     458     * all important signals.
     459     *
     460     * The annoying EINTR/ERESTART loop is for the benefit of Solaris where
     461     * sigwait returns when we receive a SIGCHLD.  Kind of makes sense since
     462     */
    451463    sigset_t signalMask;
    452     int iSignal;
    453464    sigemptyset(&signalMask);
    454465    sigaddset(&signalMask, SIGHUP);
     
    459470    pthread_sigmask(SIG_BLOCK, &signalMask, NULL);
    460471
    461     /* This loop is required on Solaris at least. FreeBSD doesn't know ERESTART. */
    462     int rc;
     472    int iSignal;
    463473    do
    464474    {
     
    472482          );
    473483
    474     VBoxServiceVerbose(3, "VBoxServiceWaitSignal: Received signal %d (rc=%d)\n", iSignal, rc);
    475 }
     484    VBoxServiceVerbose(3, "VBoxServiceMainWait: Received signal %d (rc=%d)\n", iSignal, rc);
    476485#endif /* !RT_OS_WINDOWS */
     486}
    477487
    478488
     
    653663     * Daemonize if requested.
    654664     */
     665    RTEXITCODE rcExit;
    655666    if (fDaemonize && !fDaemonized)
    656667    {
    657668#ifdef RT_OS_WINDOWS
    658         /** @todo Should do something like VBoxSVC here, OR automatically re-register
    659          *        the service and start it. Involving VbglR3Daemonize isn't an option
    660          *        here.
    661          *
    662          *        Also, the idea here, IIRC, was to map the sub service to windows
    663          *        services. The todo below is for mimicking windows services on
    664          *        non-windows systems. Not sure if this is doable or not, but in anycase
    665          *        this code can be moved into -win.
    666          *
    667          *        You should return when StartServiceCtrlDispatcher, btw., not
    668          *        continue.
    669          */
    670669        VBoxServiceVerbose(2, "Starting service dispatcher ...\n");
    671         if (!StartServiceCtrlDispatcher(&g_aServiceTable[0]))
    672             return VBoxServiceError("StartServiceCtrlDispatcher: %u. Please start %s with option -f (foreground)!",
    673                                     GetLastError(), g_pszProgName);
    674         /* Service now lives in the control dispatcher registered above. */
     670        rcExit = VBoxServiceWinEnterCtrlDispatcher();
    675671#else
    676672        VBoxServiceVerbose(1, "Daemonizing...\n");
     
    694690         */
    695691        rc = VBoxServiceStartServices();
    696 #ifndef RT_OS_WINDOWS
     692        rcExit = RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
    697693        if (RT_SUCCESS(rc))
    698             VBoxServiceWaitSignal();
    699 #endif
     694            VBoxServiceMainWait();
    700695        VBoxServiceStopServices();
    701696    }
     
    713708
    714709    VBoxServiceVerbose(0, "Ended.\n");
    715     return RT_SUCCESS(rc) ? 0 : 1;
    716 }
     710    return rcExit;
     711}
     712
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