Jacek Caban : mshtml: Make load_gecko thread safe.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 14 09:25:57 CST 2007


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb 13 18:06:25 2007 +0100

mshtml: Make load_gecko thread safe.

---

 dlls/mshtml/install.c        |    4 ++-
 dlls/mshtml/mshtml_private.h |    2 +-
 dlls/mshtml/nsembed.c        |   62 +++++++++++++++++++++++++++++------------
 3 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/dlls/mshtml/install.c b/dlls/mshtml/install.c
index ddc3edc..07f83e7 100644
--- a/dlls/mshtml/install.c
+++ b/dlls/mshtml/install.c
@@ -358,7 +358,7 @@ static INT_PTR CALLBACK installer_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
     return FALSE;
 }
 
-void install_wine_gecko(void)
+BOOL install_wine_gecko(void)
 {
     HANDLE hsem;
 
@@ -374,4 +374,6 @@ void install_wine_gecko(void)
 
     ReleaseSemaphore(hsem, 1, NULL);
     CloseHandle(hsem);
+
+    return TRUE;
 }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index ca5527b..7038c70 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -370,7 +370,7 @@ HRESULT HTMLElement_QI(HTMLElement*,REFIID,void**);
 HTMLDOMNode *get_node(HTMLDocument*,nsIDOMNode*);
 void release_nodes(HTMLDocument*);
 
-void install_wine_gecko(void);
+BOOL install_wine_gecko(void);
 
 /* editor */
 void handle_edit_event(HTMLDocument*,nsIDOMEvent*);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 31e9551..2cf4d88 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -321,30 +321,13 @@ static void set_profile(void)
     nsIProfile_Release(profile);
 }
 
-static BOOL load_gecko(void)
+static BOOL init_xpcom(PRUnichar *gre_path)
 {
     nsresult nsres;
     nsIObserver *pStartNotif;
     nsIComponentRegistrar *registrar = NULL;
     nsAString path;
     nsIFile *gre_dir;
-    PRUnichar gre_path[MAX_PATH];
-
-    static BOOL tried_load = FALSE;
-
-    TRACE("()\n");
-
-    if(tried_load)
-        return pCompMgr != NULL;
-    tried_load = TRUE;
-
-    if(!load_wine_gecko(gre_path) && !load_mozctl(gre_path) && !load_mozilla(gre_path)) {
-        install_wine_gecko();
-        if(!load_wine_gecko(gre_path)) {
-            MESSAGE("Could not load Mozilla. HTML rendering will be disabled.\n");
-            return FALSE;
-        }
-    }
 
     nsAString_Init(&path, gre_path);
     nsres = NS_NewLocalFile(&path, FALSE, &gre_dir);
@@ -408,6 +391,49 @@ static BOOL load_gecko(void)
     return TRUE;
 }
 
+static CRITICAL_SECTION cs_load_gecko;
+static CRITICAL_SECTION_DEBUG cs_load_gecko_dbg =
+{
+    0, 0, &cs_load_gecko,
+    { &cs_load_gecko_dbg.ProcessLocksList, &cs_load_gecko_dbg.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": load_gecko") }
+};
+static CRITICAL_SECTION cs_load_gecko = { &cs_load_gecko_dbg, -1, 0, 0, 0, 0 };
+
+static BOOL load_gecko(void)
+{
+    PRUnichar gre_path[MAX_PATH];
+    BOOL ret = FALSE;
+
+    static LONG loading_thread;
+
+    TRACE("()\n");
+
+    /* load_gecko may be called recursively */
+    if(loading_thread == GetCurrentThreadId())
+        return pCompMgr != NULL;
+
+    EnterCriticalSection(&cs_load_gecko);
+
+    if(!loading_thread) {
+        loading_thread = GetCurrentThreadId();
+
+        if(load_wine_gecko(gre_path)
+           || load_mozctl(gre_path)
+           || load_mozilla(gre_path)
+           || (install_wine_gecko() && load_wine_gecko(gre_path)))
+            ret = init_xpcom(gre_path);
+        else
+           MESSAGE("Could not load Mozilla. HTML rendering will be disabled.\n");
+    }else {
+        ret = pCompMgr != NULL;
+    }
+
+    LeaveCriticalSection(&cs_load_gecko);
+
+    return ret;
+}
+
 void *nsalloc(size_t size)
 {
     return nsIMemory_Alloc(nsmem, size);




More information about the wine-cvs mailing list