try_free_delayed_free_item (int index)
{
if (delayed_free_table->len > index) {
- DelayedFreeItem item;
+ DelayedFreeItem item = { NULL, NULL };
- item.p = NULL;
EnterCriticalSection (&delayed_free_table_mutex);
/* We have to check the length again because another
thread might have freed an item before we acquired
if (thread->serialized_culture_info)
g_free (thread->serialized_culture_info);
+ g_free (thread->name);
+
thread->cached_culture_info = NULL;
mono_gc_free_fixed (thread->static_data);
/* On 2.0 profile (and higher), set explicitly since state might have been
Unknown */
- if (mono_get_runtime_info ()->framework_version [0] != '1') {
+ if (mono_framework_version () != 1) {
if (thread->apartment_state == ThreadApartmentState_Unknown)
thread->apartment_state = ThreadApartmentState_MTA;
}
InitializeCriticalSection (thread->synch_cs);
thread->threadpool_thread = threadpool_thread;
+ if (threadpool_thread)
+ mono_thread_set_state (thread, ThreadState_Background);
if (handle_store (thread))
ResumeThread (thread_handle);
#if defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
*staddr = (guint8*)pthread_get_stackaddr_np (pthread_self ());
*stsize = pthread_get_stacksize_np (pthread_self ());
+ *staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
return;
/* FIXME: simplify the mess below */
#elif !defined(PLATFORM_WIN32)
pthread_attr_init (&attr);
#ifdef HAVE_PTHREAD_GETATTR_NP
- pthread_getattr_np (pthread_self(), &attr);
+ pthread_getattr_np (pthread_self(), &attr);
#else
#ifdef HAVE_PTHREAD_ATTR_GET_NP
- pthread_attr_get_np (pthread_self(), &attr);
+ pthread_attr_get_np (pthread_self(), &attr);
#elif defined(sun)
- *staddr = NULL;
- pthread_attr_getstacksize (&attr, &stsize);
+ *staddr = NULL;
+ pthread_attr_getstacksize (&attr, &stsize);
#else
- *staddr = NULL;
- *stsize = 0;
- return;
+ *staddr = NULL;
+ *stsize = 0;
+ return;
#endif
#endif
#ifndef sun
- pthread_attr_getstack (&attr, (void**)staddr, stsize);
- if (*staddr)
- g_assert ((current > *staddr) && (current < *staddr + *stsize));
+ pthread_attr_getstack (&attr, (void**)staddr, stsize);
+ if (*staddr)
+ g_assert ((current > *staddr) && (current < *staddr + *stsize));
#endif
- pthread_attr_destroy (&attr);
+ pthread_attr_destroy (&attr);
#endif
- /* When running under emacs, sometimes staddr is not aligned to a page size */
- *staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
+ /* When running under emacs, sometimes staddr is not aligned to a page size */
+ *staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
}
MonoThread *
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
}
-void ves_icall_System_Threading_Thread_SpinWait_internal (gint32 iterations)
+void ves_icall_System_Threading_Thread_SpinWait_nop (void)
{
- gint32 i;
-
- for(i = 0; i < iterations; i++) {
- /* We're busy waiting, but at least we can tell the
- * scheduler to let someone else have a go...
- */
- Sleep (0);
- }
}
gint32
gboolean throw = FALSE;
ensure_synch_cs_set (this);
+
+ if (this == mono_thread_current ())
+ return;
EnterCriticalSection (this->synch_cs);
MonoThread *thread = mono_thread_current ();
gboolean throw = FALSE;
+ mono_debugger_check_interruption ();
+
ensure_synch_cs_set (thread);
EnterCriticalSection (thread->synch_cs);
LeaveCriticalSection (thread->synch_cs);
THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Abort requested for %p (%"G_GSIZE_FORMAT")", __func__, GetCurrentThreadId (), thread, (gsize)thread->tid));
-
- /* Make sure the thread is awake */
- mono_thread_resume (thread);
+
+ /* During shutdown, we can't wait for other threads */
+ if (!shutting_down)
+ /* Make sure the thread is awake */
+ mono_thread_resume (thread);
signal_thread_state_change (thread);
}
{
abort_appdomain_data user_data;
guint32 start_time;
+ int orig_timeout = timeout;
THREAD_DEBUG (g_message ("%s: starting abort", __func__));
timeout -= mono_msec_ticks () - start_time;
start_time = mono_msec_ticks ();
- if (timeout < 0)
+ if (orig_timeout != -1 && timeout < 0)
return FALSE;
}
while (user_data.wait.num > 0);
return NULL;
} else if (thread->thread_interrupt_requested) {
+ thread->thread_interrupt_requested = FALSE;
LeaveCriticalSection (thread->synch_cs);
return(mono_get_exception_thread_interrupted ());
* the thread. If the result is an exception that needs to be throw, it is
* provided as return value.
*/
-MonoException* mono_thread_request_interruption (gboolean running_managed)
+MonoException*
+mono_thread_request_interruption (gboolean running_managed)
{
MonoThread *thread = mono_thread_current ();
if (thread == NULL)
return NULL;
- ensure_synch_cs_set (thread);
-
- /* FIXME: This is NOT signal safe */
- EnterCriticalSection (thread->synch_cs);
-
- if (thread->interruption_requested) {
- LeaveCriticalSection (thread->synch_cs);
-
+ if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 1)
return NULL;
- }
if (!running_managed || is_running_protected_wrapper ()) {
/* Can't stop while in unmanaged code. Increase the global interruption
checked and the thread will be interrupted. */
InterlockedIncrement (&thread_interruption_requested);
- thread->interruption_requested = TRUE;
-
- LeaveCriticalSection (thread->synch_cs);
if (mono_thread_notify_pending_exc_fn && !running_managed)
/* The JIT will notify the thread about the interruption */
return NULL;
}
else {
- LeaveCriticalSection (thread->synch_cs);
-
return mono_thread_execute_interruption (thread);
}
}
if (thread == NULL)
return;
+ mono_debugger_check_interruption ();
+
if (thread->interruption_requested && (bypass_abort_protection || !is_running_protected_wrapper ())) {
MonoException* exc = mono_thread_execute_interruption (thread);
if (exc) mono_raise_exception (exc);