Changeset 35638 in vbox for trunk/src/VBox/Main/glue
- Timestamp:
- Jan 19, 2011 7:10:49 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 69546
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/glue/initterm.cpp
r33540 r35638 247 247 * @return S_OK on success and a COM result code in case of failure. 248 248 */ 249 HRESULT Initialize( )249 HRESULT Initialize(bool fGui) 250 250 { 251 251 HRESULT rc = E_FAIL; … … 253 253 #if !defined(VBOX_WITH_XPCOM) 254 254 255 DWORD flags = COINIT_MULTITHREADED 255 /** 256 * We initialize COM in GUI thread in STA, to be compliant with QT and 257 * OLE requirments (for example to allow D&D), while other threads 258 * initialized in regular MTA. To allow fast proxyless access from 259 * GUI thread to COM objects, we explicitly provide our COM objects 260 * with free threaded marshaller. 261 * !!!!! Please think twice before touching this code !!!!! 262 */ 263 DWORD flags = fGui ? 264 COINIT_APARTMENTTHREADED 265 | COINIT_SPEED_OVER_MEMORY 266 : 267 COINIT_MULTITHREADED 256 268 | COINIT_DISABLE_OLE1DDE 257 269 | COINIT_SPEED_OVER_MEMORY; 258 270 259 271 rc = CoInitializeEx(NULL, flags); 260 261 /// @todo the below rough method of changing the apartment type doesn't262 /// work on some systems for unknown reason (CoUninitialize() simply does263 /// nothing there, or at least all 10 000 of subsequent CoInitializeEx()264 /// continue to return RPC_E_CHANGED_MODE there). The problem on those265 /// systems is related to the "Extend support for advanced text services266 /// to all programs" checkbox in the advanced language settings dialog,267 /// i.e. the problem appears when this checkbox is checked and disappears268 /// if you clear it. For this reason, we disable the code below and269 /// instead initialize COM in MTA as early as possible, before 3rd party270 /// libraries we use have done so (i.e. Qt).271 # if 0272 /* If we fail to set the necessary apartment model, it may mean that some273 * DLL that was indirectly loaded by the process calling this function has274 * already initialized COM on the given thread in an incompatible way275 * which we can't leave with. Therefore, we try to fix this by using the276 * brute force method: */277 278 if (rc == RPC_E_CHANGED_MODE)279 {280 /* Before we use brute force, we need to check if we are in the281 * neutral threaded apartment -- in this case there is no need to282 * worry at all. */283 284 rc = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);285 if (rc == RPC_E_CHANGED_MODE)286 {287 /* This is a neutral apartment, reset the error */288 rc = S_OK;289 290 LogFlowFunc(("COM is already initialized in neutral threaded "291 "apartment mode,\nwill accept it.\n"));292 }293 else if (rc == S_FALSE)294 {295 /* balance the test CoInitializeEx above */296 CoUninitialize();297 rc = RPC_E_CHANGED_MODE;298 299 LogFlowFunc(("COM is already initialized in single threaded "300 "apartment mode,\nwill reinitialize as "301 "multi threaded.\n"));302 303 enum { MaxTries = 10000 };304 int tries = MaxTries;305 while (rc == RPC_E_CHANGED_MODE && tries --)306 {307 CoUninitialize();308 rc = CoInitializeEx(NULL, flags);309 if (rc == S_OK)310 {311 /* We've successfully reinitialized COM; restore the312 * initialization reference counter */313 314 LogFlowFunc(("Will call CoInitializeEx() %d times.\n",315 MaxTries - tries));316 317 while (tries ++ < MaxTries)318 {319 rc = CoInitializeEx(NULL, flags);320 Assert(rc == S_FALSE);321 }322 }323 }324 }325 else326 AssertMsgFailed(("rc=%08X\n", rc));327 }328 # endif329 272 330 273 /* the overall result must be either S_OK or S_FALSE (S_FALSE means … … 342 285 else 343 286 fRc = false; 287 288 if (fGui) 289 Assert(RTThreadIsMain(hSelf)); 290 344 291 if (!fRc) 345 292 { … … 359 306 360 307 #else /* !defined (VBOX_WITH_XPCOM) */ 308 309 /* Unused here */ 310 (void)fGui; 361 311 362 312 if (ASMAtomicXchgBool(&gIsXPCOMInitialized, true) == true)
Note:
See TracChangeset
for help on using the changeset viewer.