MonoThreadInfo*
mono_thread_info_lookup (MonoNativeThreadId id)
{
- MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
+ MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
if (!mono_lls_find (&thread_list, hp, (uintptr_t)id)) {
mono_hazard_pointer_clear_all (hp, -1);
mono_thread_info_core_resume (MonoThreadInfo *info)
{
gboolean res = FALSE;
- if (info->create_suspended) {
- MonoNativeThreadId tid = mono_thread_info_get_tid (info);
- /* Have to special case this, as the normal suspend/resume pair are racy, they don't work if he resume is received before the suspend */
- info->create_suspended = FALSE;
- mono_threads_platform_resume_created (info, tid);
- return TRUE;
- }
switch (mono_threads_transition_request_resume (info)) {
case ResumeError:
return FALSE;
}
+typedef struct {
+ gint32 ref;
+ MonoThreadStart start_routine;
+ gpointer start_routine_arg;
+ gint32 priority;
+ MonoCoopSem registered;
+ gpointer handle;
+} CreateThreadData;
+
+static gsize WINAPI
+inner_start_thread (gpointer data)
+{
+ CreateThreadData *thread_data;
+ MonoThreadInfo *info;
+ MonoThreadStart start_routine;
+ gpointer start_routine_arg;
+ guint32 start_routine_res;
+ gsize dummy;
+
+ thread_data = (CreateThreadData*) data;
+ g_assert (thread_data);
+
+ start_routine = thread_data->start_routine;
+ start_routine_arg = thread_data->start_routine_arg;
+
+ info = mono_thread_info_attach (&dummy);
+ info->runtime_thread = TRUE;
+
+ thread_data->handle = mono_thread_info_duplicate_handle (info);
+
+ mono_coop_sem_post (&thread_data->registered);
+
+ if (InterlockedDecrement (&thread_data->ref) == 0) {
+ mono_coop_sem_destroy (&thread_data->registered);
+ g_free (thread_data);
+ }
+
+ /* thread_data is not valid anymore */
+ thread_data = NULL;
+
+ /* Run the actual main function of the thread */
+ start_routine_res = start_routine (start_routine_arg);
+
+ mono_threads_platform_exit (start_routine_res);
+
+ g_assert_not_reached ();
+}
+
/*
* mono_threads_create_thread:
*
* Returns: a windows or io-layer handle for the thread.
*/
HANDLE
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
-{
- return mono_threads_platform_create_thread (start, arg, tp, out_tid);
+mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize stack_size, MonoNativeThreadId *out_tid)
+{
+ CreateThreadData *thread_data;
+ gint res;
+ gpointer ret;
+
+ thread_data = g_new0 (CreateThreadData, 1);
+ thread_data->ref = 2;
+ thread_data->start_routine = start;
+ thread_data->start_routine_arg = arg;
+ mono_coop_sem_init (&thread_data->registered, 0);
+
+ res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) thread_data, stack_size, out_tid);
+ if (res != 0) {
+ /* ref is not going to be decremented in inner_start_thread */
+ InterlockedDecrement (&thread_data->ref);
+ ret = NULL;
+ goto done;
+ }
+
+ res = mono_coop_sem_wait (&thread_data->registered, MONO_SEM_FLAGS_NONE);
+ g_assert (res == 0);
+
+ ret = thread_data->handle;
+ g_assert (ret);
+
+done:
+ if (InterlockedDecrement (&thread_data->ref) == 0) {
+ mono_coop_sem_destroy (&thread_data->registered);
+ g_free (thread_data);
+ }
+
+ return ret;
}
/*
*alerted = FALSE;
if (ms != INFINITE)
- end = mono_100ns_ticks () + (ms * 1000 * 10);
+ end = mono_msec_ticks() + ms;
mono_lazy_initialize (&sleep_init, sleep_initialize);
for (;;) {
if (ms != INFINITE) {
- now = mono_100ns_ticks ();
- if (now > end)
+ now = mono_msec_ticks();
+ if (now >= end)
break;
}
}
if (ms != INFINITE)
- mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, (end - now) / 10 / 1000);
+ mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, end - now);
else
mono_coop_cond_wait (&sleep_cond, &sleep_mutex);
return mono_threads_platform_open_thread_handle (handle, tid);
}
+void
+mono_threads_close_thread_handle (HANDLE handle)
+{
+ return mono_threads_platform_close_thread_handle (handle);
+}
+
#define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
struct _MonoThreadInfoInterruptToken {
}
gpointer
-mono_thread_info_get_handle (THREAD_INFO_TYPE *info)
-{
- g_assert (info->handle);
- return info->handle;
-}
-
-void
-mono_thread_info_describe (MonoThreadInfo *info, GString *text)
+mono_thread_info_duplicate_handle (MonoThreadInfo *info)
{
- mono_threads_platform_describe (info, text);
+ g_assert (mono_thread_info_is_current (info));
+ return mono_threads_platform_duplicate_handle (info);
}
void
{
mono_threads_platform_disown_mutex (info, mutex_handle);
}
-
-MonoThreadPriority
-mono_thread_info_get_priority (MonoThreadInfo *info)
-{
- return mono_threads_platform_get_priority (info);
-}
-
-gboolean
-mono_thread_info_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
-{
- return mono_threads_platform_set_priority (info, priority);
-}