[PATCH 1/5] gameux: Parse GDFs in a separate thread.

Henri Verbeet hverbeet at codeweavers.com
Tue Oct 11 10:24:51 CDT 2011


The res protocol handler dislikes running from a multithreaded apartment.
---
 dlls/gameux/gameexplorer.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/dlls/gameux/gameexplorer.c b/dlls/gameux/gameexplorer.c
index 322dd7a..c6935c9 100644
--- a/dlls/gameux/gameexplorer.c
+++ b/dlls/gameux/gameexplorer.c
@@ -387,6 +387,13 @@ static HRESULT GAMEUX_ParseGameDefinition(
 
     return hr;
 }
+
+struct parse_gdf_thread_param
+{
+    struct GAMEUX_GAME_DATA *GameData;
+    HRESULT hr;
+};
+
 /*******************************************************************************
  * GAMEUX_ParseGDFBinary
  *
@@ -399,8 +406,10 @@ static HRESULT GAMEUX_ParseGameDefinition(
  *                                  GDF will be stored in other fields of this
  *                                  structure.
  */
-static HRESULT GAMEUX_ParseGDFBinary(struct GAMEUX_GAME_DATA *GameData)
+static DWORD WINAPI GAMEUX_ParseGDFBinary(void *thread_param)
 {
+    struct parse_gdf_thread_param *ctx = thread_param;
+    struct GAMEUX_GAME_DATA *GameData = ctx->GameData;
     static const WCHAR sRes[] = {'r','e','s',':','/','/',0};
     static const WCHAR sDATA[] = {'D','A','T','A',0};
     static const WCHAR sSlash[] = {'/',0};
@@ -423,6 +432,8 @@ static HRESULT GAMEUX_ParseGDFBinary(struct GAMEUX_GAME_DATA *GameData)
     lstrcatW(sResourcePath, sSlash);
     lstrcatW(sResourcePath, ID_GDF_XML_STR);
 
+    CoInitialize(NULL);
+
     hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
             &IID_IXMLDOMDocument, (void**)&document);
 
@@ -474,8 +485,11 @@ static HRESULT GAMEUX_ParseGDFBinary(struct GAMEUX_GAME_DATA *GameData)
         IXMLDOMDocument_Release(document);
     }
 
-    return hr;
+    CoUninitialize();
+    ctx->hr = hr;
+    return 0;
 }
+
 /*******************************************************************
  * GAMEUX_RemoveRegistryRecord
  *
@@ -548,12 +562,35 @@ static HRESULT GAMEUX_RegisterGame(LPCWSTR sGDFBinaryPath,
 
     /* load data from GDF binary */
     if(SUCCEEDED(hr))
-        hr = GAMEUX_ParseGDFBinary(&GameData);
+    {
+        struct parse_gdf_thread_param thread_param;
+        HANDLE thread;
+        HRESULT hr;
+        DWORD ret;
+
+        thread_param.GameData = &GameData;
+        if(!(thread = CreateThread(NULL, 0, GAMEUX_ParseGDFBinary, &thread_param, 0, &ret)))
+        {
+            ERR("Failed to create thread.\n");
+            hr = E_FAIL;
+            goto done;
+        }
+        ret = WaitForSingleObject(thread, INFINITE);
+        CloseHandle(thread);
+        if(ret != WAIT_OBJECT_0)
+        {
+            ERR("Wait failed (%#x).\n", ret);
+            hr = E_FAIL;
+            goto done;
+        }
+        hr = thread_param.hr;
+    }
 
     /* save data to registry */
     if(SUCCEEDED(hr))
         hr = GAMEUX_WriteRegistryRecord(&GameData);
 
+done:
     GAMEUX_uninitGameData(&GameData);
     TRACE("returning 0x%08x\n", hr);
     return hr;
-- 
1.7.3.4




More information about the wine-patches mailing list