ieframe: Make get_typeinfo implementation thread safe and more generic.

This commit is contained in:
Jacek Caban 2012-02-10 12:36:29 +01:00 committed by Alexandre Julliard
parent 096eeb1a1e
commit 770f864af4
3 changed files with 69 additions and 19 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;