diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c index 7fc6867c9c7..94eca7f0f7e 100644 --- a/dlls/mscoree/corruntimehost.c +++ b/dlls/mscoree/corruntimehost.c @@ -68,6 +68,25 @@ struct dll_fixup void *tokens; /* pointer into process heap */ }; +static MonoDomain* domain_attach(MonoDomain *domain) +{ + MonoDomain *prev_domain = mono_domain_get(); + + if (prev_domain == domain) + /* Do not set or restore domain. */ + return NULL; + + mono_thread_attach(domain); + + return prev_domain; +} + +static void domain_restore(MonoDomain *prev_domain) +{ + if (prev_domain != NULL) + mono_domain_set(prev_domain, FALSE); +} + static HRESULT RuntimeHost_AddDefaultDomain(RuntimeHost *This, MonoDomain **result) { struct DomainEntry *entry; @@ -267,15 +286,17 @@ static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain, MonoObject *obj, void **args, int arg_count, MonoObject **result) { MonoMethod *method; + MonoDomain *prev_domain; HRESULT hr; *result = NULL; - mono_thread_attach(domain); + prev_domain = domain_attach(domain); if (!RuntimeHost_GetMethod(domain, assemblyname, namespace, typename, methodname, arg_count, &method)) { + domain_restore(prev_domain); return E_FAIL; } @@ -285,6 +306,8 @@ static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain, ERR("Method %s.%s:%s raised an exception, hr=%x\n", namespace, typename, methodname, hr); } + domain_restore(prev_domain); + return hr; } @@ -293,6 +316,7 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain, MonoObject *obj, void **args, int arg_count, MonoObject **result) { MonoMethod *method; + MonoDomain *prev_domain; HRESULT hr; *result = NULL; @@ -303,11 +327,12 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain, return E_POINTER; } - mono_thread_attach(domain); + prev_domain = domain_attach(domain); if (!RuntimeHost_GetMethod(domain, assemblyname, namespace, typename, methodname, arg_count, &method)) { + domain_restore(prev_domain); return E_FAIL; } @@ -315,6 +340,7 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain, if (!method) { ERR("Object %p does not support method %s.%s:%s\n", obj, namespace, typename, methodname); + domain_restore(prev_domain); return E_FAIL; } @@ -324,6 +350,8 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain, ERR("Method %s.%s:%s raised an exception, hr=%x\n", namespace, typename, methodname, hr); } + domain_restore(prev_domain); + return hr; } @@ -853,7 +881,7 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* { RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); HRESULT hr; - MonoDomain *domain; + MonoDomain *domain, *prev_domain; MonoObject *result; MonoString *str; char *filenameA = NULL, *classA = NULL, *methodA = NULL; @@ -864,10 +892,13 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); + if (FAILED(hr)) + return hr; + + prev_domain = domain_attach(domain); + if (SUCCEEDED(hr)) { - mono_thread_attach(domain); - filenameA = WtoA(pwzAssemblyPath); if (!filenameA) hr = E_OUTOFMEMORY; } @@ -917,6 +948,8 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* if (SUCCEEDED(hr)) *pReturnValue = *(DWORD*)mono_object_unbox(result); + domain_restore(prev_domain); + HeapFree(GetProcessHeap(), 0, filenameA); HeapFree(GetProcessHeap(), 0, classA); HeapFree(GetProcessHeap(), 0, argsA); @@ -952,10 +985,16 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, MonoType *type; MonoClass *klass; MonoObject *obj; + MonoDomain *prev_domain; if (!domain) hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); + if (FAILED(hr)) + return hr; + + prev_domain = domain_attach(domain); + if (SUCCEEDED(hr)) { nameA = WtoA(name); @@ -965,8 +1004,6 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, if (SUCCEEDED(hr)) { - mono_thread_attach(domain); - type = mono_reflection_type_from_name(nameA, NULL); if (!type) { @@ -1002,6 +1039,8 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, *result = obj; } + domain_restore(prev_domain); + HeapFree(GetProcessHeap(), 0, nameA); return hr; @@ -1014,9 +1053,7 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name, * * NOTE: The IUnknown* is created with a reference to the object. * Until they have a reference, objects must be in the stack to prevent the - * garbage collector from freeing them. - * - * mono_thread_attach must have already been called for this thread. */ + * garbage collector from freeing them. */ HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj, IUnknown **ppUnk) { @@ -1230,35 +1267,39 @@ static void CDECL ReallyFixupVTable(struct dll_fixup *fixup) if (SUCCEEDED(hr)) { - mono_thread_attach(domain); + MonoDomain *prev_domain; + + prev_domain = domain_attach(domain); assembly = mono_assembly_open(filenameA, &status); - } - if (assembly) - { - int i; + if (assembly) + { + int i; - /* Mono needs an image that belongs to an assembly. */ - image = mono_assembly_get_image(assembly); + /* Mono needs an image that belongs to an assembly. */ + image = mono_assembly_get_image(assembly); #if __x86_64__ - if (fixup->fixup->type & COR_VTABLE_64BIT) + if (fixup->fixup->type & COR_VTABLE_64BIT) #else - if (fixup->fixup->type & COR_VTABLE_32BIT) + if (fixup->fixup->type & COR_VTABLE_32BIT) #endif - { - void **vtable = fixup->vtable; - ULONG_PTR *tokens = fixup->tokens; - for (i=0; ifixup->count; i++) { - TRACE("%#lx\n", tokens[i]); - vtable[i] = mono_marshal_get_vtfixup_ftnptr( - image, tokens[i], fixup->fixup->type); + void **vtable = fixup->vtable; + ULONG_PTR *tokens = fixup->tokens; + for (i=0; ifixup->count; i++) + { + TRACE("%#lx\n", tokens[i]); + vtable[i] = mono_marshal_get_vtfixup_ftnptr( + image, tokens[i], fixup->fixup->type); + } } + + fixup->done = TRUE; } - fixup->done = TRUE; + domain_restore(prev_domain); } if (info != NULL) @@ -1686,13 +1727,14 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) MonoImage *image; MonoClass *klass; MonoObject *result; + MonoDomain *prev_domain; IUnknown *unk = NULL; char *filenameA, *ns; char *classA; hr = CLASS_E_CLASSNOTAVAILABLE; - mono_thread_attach(domain); + prev_domain = domain_attach(domain); filenameA = WtoA(filename); assembly = mono_domain_assembly_open(domain, filenameA); @@ -1700,6 +1742,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) if (!assembly) { ERR("Cannot open assembly %s\n", filenameA); + domain_restore(prev_domain); goto cleanup; } @@ -1707,6 +1750,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) if (!image) { ERR("Couldn't get assembly image\n"); + domain_restore(prev_domain); goto cleanup; } @@ -1719,6 +1763,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) if (!klass) { ERR("Couldn't get class from image\n"); + domain_restore(prev_domain); goto cleanup; } @@ -1737,6 +1782,8 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) } else hr = CLASS_E_CLASSNOTAVAILABLE; + + domain_restore(prev_domain); } else hr = CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index 201757d30ae..ca6914e99a6 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -79,7 +79,9 @@ MonoClass* (CDECL *mono_class_from_name)(MonoImage *image, const char* name_spac MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count); static void (CDECL *mono_config_parse)(const char *filename); MonoAssembly* (CDECL *mono_domain_assembly_open)(MonoDomain *domain, const char *name); +MonoDomain* (CDECL *mono_domain_get)(void); MonoDomain* (CDECL *mono_domain_get_by_id)(int id); +BOOL (CDECL *mono_domain_set)(MonoDomain *domain,BOOL force); void (CDECL *mono_domain_set_config)(MonoDomain *domain,const char *base_dir,const char *config_file_name); static void (CDECL *mono_free)(void *); static MonoImage* (CDECL *mono_image_open)(const char *fname, MonoImageOpenStatus *status); @@ -177,7 +179,9 @@ static HRESULT load_mono(LPCWSTR mono_path) LOAD_MONO_FUNCTION(mono_class_from_name); LOAD_MONO_FUNCTION(mono_class_get_method_from_name); LOAD_MONO_FUNCTION(mono_domain_assembly_open); + LOAD_MONO_FUNCTION(mono_domain_get); LOAD_MONO_FUNCTION(mono_domain_get_by_id); + LOAD_MONO_FUNCTION(mono_domain_set); LOAD_MONO_FUNCTION(mono_domain_set_config); LOAD_MONO_FUNCTION(mono_free); LOAD_MONO_FUNCTION(mono_image_open); diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h index c7399495869..9df41d20565 100644 --- a/dlls/mscoree/mscoree_private.h +++ b/dlls/mscoree/mscoree_private.h @@ -146,7 +146,9 @@ extern MonoClass* (CDECL *mono_class_from_mono_type)(MonoType *type) DECLSPEC_HI extern MonoClass* (CDECL *mono_class_from_name)(MonoImage *image, const char* name_space, const char *name) DECLSPEC_HIDDEN; extern MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count) DECLSPEC_HIDDEN; extern MonoAssembly* (CDECL *mono_domain_assembly_open)(MonoDomain *domain, const char *name) DECLSPEC_HIDDEN; -extern MonoDomain* (CDECL *mono_domain_get_by_id)(int id); +extern MonoDomain* (CDECL *mono_domain_get)(void) DECLSPEC_HIDDEN; +extern MonoDomain* (CDECL *mono_domain_get_by_id)(int id) DECLSPEC_HIDDEN; +extern BOOL (CDECL *mono_domain_set)(MonoDomain *domain, BOOL force) DECLSPEC_HIDDEN; extern void (CDECL *mono_domain_set_config)(MonoDomain *domain,const char *base_dir,const char *config_file_name) DECLSPEC_HIDDEN; extern int (CDECL *mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]) DECLSPEC_HIDDEN; extern MonoDomain* (CDECL *mono_jit_init_version)(const char *domain_name, const char *runtime_version) DECLSPEC_HIDDEN;