VirtualBox

Changeset 4557 in vbox


Ignore:
Timestamp:
Sep 6, 2007 6:59:25 AM (17 years ago)
Author:
vboxsync
Message:

Main: Attempted to fix the CoInitializeEx race condition (#2304).

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/COMDefs.cpp

    r4071 r4557  
    9090    LogFlowFuncEnter();
    9191
    92     HRESULT rc = S_OK;
    93 
    94 #if !defined (VBOX_WITH_XPCOM)
    95 
    96     /* disable this damn CoInitialize* somehow made by Qt during
    97      * creation of the QApplication instance (didn't explore deeply
    98      * why does it do this) */
    99     CoUninitialize();
    100 
    101 #endif /* !defined (VBOX_WITH_XPCOM) */
    102 
    103     rc = com::Initialize();
     92    /* Note: On Win32, Qt somehow calls CoInitialize[Ex]() during creation of
     93     * the QApplication instance (didn't explore deeply why it does so) with
     94     * different flags which is incompatible with our multithreaded
     95     * apartment. com::Initialize() will properly care of this situation. */
     96
     97    HRESULT rc = com::Initialize();
    10498
    10599#if defined (VBOX_WITH_XPCOM)
  • trunk/src/VBox/Main/glue/initterm.cpp

    r4071 r4557  
    4646#include "VBox/com/assert.h"
    4747
     48#include "../include/Logging.h"
    4849
    4950namespace com
     
    171172#if !defined (VBOX_WITH_XPCOM)
    172173
    173     rc = CoInitializeEx (NULL, COINIT_MULTITHREADED |
    174                                COINIT_DISABLE_OLE1DDE |
    175                                COINIT_SPEED_OVER_MEMORY);
     174    DWORD flags = COINIT_MULTITHREADED |
     175                  COINIT_DISABLE_OLE1DDE |
     176                  COINIT_SPEED_OVER_MEMORY;
     177
     178    rc = CoInitializeEx (NULL, flags);
     179
     180    /* If we fail to set the necessary apartment model, it may mean that some
     181     * DLL that was indirectly loaded by the process calling this function has
     182     * already initialized COM on the given thread in an incompatible way
     183     * which we can't leave with. Therefore, we try to fix this by using the
     184     * brute force method: */
     185
     186    enum { MaxTries = 10000 };
     187    int tries = MaxTries;
     188    while (rc == RPC_E_CHANGED_MODE && tries --)
     189    {
     190        LogFlowFunc (("COM already initialized in wrong apartment mode, "
     191                      "will reinitialize.\n"));
     192
     193        CoUninitialize();
     194        rc = CoInitializeEx (NULL, flags);
     195        if (rc == S_OK)
     196        {
     197            /* We've successfully reinitialized COM; restore the
     198             * initialization reference counter */
     199
     200            LogFlowFunc (("Will call CoInitializeEx() %d times.\n",
     201                          MaxTries - tries));
     202
     203            while (tries ++ < MaxTries)
     204            {
     205                rc = CoInitializeEx (NULL, flags);
     206                Assert (rc == S_FALSE);
     207            }
     208        }
     209    }
     210
     211    /* the overall result must be either S_OK or S_FALSE */
     212    AssertMsg (rc == S_OK || rc == S_FALSE, ("rc=%08X\n", rc));
    176213
    177214#else /* !defined (VBOX_WITH_XPCOM) */
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