VirtualBox

Changeset 4557

Show
Ignore:
Timestamp:
09/06/07 08:59:25 (1 year ago)
Author:
vboxsync
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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) */ 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy