Author: dick
Date: 2007-08-30 16:34:41 -0400 (Thu, 30 Aug 2007)
New Revision: 85075
Modified:
trunk/mono/mono/metadata/ChangeLog
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.c
trunk/mono/mono/metadata/threads.h
Log:
2007-08-30 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-08-30 20:33:52 UTC (rev 85074)
+++ trunk/mono/mono/metadata/ChangeLog 2007-08-30 20:34:41 UTC (rev 85075)
@@ -1,4 +1,19 @@
+2007-08-30 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
+
Thu Aug 30 18:34:38 CEST 2007 Paolo Molaro <[EMAIL PROTECTED]>
* cil-coff.h, image.c: updated assembly loader to cope with the
Modified: trunk/mono/mono/metadata/monitor.c
===================================================================
--- trunk/mono/mono/metadata/monitor.c 2007-08-30 20:33:52 UTC (rev 85074)
+++ trunk/mono/mono/metadata/monitor.c 2007-08-30 20:34:41 UTC (rev 85075)
@@ -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-08-30 20:33:52 UTC (rev
85074)
+++ trunk/mono/mono/metadata/object-internals.h 2007-08-30 20:34:41 UTC (rev
85075)
@@ -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-08-30 20:33:52 UTC (rev
85074)
+++ trunk/mono/mono/metadata/socket-io.c 2007-08-30 20:34:41 UTC (rev
85075)
@@ -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.c
===================================================================
--- trunk/mono/mono/metadata/threads.c 2007-08-30 20:33:52 UTC (rev 85074)
+++ trunk/mono/mono/metadata/threads.c 2007-08-30 20:34:41 UTC (rev 85075)
@@ -447,13 +447,16 @@
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);
+ DeleteCriticalSection (thread->synch_cs);
+
+ g_free (thread->synch_cs);
+
mono_profiler_thread_end (thread->tid);
if (thread == mono_thread_current ())
@@ -635,7 +638,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);
@@ -719,8 +723,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);
@@ -787,15 +793,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;
}
@@ -803,7 +820,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;
@@ -818,7 +835,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);
}
@@ -826,7 +843,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);
}
@@ -847,7 +864,7 @@
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);
}
}
@@ -903,15 +920,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)
@@ -938,24 +951,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;
}
@@ -967,7 +983,7 @@
else
this_obj->name = NULL;
- mono_monitor_exit (this_obj->synch_lock);
+ LeaveCriticalSection (this_obj->synch_cs);
}
static MonoObject*
@@ -999,15 +1015,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;
}
@@ -1020,7 +1038,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);
@@ -1043,7 +1062,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
@@ -1055,13 +1075,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);
}
@@ -1076,15 +1098,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;
}
@@ -1097,13 +1121,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 */
@@ -1120,20 +1146,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;
}
@@ -1141,9 +1169,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__));
@@ -1183,15 +1209,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);
@@ -1238,16 +1260,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));
@@ -1282,16 +1300,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);
@@ -1730,8 +1744,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
@@ -1739,14 +1753,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
@@ -1754,16 +1767,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;
}
@@ -1771,19 +1787,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);
}
@@ -1794,14 +1807,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 ());
@@ -1876,19 +1889,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;
}
@@ -1896,7 +1909,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));
@@ -1913,20 +1926,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
@@ -1934,13 +1947,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;
}
@@ -1948,13 +1961,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;
}
@@ -1971,11 +1985,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;
}
@@ -1984,20 +1998,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);
@@ -2040,12 +2054,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;
}
@@ -2055,7 +2069,7 @@
thread->state |= ThreadState_StopRequested;
thread->state &= ~ThreadState_AbortRequested;
- mono_monitor_exit (thread->synch_lock);
+ EnterCriticalSection (thread->synch_cs);
signal_thread_state_change (thread);
}
@@ -2129,6 +2143,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);
@@ -2523,13 +2538,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;
@@ -2545,13 +2560,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);
@@ -2564,10 +2579,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);
@@ -2734,7 +2749,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) {
@@ -3111,7 +3126,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 */
@@ -3123,7 +3138,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) {
@@ -3131,16 +3146,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;
@@ -3149,20 +3166,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;
}
@@ -3182,10 +3206,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;
}
@@ -3196,15 +3221,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);
}
}
@@ -3298,3 +3325,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-08-30 20:33:52 UTC (rev 85074)
+++ trunk/mono/mono/metadata/threads.h 2007-08-30 20:34:41 UTC (rev 85075)
@@ -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