Jacek Caban : ieframe: Make get_typeinfo implementation thread safe and more generic.

Alexandre Julliard julliard at winehq.org
Sat Feb 11 10:28:39 CST 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Feb 10 12:36:29 2012 +0100

ieframe: Make get_typeinfo implementation thread safe and more generic.

---

 dlls/ieframe/ieframe.h      |   12 +++++++-
 dlls/ieframe/ieframe_main.c |   70 +++++++++++++++++++++++++++++++++---------
 dlls/ieframe/webbrowser.c   |    6 ++--
 3 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/dlls/ieframe/ieframe.h b/dlls/ieframe/ieframe.h
index 2953841..ac3e34d 100644
--- a/dlls/ieframe/ieframe.h
+++ b/dlls/ieframe/ieframe.h
@@ -283,7 +283,17 @@ void released_obj(void) DECLSPEC_HIDDEN;
 void register_iewindow_class(void) DECLSPEC_HIDDEN;
 void unregister_iewindow_class(void) DECLSPEC_HIDDEN;
 
-HRESULT get_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN;
+#define TID_LIST \
+    XIID(IWebBrowser2)
+
+typedef enum {
+#define XIID(iface) iface ## _tid,
+TID_LIST
+#undef XIID
+    LAST_tid
+} tid_t;
+
+HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
 HRESULT register_class_object(BOOL) DECLSPEC_HIDDEN;
 
 HRESULT WINAPI CUrlHistory_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
diff --git a/dlls/ieframe/ieframe_main.c b/dlls/ieframe/ieframe_main.c
index cb810cc..cbdff92 100644
--- a/dlls/ieframe/ieframe_main.c
+++ b/dlls/ieframe/ieframe_main.c
@@ -54,31 +54,72 @@ const char *debugstr_variant(const VARIANT *v)
     }
 }
 
-static ITypeInfo *wb_typeinfo = NULL;
+static ITypeLib *typelib;
+static ITypeInfo *typeinfos[LAST_tid];
 
-HRESULT get_typeinfo(ITypeInfo **typeinfo)
+static REFIID tid_ids[] = {
+#define XIID(iface) &IID_ ## iface,
+TID_LIST
+#undef XIID
+};
+
+static HRESULT load_typelib(void)
 {
-    ITypeLib *typelib;
     HRESULT hres;
+    ITypeLib *tl;
 
-    if(wb_typeinfo) {
-        *typeinfo = wb_typeinfo;
-        return S_OK;
-    }
-
-    hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &typelib);
+    hres = LoadRegTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, &tl);
     if(FAILED(hres)) {
         ERR("LoadRegTypeLib failed: %08x\n", hres);
         return hres;
     }
 
-    hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IWebBrowser2, &wb_typeinfo);
-    ITypeLib_Release(typelib);
-
-    *typeinfo = wb_typeinfo;
+    if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
+        ITypeLib_Release(tl);
     return hres;
 }
 
+HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
+{
+    HRESULT hres;
+
+    if(!typelib)
+        hres = load_typelib();
+    if(!typelib)
+        return hres;
+
+    if(!typeinfos[tid]) {
+        ITypeInfo *ti;
+
+        hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
+        if(FAILED(hres)) {
+            ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
+            return hres;
+        }
+
+        if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
+            ITypeInfo_Release(ti);
+    }
+
+    *typeinfo = typeinfos[tid];
+    return S_OK;
+}
+
+static void release_typelib(void)
+{
+    unsigned i;
+
+    if(!typelib)
+        return;
+
+    for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) {
+        if(typeinfos[i])
+            ITypeInfo_Release(typeinfos[i]);
+    }
+
+    ITypeLib_Release(typelib);
+}
+
 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
 {
     *ppv = NULL;
@@ -186,8 +227,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
         break;
     case DLL_PROCESS_DETACH:
         unregister_iewindow_class();
-        if(wb_typeinfo)
-            ITypeInfo_Release(wb_typeinfo);
+        release_typelib();
     }
 
     return TRUE;
diff --git a/dlls/ieframe/webbrowser.c b/dlls/ieframe/webbrowser.c
index 4846207..033cda8 100644
--- a/dlls/ieframe/webbrowser.c
+++ b/dlls/ieframe/webbrowser.c
@@ -200,7 +200,7 @@ static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, L
 
     TRACE("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
 
-    hres = get_typeinfo(&typeinfo);
+    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
     if(FAILED(hres))
         return hres;
 
@@ -220,7 +220,7 @@ static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
     TRACE("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
           lcid, rgDispId);
 
-    hres = get_typeinfo(&typeinfo);
+    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
     if(FAILED(hres))
         return hres;
 
@@ -239,7 +239,7 @@ static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember
     TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
             lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
 
-    hres = get_typeinfo(&typeinfo);
+    hres = get_typeinfo(IWebBrowser2_tid, &typeinfo);
     if(FAILED(hres))
         return hres;
 




More information about the wine-cvs mailing list