This guarantee that a MonoThreadInfo always has a handle.
}
}
+void
+mono_threads_platform_register (MonoThreadInfo *info)
+{
+ g_assert (!info->handle);
+ info->handle = thread_handle_create ();
+}
+
typedef struct {
void *(*start_routine)(void*);
void *arg;
void *(*start_func)(void*) = start_info->start_routine;
guint32 flags = start_info->flags;
void *result;
- HANDLE handle;
MonoThreadInfo *info;
- /* Register the thread with the io-layer */
- handle = thread_handle_create ();
- if (!handle) {
- mono_coop_sem_post (&(start_info->registered));
- return NULL;
- }
- start_info->handle = handle;
-
info = mono_thread_info_attach (&result);
-
info->runtime_thread = TRUE;
- info->handle = handle;
+
+ start_info->handle = info->handle;
mono_threads_platform_set_priority (info, start_info->priority);
void
mono_threads_platform_exit (int exit_code)
{
- MonoThreadInfo *current = mono_thread_info_current ();
-
#if defined(__native_client__)
nacl_shutdown_gc_thread();
#endif
- mono_threads_platform_set_exited (current);
-
mono_thread_info_detach ();
pthread_exit (NULL);
void
mono_threads_platform_unregister (MonoThreadInfo *info)
{
- if (info->handle) {
- mono_threads_platform_set_exited (info);
- info->handle = NULL;
- }
+ mono_threads_platform_set_exited (info);
}
HANDLE
info = mono_thread_info_current ();
g_assert (info);
+ g_assert (info->handle);
+
+ mono_w32handle_ref (info->handle);
- if (!info->handle)
- info->handle = thread_handle_create ();
- else
- mono_w32handle_ref (info->handle);
return info->handle;
}
pid_t pid;
pthread_t tid;
- if (!info->handle || mono_w32handle_issignalled (info->handle) || mono_w32handle_get_type (info->handle) == MONO_W32HANDLE_UNUSED) {
+ g_assert (info->handle);
+
+ if (mono_w32handle_issignalled (info->handle) || mono_w32handle_get_type (info->handle) == MONO_W32HANDLE_UNUSED) {
/* We must have already deliberately finished
* with this thread, so don't do any more now */
return;
#if defined (PLATFORM_ANDROID)
info->native_handle = gettid ();
#endif
-
- g_assert (!info->handle);
- info->handle = thread_handle_create ();
}
void
void
mono_threads_suspend_register (MonoThreadInfo *info)
{
- g_assert (!info->handle);
- info->handle = mono_threads_platform_open_handle();
}
void
#if defined (HOST_WIN32)
+void
+mono_threads_platform_register (MonoThreadInfo *info)
+{
+ HANDLE thread_handle;
+
+ thread_handle = GetCurrentThread ();
+ g_assert (thread_handle);
+
+ /* The handle returned by GetCurrentThread () is a pseudo handle, so it can't
+ * be used to refer to the thread from other threads for things like aborting. */
+ DuplicateHandle (GetCurrentProcess (), thread_handle, GetCurrentProcess (), &thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
+
+ g_assert (!info->handle);
+ info->handle = thread_handle;
+}
+
typedef struct {
LPTHREAD_START_ROUTINE start_routine;
void *arg;
MonoCoopSem registered;
gboolean suspend;
HANDLE suspend_event;
+ HANDLE handle;
} ThreadStartInfo;
static DWORD WINAPI
{
ThreadStartInfo *start_info = arg;
void *t_arg = start_info->arg;
- int post_result;
LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
DWORD result;
gboolean suspend = start_info->suspend;
info->runtime_thread = TRUE;
info->create_suspended = suspend;
+ start_info->handle = info->handle;
+
mono_threads_platform_set_priority(info, start_info->priority);
mono_coop_sem_post (&(start_info->registered));
res = mono_coop_sem_wait (&(start_info->registered), MONO_SEM_FLAGS_NONE);
g_assert (res != -1);
+ /* A new handle has been opened when attaching
+ * the thread, so we don't need this one */
+ CloseHandle (result);
+
if (start_info->suspend) {
g_assert (SuspendThread (result) != (DWORD)-1);
SetEvent (start_info->suspend_event);
info->stackdata = g_byte_array_new ();
+ mono_threads_platform_register (info);
mono_threads_suspend_register (info);
/*
void mono_threads_suspend_abort_syscall (THREAD_INFO_TYPE *info);
gboolean mono_threads_suspend_needs_abort_syscall (void);
+void mono_threads_platform_register (THREAD_INFO_TYPE *info);
+void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
HANDLE mono_threads_platform_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *, MonoNativeThreadId *out_tid);
void mono_threads_platform_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid);
void mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize);
gboolean mono_threads_platform_yield (void);
void mono_threads_platform_exit (int exit_code);
-void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
HANDLE mono_threads_platform_open_handle (void);
HANDLE mono_threads_platform_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
void mono_threads_platform_set_exited (THREAD_INFO_TYPE *info);