tid=thread->tid;
SET_CURRENT_OBJECT (thread);
+
+ /* Every thread references the appdomain which created it */
+ mono_thread_push_appdomain_ref (start_info->domain);
if (!mono_domain_set (start_info->domain, FALSE)) {
/* No point in raising an appdomain_unloaded exception here */
/* FIXME: Cleanup here */
+ mono_thread_pop_appdomain_ref ();
return 0;
}
g_free (start_info);
- /* Every thread references the appdomain which created it */
- mono_thread_push_appdomain_ref (mono_domain_get ());
-
thread_adjust_static_data (thread);
#ifdef DEBUG
g_message ("%s: start_wrapper for %"G_GSIZE_FORMAT, __func__,
ResumeThread (thread_handle);
}
+/*
+ * mono_thread_get_stack_bounds:
+ *
+ * Return the address and size of the current threads stack. Return NULL as the stack
+ * address if the stack address cannot be determined.
+ */
+static void
+mono_thread_get_stack_bounds (guint8 **staddr, size_t *stsize)
+{
+#ifndef PLATFORM_WIN32
+ pthread_attr_t attr;
+ guint8 *current = (guint8*)&attr;
+
+ pthread_attr_init (&attr);
+#ifdef HAVE_PTHREAD_GETATTR_NP
+ pthread_getattr_np (pthread_self(), &attr);
+#else
+#ifdef HAVE_PTHREAD_ATTR_GET_NP
+ pthread_attr_get_np (pthread_self(), &attr);
+#elif defined(sun)
+ *staddr = NULL;
+ pthread_attr_getstacksize (&attr, &stsize);
+#else
+ *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));
+#endif
+#endif
+}
+
MonoThread *
mono_thread_attach (MonoDomain *domain)
{
thread_adjust_static_data (thread);
if (mono_thread_attach_cb) {
- mono_thread_attach_cb (tid, &tid);
+ guint8 *staddr;
+ size_t stsize;
+
+ mono_thread_get_stack_bounds (&staddr, &stsize);
+
+ if (staddr == NULL)
+ mono_thread_attach_cb (tid, &tid);
+ else
+ mono_thread_attach_cb (tid, staddr + stsize);
}
return(thread);
MonoThread *thread=(MonoThread *)value;
/* Ignore background threads, we abort them later */
- mono_monitor_enter (thread->synch_lock);
+ /* Do not lock here since it is not needed and the caller holds threads_lock */
if (thread->state & ThreadState_Background) {
THREAD_DEBUG (g_message ("%s: ignoring background thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
- mono_monitor_exit (thread->synch_lock);
return; /* just leave, ignore */
}
- mono_monitor_exit (thread->synch_lock);
if (mono_gc_is_finalizer_thread (thread)) {
THREAD_DEBUG (g_message ("%s: ignoring finalizer thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
MonoDomain *domain = data->domain;
if (mono_thread_has_appdomain_ref (thread, domain)) {
- HANDLE handle = OpenThread (THREAD_ALL_ACCESS, TRUE, thread->tid);
- if (handle == NULL)
- return;
-
/* printf ("ABORTING THREAD %p BECAUSE IT REFERENCES DOMAIN %s.\n", thread->tid, domain->friendly_name); */
ves_icall_System_Threading_Thread_Abort (thread, NULL);
if(data->wait.num<MAXIMUM_WAIT_OBJECTS) {
+ HANDLE handle = OpenThread (THREAD_ALL_ACCESS, TRUE, thread->tid);
+ if (handle == NULL)
+ return;
data->wait.handles [data->wait.num] = handle;
data->wait.threads [data->wait.num] = thread;
data->wait.num++;