return mono_domain_from_appdomain (ad);
}
+/**
+ * mono_domain_set_config:
+ * @domain: MonoDomain initialized with the appdomain we want to change
+ * @base_dir: new base directory for the appdomain
+ * @config_file_name: path to the new configuration for the app domain
+ *
+ * Used to set the system configuration for an appdomain
+ *
+ * Without using this, embedded builds will get 'System.Configuration.ConfigurationErrorsException:
+ * Error Initializing the configuration system. ---> System.ArgumentException:
+ * The 'ExeConfigFilename' argument cannot be null.' for some managed calls.
+ */
+void
+mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *config_file_name)
+{
+ MONO_OBJECT_SETREF (domain->setup, application_base, mono_string_new (domain, base_dir));
+ MONO_OBJECT_SETREF (domain->setup, configuration_file, mono_string_new (domain, config_file_name));
+}
+
static MonoAppDomainSetup*
copy_app_domain_setup (MonoDomain *domain, MonoAppDomainSetup *setup)
{
/*
This function raises exceptions so it can cause as sorts of nasty stuff if called
while holding a lock.
+Returns old file name if shadow copy is disabled, new shadow copy file name if successful
+or NULL if source file not found.
FIXME bubble up the error instead of raising it here
*/
char *
if (copy_result == FALSE) {
g_free (shadow);
+
+ /* Fix for bug #17251 - if file not found try finding assembly by other means (it is not fatal error) */
+ if (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND)
+ return NULL; /* file not found, shadow copy failed */
+
exc = mono_get_exception_execution_engine ("Failed to create shadow copy (CopyFile).");
mono_raise_exception (exc);
}
void *data;
if (klass->has_static_refs && (data = mono_vtable_get_static_field_data (vtable)))
- mono_gc_bzero (data, mono_class_data_size (klass));
+ mono_gc_bzero_aligned (data, mono_class_data_size (klass));
}
typedef struct unload_data {
g_free (data);
return;
}
- } while (InterlockedCompareExchange (&data->refcount, count, count - 1) != count);
+ } while (InterlockedCompareExchange (&data->refcount, count - 1, count) != count);
}
static void
MonoAppDomainState prev_state;
MonoMethod *method;
unload_data *thread_data;
+ MonoNativeThreadId tid;
MonoDomain *caller_domain = mono_domain_get ();
/* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, GetCurrentThreadId ()); */
* First we create a separate thread for unloading, since
* we might have to abort some threads, including the current one.
*/
- /*
- * If we create a non-suspended thread, the runtime will hang.
- * See:
- * http://bugzilla.ximian.com/show_bug.cgi?id=27663
- */
-#if 0
- thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, 0, 0, NULL);
-#else
- thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, NULL);
- if (thread_handle == NULL) {
+ thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, &tid);
+ if (thread_handle == NULL)
return;
- }
- ResumeThread (thread_handle);
-#endif
+ mono_thread_info_resume (tid);
/* Wait for the thread */
while (!thread_data->done && WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {