VirtualBox

Ignore:
Timestamp:
Jul 1, 2010 2:56:14 PM (15 years ago)
Author:
vboxsync
Message:

Spawn 2nd VBoxService instance to handle page fusion in order to work around issues when loading dlls with the
DONT_RESOLVE_DLL_REFERENCES flag.

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

Legend:

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

    r29817 r30560  
    505505    if (RT_FAILURE(rc))
    506506        return VBoxServiceError("VbglR3Init failed with rc=%Rrc.\n", rc);
     507
     508#ifdef RT_OS_WINDOWS
     509    /* Special forked VBoxService.exe process for handling page fusion. */
     510    if (    argc == 2
     511        &&  !strcmp(argv[1], "-pagefusionfork"))
     512    {
     513        return VBoxServicePageSharingInitFork();
     514    }
     515#endif
    507516
    508517    /* Do pre-init of services. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r30095 r30560  
    288288extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage);
    289289#endif
     290#if defined(VBOX_WITH_PAGE_SHARING) && defined(RT_OS_WINDOWS)
     291extern void VBoxServicePageSharingInitFork();
     292#endif
    290293
    291294RT_C_DECLS_END
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp

    r30037 r30560  
    2424#include <iprt/asm.h>
    2525#include <iprt/mem.h>
     26#include <iprt/process.h>
     27#include <iprt/env.h>
    2628#include <iprt/stream.h>
    2729#include <iprt/file.h>
     
    556558#endif
    557559
    558     /* @todo report system name and version */
    559560    /* Never fail here. */
    560561    return VINF_SUCCESS;
     
    571572
    572573    /*
    573      * Block here first for a minute as using DONT_RESOLVE_DLL_REFERENCES is kind of risky; other code that uses LoadLibrary on a dll loaded like this
    574      * before will end up crashing the process as the dll's init routine was never called.
    575      *
    576      * We have to use this feature as we can't simply execute all init code in our service process.
    577      *
     574     * Now enter the loop retrieving runtime data continuously.
    578575     */
    579     int rc = RTSemEventMultiWait(g_PageSharingEvent, 60000);
    580     if (*pfShutdown)
    581         goto end;
    582 
    583     if (rc != VERR_TIMEOUT && RT_FAILURE(rc))
    584     {
    585         VBoxServiceError("RTSemEventMultiWait failed; rc=%Rrc\n", rc);
    586         goto end;
    587     }
     576    for (;;)
     577    {
     578        VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: enabled=%d\n", VbglR3PageSharingIsEnabled());
     579
     580        if (VbglR3PageSharingIsEnabled())
     581            VBoxServicePageSharingInspectGuest();
     582
     583        /*
     584         * Block for a minute.
     585         *
     586         * The event semaphore takes care of ignoring interruptions and it
     587         * allows us to implement service wakeup later.
     588         */
     589        if (*pfShutdown)
     590            break;
     591        int rc = RTSemEventMultiWait(g_PageSharingEvent, 60000);
     592        if (*pfShutdown)
     593            break;
     594        if (rc != VERR_TIMEOUT && RT_FAILURE(rc))
     595        {
     596            VBoxServiceError("RTSemEventMultiWait failed; rc=%Rrc\n", rc);
     597            break;
     598        }
     599    }
     600
     601    RTSemEventMultiDestroy(g_PageSharingEvent);
     602    g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
     603
     604    VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: finished thread\n");
     605    return 0;
     606}
     607
     608#ifdef RT_OS_WINDOWS
     609void VBoxServicePageSharingInitFork()
     610{
     611    VBoxServiceVerbose(3, "VBoxServicePageSharingInitFork\n");
     612
     613    bool fShutdown = false;
     614    VBoxServicePageSharingInit();
     615    VBoxServicePageSharingWorker(&fShutdown);
     616}
     617
     618/** @copydoc VBOXSERVICE::pfnWorker */
     619DECLCALLBACK(int) VBoxServicePageSharingWorkerProcess(bool volatile *pfShutdown)
     620{
     621    RTPROCESS hProcess = NIL_RTPROCESS;
     622    int rc;
     623
     624    /*
     625     * Tell the control thread that it can continue
     626     * spawning services.
     627     */
     628    RTThreadUserSignal(RTThreadSelf());
    588629
    589630    /*
     
    592633    for (;;)
    593634    {
    594         VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: enabled=%d\n", VbglR3PageSharingIsEnabled());
    595 
    596         if (VbglR3PageSharingIsEnabled())
    597             VBoxServicePageSharingInspectGuest();
     635        VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: enabled=%d\n", VbglR3PageSharingIsEnabled());
     636
     637        if (    VbglR3PageSharingIsEnabled()
     638            &&  hProcess == NIL_RTPROCESS)
     639        {
     640            char szExeName[256];
     641            char *pszExeName;
     642            char *pszArgs[3];
     643
     644            pszExeName = RTProcGetExecutableName(szExeName, sizeof(szExeName));
     645
     646            if (pszExeName)
     647            {
     648                pszArgs[0] = pszExeName;
     649                pszArgs[1] = "-pagefusionfork";
     650                pszArgs[2] = NULL;
     651                /* Start a 2nd VBoxService process to deal with page fusion as we do not wish to dummy load
     652                 * dlls into this process. (first load with DONT_RESOLVE_DLL_REFERENCES, 2nd normal -> dll init routines not called!)
     653                 */
     654                rc = RTProcCreate(pszExeName, pszArgs, RTENV_DEFAULT, 0 /* normal child */, &hProcess);
     655                if (rc != VINF_SUCCESS)
     656                    VBoxServiceError("RTProcCreate %s failed; rc=%Rrc\n", pszExeName, rc);
     657            }
     658        }
    598659
    599660        /*
     
    615676    }
    616677
    617 end:
     678    if (hProcess)
     679        RTProcTerminate(hProcess);
     680
    618681    RTSemEventMultiDestroy(g_PageSharingEvent);
    619682    g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
    620683
    621     VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: finished thread\n");
     684    VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: finished thread\n");
    622685    return 0;
    623686}
     687
     688#endif
    624689
    625690/** @copydoc VBOXSERVICE::pfnTerm */
     
    660725    VBoxServicePageSharingOption,
    661726    VBoxServicePageSharingInit,
     727#ifdef RT_OS_WINDOWS
     728    VBoxServicePageSharingWorkerProcess,
     729#else
    662730    VBoxServicePageSharingWorker,
     731#endif
    663732    VBoxServicePageSharingStop,
    664733    VBoxServicePageSharingTerm
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