Author: dick
Date: 2007-10-15 10:49:11 -0400 (Mon, 15 Oct 2007)
New Revision: 87516
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/icall-def.h
trunk/mono/mono/metadata/monitor.c
trunk/mono/mono/metadata/object-internals.h
trunk/mono/mono/metadata/socket-io.c
trunk/mono/mono/metadata/threads-types.h
trunk/mono/mono/metadata/threads.c
trunk/mono/mono/metadata/threads.h
Log:
2007-10-15 Dick Porter <[EMAIL PROTECTED]>
* monitor.c (mono_monitor_try_enter_internal): Set thread state to
WaitSleepJoin while it is waiting to acquire a lock. Fixes bug
81646.
* threads.c: Turn the thread synch_lock into a CRITICAL_SECTION,
instead of a monitor lock. This means that monitor_try_enter and
co can set the thread state safely.
(ves_icall_System_Threading_Thread_Interrupt_internal): Always set
thread_interrupt_requested, so interrupt actually works.
* socket-io.c (ves_icall_System_Net_Sockets_Socket_Poll_internal,
ves_icall_System_Net_Sockets_Socket_Select_internal): Use thread
state accessor function
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/ChangeLog 2007-10-15 14:49:11 UTC (rev 87516)
@@ -1,3 +1,19 @@
+2007-10-15 Dick Porter <[EMAIL PROTECTED]>
+
+ * monitor.c (mono_monitor_try_enter_internal): Set thread state to
+ WaitSleepJoin while it is waiting to acquire a lock. Fixes bug
+ 81646.
+
+ * threads.c: Turn the thread synch_lock into a CRITICAL_SECTION,
+ instead of a monitor lock. This means that monitor_try_enter and
+ co can set the thread state safely.
+ (ves_icall_System_Threading_Thread_Interrupt_internal): Always set
+ thread_interrupt_requested, so interrupt actually works.
+
+ * socket-io.c (ves_icall_System_Net_Sockets_Socket_Poll_internal,
+ ves_icall_System_Net_Sockets_Socket_Select_internal): Use thread
+ state accessor function
+
2007-10-15 Martin Baulig <[EMAIL PROTECTED]>
* mono-debug.h
Modified: trunk/mono/mono/metadata/icall-def.h
===================================================================
--- trunk/mono/mono/metadata/icall-def.h 2007-10-15 14:49:07 UTC (rev
87515)
+++ trunk/mono/mono/metadata/icall-def.h 2007-10-15 14:49:11 UTC (rev
87516)
@@ -786,6 +786,7 @@
ICALL(THREAD_54, "SpinWait_internal",
ves_icall_System_Threading_Thread_SpinWait_internal)
ICALL(THREAD_23, "Suspend_internal", ves_icall_System_Threading_Thread_Suspend)
ICALL(THREAD_24, "Thread_free_internal",
ves_icall_System_Threading_Thread_Thread_free_internal)
+ICALL(THREAD_24a, "Thread_init", ves_icall_System_Threading_Thread_Thread_init)
ICALL(THREAD_25, "Thread_internal",
ves_icall_System_Threading_Thread_Thread_internal)
ICALL(THREAD_26, "VolatileRead(byte&)",
ves_icall_System_Threading_Thread_VolatileRead1)
ICALL(THREAD_27, "VolatileRead(double&)",
ves_icall_System_Threading_Thread_VolatileRead8)
Modified: trunk/mono/mono/metadata/monitor.c
===================================================================
--- trunk/mono/mono/metadata/monitor.c 2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/monitor.c 2007-10-15 14:49:11 UTC (rev 87516)
@@ -332,6 +332,7 @@
guint32 then = 0, now, delta;
guint32 waitms;
guint32 ret;
+ MonoThread *thread = mono_thread_current ();
LOCK_DEBUG (g_message(G_GNUC_PRETTY_FUNCTION
": (%d) Trying to lock object %p (%d ms)", id, obj, ms));
@@ -467,7 +468,7 @@
CloseHandle (sem);
}
}
-
+
/* If we need to time out, record a timestamp and adjust ms,
* because WaitForSingleObject doesn't tell us how long it
* waited for.
@@ -490,7 +491,13 @@
}
InterlockedIncrement (&mon->entry_count);
+
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+
ret = WaitForSingleObjectEx (mon->entry_sem, waitms,
allow_interruption);
+
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+
InterlockedDecrement (&mon->entry_count);
if (ms != INFINITE) {
@@ -826,9 +833,9 @@
LOCK_DEBUG (g_message (G_GNUC_PRETTY_FUNCTION ": (%d) queuing handle
%p",
GetCurrentThreadId (), event));
- mono_monitor_enter (thread->synch_lock);
- thread->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_current_check_pending_interrupt ();
+
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
mon->wait_list = g_slist_append (mon->wait_list, event);
@@ -850,9 +857,7 @@
/* Reset the thread state fairly early, so we don't have to worry
* about the monitor error checking
*/
- mono_monitor_enter (thread->synch_lock);
- thread->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
if (mono_thread_interruption_requested ()) {
CloseHandle (event);
Modified: trunk/mono/mono/metadata/object-internals.h
===================================================================
--- trunk/mono/mono/metadata/object-internals.h 2007-10-15 14:49:07 UTC (rev
87515)
+++ trunk/mono/mono/metadata/object-internals.h 2007-10-15 14:49:11 UTC (rev
87516)
@@ -262,7 +262,7 @@
gpointer suspend_event;
gpointer suspended_event;
gpointer resume_event;
- MonoObject *synch_lock;
+ CRITICAL_SECTION *synch_cs;
guint8* serialized_culture_info;
guint32 serialized_culture_info_len;
guint8* serialized_ui_culture_info;
Modified: trunk/mono/mono/metadata/socket-io.c
===================================================================
--- trunk/mono/mono/metadata/socket-io.c 2007-10-15 14:49:07 UTC (rev
87515)
+++ trunk/mono/mono/metadata/socket-io.c 2007-10-15 14:49:11 UTC (rev
87516)
@@ -1156,10 +1156,7 @@
thread = mono_thread_current ();
}
- mono_monitor_enter (thread->synch_lock);
- leave = ((thread->state & ThreadState_AbortRequested)
!= 0 ||
- (thread->state & ThreadState_StopRequested) !=
0);
- mono_monitor_exit (thread->synch_lock);
+ leave = mono_thread_test_state (thread,
ThreadState_AbortRequested | ThreadState_StopRequested);
if (leave != 0) {
g_free (pfds);
@@ -1550,10 +1547,8 @@
if (thread == NULL)
thread = mono_thread_current ();
- mono_monitor_enter (thread->synch_lock);
- leave = ((thread->state & ThreadState_AbortRequested)
!= 0 ||
- (thread->state & ThreadState_StopRequested) !=
0);
- mono_monitor_exit (thread->synch_lock);
+ leave = mono_thread_test_state (thread,
ThreadState_AbortRequested | ThreadState_StopRequested);
+
if (leave != 0) {
g_free (pfds);
*sockets = NULL;
Modified: trunk/mono/mono/metadata/threads-types.h
===================================================================
--- trunk/mono/mono/metadata/threads-types.h 2007-10-15 14:49:07 UTC (rev
87515)
+++ trunk/mono/mono/metadata/threads-types.h 2007-10-15 14:49:11 UTC (rev
87516)
@@ -43,6 +43,7 @@
#define SPECIAL_STATIC_CONTEXT 2
extern HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread
*this_obj, MonoObject *start) MONO_INTERNAL;
+extern void ves_icall_System_Threading_Thread_Thread_init(MonoThread
*this_obj) MONO_INTERNAL;
extern void ves_icall_System_Threading_Thread_Thread_free_internal(MonoThread
*this_obj, HANDLE thread) MONO_INTERNAL;
extern void ves_icall_System_Threading_Thread_Sleep_internal(int ms)
MONO_INTERNAL;
extern gboolean ves_icall_System_Threading_Thread_Join_internal(MonoThread
*this_obj, int ms, HANDLE thread) MONO_INTERNAL;
Modified: trunk/mono/mono/metadata/threads.c
===================================================================
--- trunk/mono/mono/metadata/threads.c 2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/threads.c 2007-10-15 14:49:11 UTC (rev 87516)
@@ -447,13 +447,13 @@
return;
mono_release_type_locks (thread);
- if (!mono_monitor_enter (thread->synch_lock))
- return;
+ EnterCriticalSection (thread->synch_cs);
thread->state |= ThreadState_Stopped;
thread->state &= ~ThreadState_Background;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
mono_profiler_thread_end (thread->tid);
if (thread == mono_thread_current ())
@@ -635,7 +635,8 @@
thread->apartment_state=ThreadApartmentState_Unknown;
small_id_alloc (thread);
- MONO_OBJECT_SETREF (thread, synch_lock, mono_object_new (domain,
mono_defaults.object_class));
+ thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+ InitializeCriticalSection (thread->synch_cs);
handle_store(thread);
@@ -724,8 +725,10 @@
thread->apartment_state=ThreadApartmentState_Unknown;
small_id_alloc (thread);
thread->stack_ptr = &tid;
- MONO_OBJECT_SETREF (thread, synch_lock, mono_object_new (domain,
mono_defaults.object_class));
+ thread->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+ InitializeCriticalSection (thread->synch_cs);
+
THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT"
(handle %p)", __func__, tid, thread_handle));
handle_store(thread);
@@ -792,15 +795,26 @@
struct StartInfo *start_info;
HANDLE thread;
gsize tid;
+ CRITICAL_SECTION *synch_cs;
MONO_ARCH_SAVE_REGS;
THREAD_DEBUG (g_message("%s: Trying to start a new thread: this (%p)
start (%p)", __func__, this, start));
- mono_monitor_enter (this->synch_lock);
+ synch_cs = g_new0 (CRITICAL_SECTION, 1);
+ InitializeCriticalSection (synch_cs);
+ if (InterlockedCompareExchangePointer ((gpointer *)&this->synch_cs,
+ synch_cs, NULL) != NULL) {
+ /* This thread must have already been started! */
+ DeleteCriticalSection (synch_cs);
+ g_free (synch_cs);
+ }
+
+ EnterCriticalSection (this->synch_cs);
+
if ((this->state & ThreadState_Unstarted) == 0) {
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
mono_raise_exception (mono_get_exception_thread_state ("Thread
has already been started."));
return NULL;
}
@@ -808,7 +822,7 @@
this->small_id = -1;
if ((this->state & ThreadState_Aborted) != 0) {
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
return this;
}
start_func = NULL;
@@ -823,7 +837,7 @@
this->start_notify=CreateSemaphore (NULL, 0, 0x7fffffff, NULL);
if(this->start_notify==NULL) {
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
g_warning ("%s: CreateSemaphore error 0x%x", __func__,
GetLastError ());
return(NULL);
}
@@ -831,7 +845,7 @@
thread=CreateThread(NULL, default_stacksize_for_thread (this),
(LPTHREAD_START_ROUTINE)start_wrapper, start_info,
CREATE_SUSPENDED, &tid);
if(thread==NULL) {
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
g_warning("%s: CreateThread error 0x%x", __func__,
GetLastError());
return(NULL);
}
@@ -852,11 +866,19 @@
THREAD_DEBUG (g_message ("%s: Started thread ID
%"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread));
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
return(thread);
}
}
+void ves_icall_System_Threading_Thread_Thread_init (MonoThread *this)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ this->synch_cs = g_new0 (CRITICAL_SECTION, 1);
+ InitializeCriticalSection (this->synch_cs);
+}
+
void ves_icall_System_Threading_Thread_Thread_free_internal (MonoThread *this,
HANDLE thread)
{
@@ -865,6 +887,9 @@
THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__,
this, thread));
CloseHandle (thread);
+
+ DeleteCriticalSection (this->synch_cs);
+ g_free (this->synch_cs);
}
static void mono_thread_start (MonoThread *thread)
@@ -908,15 +933,11 @@
mono_thread_current_check_pending_interrupt ();
- mono_monitor_enter (thread->synch_lock);
- thread->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
SleepEx(ms,TRUE);
- mono_monitor_enter (thread->synch_lock);
- thread->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
}
void ves_icall_System_Threading_Thread_SpinWait_internal (gint32 iterations)
@@ -943,24 +964,27 @@
ves_icall_System_Threading_Thread_GetName_internal (MonoThread *this_obj)
{
MonoString* str;
- mono_monitor_enter (this_obj->synch_lock);
+
+ EnterCriticalSection (this_obj->synch_cs);
if (!this_obj->name)
str = NULL;
else
str = mono_string_new_utf16 (mono_domain_get (),
this_obj->name, this_obj->name_len);
- mono_monitor_exit (this_obj->synch_lock);
+ LeaveCriticalSection (this_obj->synch_cs);
+
return str;
}
void
ves_icall_System_Threading_Thread_SetName_internal (MonoThread *this_obj,
MonoString *name)
{
- mono_monitor_enter (this_obj->synch_lock);
+ EnterCriticalSection (this_obj->synch_cs);
if (this_obj->name) {
- mono_monitor_exit (this_obj->synch_lock);
+ LeaveCriticalSection (this_obj->synch_cs);
+
mono_raise_exception (mono_get_exception_invalid_operation
("Thread.Name can only be set once."));
return;
}
@@ -972,7 +996,7 @@
else
this_obj->name = NULL;
- mono_monitor_exit (this_obj->synch_lock);
+ LeaveCriticalSection (this_obj->synch_cs);
}
static MonoObject*
@@ -1004,15 +1028,17 @@
{
MonoArray *res;
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
+
if (this->serialized_culture_info) {
res = mono_array_new (mono_domain_get (),
mono_defaults.byte_class, this->serialized_culture_info_len);
memcpy (mono_array_addr (res, guint8, 0),
this->serialized_culture_info, this->serialized_culture_info_len);
} else {
res = NULL;
}
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
+
return res;
}
@@ -1025,7 +1051,8 @@
int free_slot = -1;
int same_domain_slot = -1;
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
+
if (!this->cached_culture_info)
this->cached_culture_info = mono_array_new (mono_object_domain
(this), mono_defaults.object_class, NUM_CACHED_CULTURES * 2);
@@ -1048,7 +1075,8 @@
else if (free_slot >= 0)
mono_array_setref (this->cached_culture_info, free_slot,
culture);
/* we may want to replace an existing entry here, even when no suitable
slot is found */
- mono_monitor_exit (this->synch_lock);
+
+ LeaveCriticalSection (this->synch_cs);
}
void
@@ -1060,13 +1088,15 @@
void
ves_icall_System_Threading_Thread_SetSerializedCurrentCulture (MonoThread
*this, MonoArray *arr)
{
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
+
if (this->serialized_culture_info)
g_free (this->serialized_culture_info);
this->serialized_culture_info = g_new0 (guint8, mono_array_length
(arr));
this->serialized_culture_info_len = mono_array_length (arr);
memcpy (this->serialized_culture_info, mono_array_addr (arr, guint8,
0), mono_array_length (arr));
- mono_monitor_exit (this->synch_lock);
+
+ LeaveCriticalSection (this->synch_cs);
}
@@ -1081,15 +1111,17 @@
{
MonoArray *res;
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
+
if (this->serialized_ui_culture_info) {
res = mono_array_new (mono_domain_get (),
mono_defaults.byte_class, this->serialized_ui_culture_info_len);
memcpy (mono_array_addr (res, guint8, 0),
this->serialized_ui_culture_info, this->serialized_ui_culture_info_len);
} else {
res = NULL;
}
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
+
return res;
}
@@ -1102,13 +1134,15 @@
void
ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture (MonoThread
*this, MonoArray *arr)
{
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
+
if (this->serialized_ui_culture_info)
g_free (this->serialized_ui_culture_info);
this->serialized_ui_culture_info = g_new0 (guint8, mono_array_length
(arr));
this->serialized_ui_culture_info_len = mono_array_length (arr);
memcpy (this->serialized_ui_culture_info, mono_array_addr (arr, guint8,
0), mono_array_length (arr));
- mono_monitor_exit (this->synch_lock);
+
+ LeaveCriticalSection (this->synch_cs);
}
/* the jit may read the compiled code of this function */
@@ -1125,20 +1159,22 @@
gboolean ret;
MONO_ARCH_SAVE_REGS;
+
+ mono_thread_current_check_pending_interrupt ();
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
if ((this->state & ThreadState_Unstarted) != 0) {
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
+
mono_raise_exception (mono_get_exception_thread_state ("Thread
has not been started."));
return FALSE;
}
- mono_thread_current_check_pending_interrupt ();
-
this->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (this->synch_lock);
+ LeaveCriticalSection (this->synch_cs);
+
if(ms== -1) {
ms=INFINITE;
}
@@ -1146,9 +1182,7 @@
ret=WaitForSingleObjectEx (thread, ms, TRUE);
- mono_monitor_enter (this->synch_lock);
- this->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (this->synch_lock);
+ mono_thread_clr_state (this, ThreadState_WaitSleepJoin);
if(ret==WAIT_OBJECT_0) {
THREAD_DEBUG (g_message ("%s: join successful", __func__));
@@ -1188,15 +1222,11 @@
ms=INFINITE;
}
- mono_monitor_enter (thread->synch_lock);
- thread->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
ret=WaitForMultipleObjectsEx(numhandles, handles, TRUE, ms, TRUE);
- mono_monitor_enter (thread->synch_lock);
- thread->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
g_free(handles);
@@ -1243,16 +1273,12 @@
ms=INFINITE;
}
- mono_monitor_enter (thread->synch_lock);
- thread->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
-
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+
ret=WaitForMultipleObjectsEx(numhandles, handles, FALSE, ms, TRUE);
- mono_monitor_enter (thread->synch_lock);
- thread->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
-
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+
g_free(handles);
THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") returning %d",
__func__, GetCurrentThreadId (), ret));
@@ -1287,16 +1313,12 @@
mono_thread_current_check_pending_interrupt ();
- mono_monitor_enter (thread->synch_lock);
- thread->state |= ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
-
+ mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
+
ret=WaitForSingleObjectEx (handle, ms, TRUE);
- mono_monitor_enter (thread->synch_lock);
- thread->state &= ~ThreadState_WaitSleepJoin;
- mono_monitor_exit (thread->synch_lock);
-
+ mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+
if(ret==WAIT_FAILED) {
THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait
failed", __func__, GetCurrentThreadId ()));
return(FALSE);
@@ -1735,8 +1757,8 @@
void
ves_icall_System_Threading_Thread_ClrState (MonoThread* this, guint32 state)
{
- mono_monitor_enter (this->synch_lock);
- this->state &= ~state;
+ mono_thread_clr_state (this, state);
+
if (state & ThreadState_Background) {
/* If the thread changes the background mode, the main thread
has to
* be notified, since it has to rebuild the list of threads to
@@ -1744,14 +1766,13 @@
*/
SetEvent (background_change_event);
}
- mono_monitor_exit (this->synch_lock);
}
void
ves_icall_System_Threading_Thread_SetState (MonoThread* this, guint32 state)
{
- mono_monitor_enter (this->synch_lock);
- this->state |= state;
+ mono_thread_set_state (this, state);
+
if (state & ThreadState_Background) {
/* If the thread changes the background mode, the main thread
has to
* be notified, since it has to rebuild the list of threads to
@@ -1759,16 +1780,19 @@
*/
SetEvent (background_change_event);
}
- mono_monitor_exit (this->synch_lock);
}
guint32
ves_icall_System_Threading_Thread_GetState (MonoThread* this)
{
guint32 state;
- mono_monitor_enter (this->synch_lock);
+
+ EnterCriticalSection (this->synch_cs);
+
state = this->state;
- mono_monitor_exit (this->synch_lock);
+
+ LeaveCriticalSection (this->synch_cs);
+
return state;
}
@@ -1776,19 +1800,16 @@
{
gboolean throw = FALSE;
- mono_monitor_enter (this->synch_lock);
+ EnterCriticalSection (this->synch_cs);
- /* Clear out any previous request */
- this->thread_interrupt_requested = FALSE;
+ this->thread_interrupt_requested = TRUE;
if (this->state & ThreadState_WaitSleepJoin) {
throw = TRUE;
- } else {
- this->thread_interrupt_requested = TRUE;
}
- mono_monitor_exit (this->synch_lock);
-
+ LeaveCriticalSection (this->synch_cs);
+
if (throw) {
signal_thread_state_change (this);
}
@@ -1799,14 +1820,14 @@
MonoThread *thread = mono_thread_current ();
gboolean throw = FALSE;
- mono_monitor_enter (thread->synch_lock);
-
+ EnterCriticalSection (thread->synch_cs);
+
if (thread->thread_interrupt_requested) {
throw = TRUE;
thread->thread_interrupt_requested = FALSE;
}
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
if (throw) {
mono_raise_exception (mono_get_exception_thread_interrupted ());
@@ -1881,19 +1902,19 @@
{
MONO_ARCH_SAVE_REGS;
- mono_monitor_enter (thread->synch_lock);
-
+ EnterCriticalSection (thread->synch_cs);
+
if ((thread->state & ThreadState_AbortRequested) != 0 ||
(thread->state & ThreadState_StopRequested) != 0 ||
(thread->state & ThreadState_Stopped) != 0)
{
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return;
}
if ((thread->state & ThreadState_Unstarted) != 0) {
thread->state |= ThreadState_Aborted;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return;
}
@@ -1901,7 +1922,7 @@
MONO_OBJECT_SETREF (thread, abort_state, state);
thread->abort_exc = NULL;
- mono_monitor_exit (thread->synch_lock);
+ 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));
@@ -1918,20 +1939,20 @@
MONO_ARCH_SAVE_REGS;
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
thread->state &= ~ThreadState_AbortRequested;
if (!thread->abort_exc) {
const char *msg = "Unable to reset abort because no abort was
requested";
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
mono_raise_exception (mono_get_exception_thread_state (msg));
} else {
thread->abort_exc = NULL;
thread->abort_state = NULL;
}
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
}
static gboolean
@@ -1939,13 +1960,13 @@
{
MONO_ARCH_SAVE_REGS;
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if ((thread->state & ThreadState_Unstarted) != 0 ||
(thread->state & ThreadState_Aborted) != 0 ||
(thread->state & ThreadState_Stopped) != 0)
{
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return FALSE;
}
@@ -1953,13 +1974,14 @@
(thread->state & ThreadState_SuspendRequested) != 0 ||
(thread->state & ThreadState_StopRequested) != 0)
{
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return TRUE;
}
thread->state |= ThreadState_SuspendRequested;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
signal_thread_state_change (thread);
return TRUE;
}
@@ -1976,11 +1998,11 @@
{
MONO_ARCH_SAVE_REGS;
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if ((thread->state & ThreadState_SuspendRequested) != 0) {
thread->state &= ~ThreadState_SuspendRequested;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return TRUE;
}
@@ -1989,20 +2011,20 @@
(thread->state & ThreadState_Aborted) != 0 ||
(thread->state & ThreadState_Stopped) != 0)
{
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return FALSE;
}
thread->resume_event = CreateEvent (NULL, TRUE, FALSE, NULL);
if (thread->resume_event == NULL) {
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return(FALSE);
}
/* Awake the thread */
SetEvent (thread->suspend_event);
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
/* Wait for the thread to awake */
WaitForSingleObject (thread->resume_event, INFINITE);
@@ -2045,12 +2067,12 @@
void mono_thread_stop (MonoThread *thread)
{
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if ((thread->state & ThreadState_StopRequested) != 0 ||
(thread->state & ThreadState_Stopped) != 0)
{
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return;
}
@@ -2060,7 +2082,7 @@
thread->state |= ThreadState_StopRequested;
thread->state &= ~ThreadState_AbortRequested;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
signal_thread_state_change (thread);
}
@@ -2134,6 +2156,7 @@
InitializeCriticalSection(&contexts_mutex);
InitializeCriticalSection(&delayed_free_table_mutex);
InitializeCriticalSection(&small_id_mutex);
+
background_change_event = CreateEvent (NULL, TRUE, FALSE, NULL);
g_assert(background_change_event != NULL);
@@ -2528,13 +2551,13 @@
continue;
}
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if ((thread->state & ThreadState_Suspended) != 0 ||
(thread->state & ThreadState_SuspendRequested) != 0 ||
(thread->state & ThreadState_StopRequested) != 0 ||
(thread->state & ThreadState_Stopped) != 0) {
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
CloseHandle (wait->handles [i]);
wait->threads [i] = NULL; /* ignore this thread in next
loop */
continue;
@@ -2550,13 +2573,13 @@
thread->suspended_event = CreateEvent (NULL, TRUE,
FALSE, NULL);
if (thread->suspended_event == NULL) {
/* Forget this one and go on to the next */
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
continue;
}
}
events [eventidx++] = thread->suspended_event;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
/* Signal the thread to suspend */
signal_thread_state_change (thread);
@@ -2569,10 +2592,10 @@
if (thread == NULL)
continue;
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
CloseHandle (thread->suspended_event);
thread->suspended_event = NULL;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
}
g_free (events);
@@ -2739,7 +2762,7 @@
int i;
/* No locking needed here */
- /* FIXME: why no locking? writes to the cache are protected with
synch_lock above */
+ /* 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) {
@@ -3116,7 +3139,7 @@
*/
static MonoException* mono_thread_execute_interruption (MonoThread *thread)
{
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if (thread->interruption_requested) {
/* this will consume pending APC calls */
@@ -3128,7 +3151,7 @@
if ((thread->state & ThreadState_AbortRequested) != 0) {
if (thread->abort_exc == NULL)
MONO_OBJECT_SETREF (thread, abort_exc,
mono_get_exception_thread_abort ());
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return thread->abort_exc;
}
else if ((thread->state & ThreadState_SuspendRequested) != 0) {
@@ -3136,16 +3159,18 @@
thread->state |= ThreadState_Suspended;
thread->suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
if (thread->suspend_event == NULL) {
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
return(NULL);
}
if (thread->suspended_event)
SetEvent (thread->suspended_event);
- mono_monitor_exit (thread->synch_lock);
+
+ LeaveCriticalSection (thread->synch_cs);
WaitForSingleObject (thread->suspend_event, INFINITE);
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
+
CloseHandle (thread->suspend_event);
thread->suspend_event = NULL;
thread->state &= ~ThreadState_Suspended;
@@ -3154,20 +3179,27 @@
* and will be waiting for it
*/
SetEvent (thread->resume_event);
- mono_monitor_exit (thread->synch_lock);
+
+ LeaveCriticalSection (thread->synch_cs);
+
return NULL;
}
else if ((thread->state & ThreadState_StopRequested) != 0) {
/* FIXME: do this through the JIT? */
- mono_monitor_exit (thread->synch_lock);
+
+ LeaveCriticalSection (thread->synch_cs);
+
mono_thread_exit ();
return NULL;
} else if (thread->thread_interrupt_requested) {
- mono_monitor_exit (thread->synch_lock);
+
+ LeaveCriticalSection (thread->synch_cs);
+
return(mono_get_exception_thread_interrupted ());
}
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
return NULL;
}
@@ -3187,10 +3219,11 @@
if (thread == NULL)
return NULL;
- mono_monitor_enter (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
if (thread->interruption_requested) {
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
return NULL;
}
@@ -3201,15 +3234,17 @@
InterlockedIncrement (&thread_interruption_requested);
thread->interruption_requested = TRUE;
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
/* this will awake the thread if it is in WaitForSingleObject
or similar */
QueueUserAPC ((PAPCFUNC)dummy_apc, thread->handle, NULL);
return NULL;
}
else {
- mono_monitor_exit (thread->synch_lock);
+ LeaveCriticalSection (thread->synch_cs);
+
return mono_thread_execute_interruption (thread);
}
}
@@ -3303,3 +3338,35 @@
}
#endif
}
+
+void
+mono_thread_set_state (MonoThread *thread, MonoThreadState state)
+{
+ EnterCriticalSection (thread->synch_cs);
+ thread->state |= state;
+ LeaveCriticalSection (thread->synch_cs);
+}
+
+void
+mono_thread_clr_state (MonoThread *thread, MonoThreadState state)
+{
+ EnterCriticalSection (thread->synch_cs);
+ thread->state &= ~state;
+ LeaveCriticalSection (thread->synch_cs);
+}
+
+gboolean
+mono_thread_test_state (MonoThread *thread, MonoThreadState test)
+{
+ gboolean ret = FALSE;
+
+ EnterCriticalSection (thread->synch_cs);
+
+ if ((thread->state & test) != 0) {
+ ret = TRUE;
+ }
+
+ LeaveCriticalSection (thread->synch_cs);
+
+ return ret;
+}
Modified: trunk/mono/mono/metadata/threads.h
===================================================================
--- trunk/mono/mono/metadata/threads.h 2007-10-15 14:49:07 UTC (rev 87515)
+++ trunk/mono/mono/metadata/threads.h 2007-10-15 14:49:11 UTC (rev 87516)
@@ -14,6 +14,7 @@
#include <mono/utils/mono-membar.h>
#include <mono/metadata/object.h>
#include <mono/metadata/appdomain.h>
+#include <mono/metadata/threads-types.h>
G_BEGIN_DECLS
@@ -66,6 +67,10 @@
extern void mono_thread_force_interruption_checkpoint (void);
extern gint32* mono_thread_interruption_request_flag (void);
+extern void mono_thread_set_state (MonoThread *thread, MonoThreadState state);
+extern void mono_thread_clr_state (MonoThread *thread, MonoThreadState state);
+extern gboolean mono_thread_test_state (MonoThread *thread, MonoThreadState
test);
+
G_END_DECLS
#endif /* _MONO_METADATA_THREADS_H_ */
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches