Module: wine Branch: master Commit: 770f864af492cf84b1e4d7427b1b04538dfaf754 URL: http://source.winehq.org/git/wine.git/?a=commit;h=770f864af492cf84b1e4d7427b...
Author: Jacek Caban jacek@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;