Henri Verbeet : gameux: Parse GDFs in a separate thread.

Alexandre Julliard julliard at winehq.org
Tue Oct 11 14:03:39 CDT 2011


Module: wine
Branch: master
Commit: 95ede76673df1dafb3e716a4617c57922907694c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=95ede76673df1dafb3e716a4617c57922907694c

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Oct 11 17:24:51 2011 +0200

gameux: Parse GDFs in a separate thread.

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;




More information about the wine-cvs mailing list