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