#include <mono/metadata/marshal.h>
#include <mono/metadata/runtime.h>
#include <mono/metadata/object-internals.h>
-#include <mono/metadata/mono-debug-debugger.h>
+#include <mono/metadata/debug-internals.h>
#include <mono/utils/monobitset.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-mmap.h>
StaticDataFreeList *freelist;
} StaticDataInfo;
-/* Number of cached culture objects in the MonoThread->cached_culture_info array
- * (per-type): we use the first NUM entries for CultureInfo and the last for
- * UICultureInfo. So the size of the array is really NUM_CACHED_CULTURES * 2.
- */
-#define NUM_CACHED_CULTURES 4
-#define CULTURES_START_IDX 0
-#define UICULTURES_START_IDX NUM_CACHED_CULTURES
-
/* Controls access to the 'threads' hash table */
static void mono_threads_lock (void);
static void mono_threads_unlock (void);
if (shutting_down && !force_attach) {
mono_threads_unlock ();
+ mono_thread_pop_appdomain_ref ();
return FALSE;
}
*/
mono_threads_join_threads ();
- mono_error_init (error);
+ error_init (error);
mono_threads_lock ();
if (shutting_down) {
MonoInternalThread *internal;
gboolean res;
- mono_error_init (error);
+ error_init (error);
internal = create_internal_thread_object ();
thread->abort_exc = NULL;
thread->current_appcontext = NULL;
- /*
- * This is necessary because otherwise we might have
- * cross-domain references which will not get cleaned up when
- * the target domain is unloaded.
- */
- if (thread->cached_culture_info) {
- int i;
- for (i = 0; i < NUM_CACHED_CULTURES * 2; ++i)
- mono_array_set (thread->cached_culture_info, MonoObject*, i, NULL);
- }
-
/*
* thread->synch_cs can be NULL if this was called after
* ves_icall_System_Threading_InternalThread_Thread_free_internal.
if (thread == mono_thread_internal_current ())
mono_thread_pop_appdomain_ref ();
- thread->cached_culture_info = NULL;
-
mono_free_static_data (thread->static_data);
thread->static_data = NULL;
ref_stack_destroy (thread->appdomain_refs);
MonoError error;
MonoString* str;
- mono_error_init (&error);
+ error_init (&error);
LOCK_THREAD (this_obj);
{
LOCK_THREAD (this_obj);
- mono_error_init (error);
+ error_init (error);
if (reset) {
this_obj->flags &= ~MONO_THREAD_FLAG_NAME_SET;
{
MonoArray *copy;
- mono_error_init (error);
+ error_init (error);
if (!arr)
return NULL;
gint32 diff_ms;
gint32 wait = ms;
- mono_error_init (error);
+ error_init (error);
start = (ms == -1) ? 0 : mono_msec_ticks ();
for (;;) {
gint32 diff_ms;
gint32 wait = ms;
- mono_error_init (error);
+ error_init (error);
start = (ms == -1) ? 0 : mono_100ns_ticks ();
do {
return found;
}
-static gboolean
-request_thread_stop (MonoInternalThread *thread)
+void
+mono_thread_stop (MonoThread *thread)
{
- LOCK_THREAD (thread);
+ MonoInternalThread *internal = thread->internal_thread;
- if ((thread->state & ThreadState_StopRequested) != 0 ||
- (thread->state & ThreadState_Stopped) != 0)
+ LOCK_THREAD (internal);
+
+ if (internal->state & (ThreadState_StopRequested | ThreadState_Stopped))
{
- UNLOCK_THREAD (thread);
- return FALSE;
+ UNLOCK_THREAD (internal);
+ return;
}
-
- /* Make sure the thread is awake */
- mono_thread_resume (thread);
- thread->state |= ThreadState_StopRequested;
- thread->state &= ~ThreadState_AbortRequested;
-
- UNLOCK_THREAD (thread);
- return TRUE;
-}
+ /* Make sure the internal is awake */
+ mono_thread_resume (internal);
-/**
- * mono_thread_internal_stop:
- *
- * Request thread @thread to stop.
- *
- * @thread MUST NOT be the current thread.
- */
-void
-mono_thread_internal_stop (MonoInternalThread *thread)
-{
- g_assert (thread != mono_thread_internal_current ());
+ internal->state |= ThreadState_StopRequested;
+ internal->state &= ~ThreadState_AbortRequested;
- if (!request_thread_stop (thread))
- return;
-
- async_abort_internal (thread, TRUE);
-}
-
-void mono_thread_stop (MonoThread *thread)
-{
- MonoInternalThread *internal = thread->internal_thread;
+ UNLOCK_THREAD (internal);
- if (!request_thread_stop (internal))
- return;
-
if (internal == mono_thread_internal_current ()) {
MonoError error;
self_abort_internal (&error);
MonoDebugSourceLocation *location;
int tindex, nthreads;
- mono_error_init (error);
+ error_init (error);
*out_threads = NULL;
*out_stack_frames = NULL;
return TRUE;
}
-static void
-clear_cached_culture (gpointer key, gpointer value, gpointer user_data)
-{
- MonoInternalThread *thread = (MonoInternalThread*)value;
- MonoDomain *domain = (MonoDomain*)user_data;
- int i;
-
- /* No locking needed here */
- /* FIXME: why no locking? writes to the cache are protected with synch_cs above */
-
- if (thread->cached_culture_info) {
- for (i = 0; i < NUM_CACHED_CULTURES * 2; ++i) {
- MonoObject *obj = mono_array_get (thread->cached_culture_info, MonoObject*, i);
- if (obj && obj->vtable->domain == domain)
- mono_array_set (thread->cached_culture_info, MonoObject*, i, NULL);
- }
- }
-}
-
-/*
- * mono_threads_clear_cached_culture:
- *
- * Clear the cached_current_culture from all threads if it is in the
- * given appdomain.
- */
-void
-mono_threads_clear_cached_culture (MonoDomain *domain)
-{
- mono_threads_lock ();
- mono_g_hash_table_foreach (threads, clear_cached_culture, domain);
- mono_threads_unlock ();
-}
-
/*
* mono_thread_get_undeniable_exception:
*
if (mono_get_eh_callbacks ()->mono_install_handler_block_guard (mono_thread_info_get_suspend_state (info)))
return MonoResumeThread;
- /*
- The target thread is running at least one protected block, which must not be interrupted, so we give up.
- The protected block code will give them a chance when appropriate.
- */
- if (mono_thread_get_abort_prot_block_count (thread) > 0)
- return MonoResumeThread;
-
/*someone is already interrupting it*/
if (!mono_thread_set_interruption_requested (thread))
return MonoResumeThread;
{
MonoException *exc;
- mono_error_init (error);
+ error_init (error);
/* FIXME this is insanely broken, it doesn't cause interruption to happen synchronously
* since passing FALSE to mono_thread_request_interruption makes sure it returns NULL */