Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Kumpera <kumpera@gmail.com>2009-06-08 19:45:51 +0400
committerRodrigo Kumpera <kumpera@gmail.com>2009-06-08 19:45:51 +0400
commit3075fb3f7c745c63b8819e8bf9793a1ba867bcd2 (patch)
tree21a2659519ce7e79d6ca0d2ec544f5232827c2b7
parentaa667d9821277cc52f2e7d164882432176450254 (diff)
2009-06-08 Rodrigo Kumpera <rkumpera@novell.com>
Backport of 135171. * threads.c (ves_icall_System_Threading_Thread_Sleep_internal): Check if the thread was interrupted and proccess it straight away. Makes abortion much more responsive. Backport of 135170. * threads.c (mono_thread_execute_interruption): Use atomic cas with MonoThread::interruption_requested to match it's counterpart. Fixes a hang in abort-stress-1 on a 2 core x86. svn path=/branches/mono-2-4/mono/; revision=135666
-rw-r--r--mono/metadata/ChangeLog15
-rw-r--r--mono/metadata/threads.c16
2 files changed, 26 insertions, 5 deletions
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index b6e783f2dbc..ffe74473132 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,18 @@
+2009-06-08 Rodrigo Kumpera <rkumpera@novell.com>
+
+ Backport of 135171.
+
+ * threads.c (ves_icall_System_Threading_Thread_Sleep_internal):
+ Check if the thread was interrupted and proccess it straight away.
+ Makes abortion much more responsive.
+
+ Backport of 135170.
+
+ * threads.c (mono_thread_execute_interruption): Use atomic cas with
+ MonoThread::interruption_requested to match it's counterpart.
+
+ Fixes a hang in abort-stress-1 on a 2 core x86.
+
2009-06-01 Rodrigo Kumpera <rkumpera@novell.com>
* marshal.c (mono_marshal_get_runtime_invoke): Emit the right kind
diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c
index 8de9c2283e8..913935a7af8 100644
--- a/mono/metadata/threads.c
+++ b/mono/metadata/threads.c
@@ -167,6 +167,8 @@ static gboolean mono_thread_resume (MonoThread* thread);
static void mono_thread_start (MonoThread *thread);
static void signal_thread_state_change (MonoThread *thread);
+static MonoException* mono_thread_execute_interruption (MonoThread *thread);
+
/* Spin lock for InterlockedXXX 64 bit functions */
#define mono_interlocked_lock() EnterCriticalSection (&interlocked_mutex)
#define mono_interlocked_unlock() LeaveCriticalSection (&interlocked_mutex)
@@ -1043,6 +1045,7 @@ static void mono_thread_start (MonoThread *thread)
void ves_icall_System_Threading_Thread_Sleep_internal(gint32 ms)
{
+ guint32 res;
MonoThread *thread = mono_thread_current ();
MONO_ARCH_SAVE_REGS;
@@ -1053,9 +1056,14 @@ void ves_icall_System_Threading_Thread_Sleep_internal(gint32 ms)
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- SleepEx(ms,TRUE);
+ res = SleepEx(ms,TRUE);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
+
+ if (res == WAIT_IO_COMPLETION) { /* we might have been interrupted */
+ MonoException* exc = mono_thread_execute_interruption (thread);
+ if (exc) mono_raise_exception (exc);
+ }
}
void ves_icall_System_Threading_Thread_SpinWait_nop (void)
@@ -2607,8 +2615,6 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
return (thread->tid != self && !mono_gc_is_finalizer_thread (thread));
}
-static MonoException* mono_thread_execute_interruption (MonoThread *thread);
-
/**
* mono_threads_set_shutting_down:
*
@@ -3497,11 +3503,11 @@ static MonoException* mono_thread_execute_interruption (MonoThread *thread)
EnterCriticalSection (thread->synch_cs);
- if (thread->interruption_requested) {
+ /* MonoThread::interruption_requested can only be changed with atomics */
+ if (InterlockedCompareExchange (&thread->interruption_requested, FALSE, TRUE)) {
/* this will consume pending APC calls */
WaitForSingleObjectEx (GetCurrentThread(), 0, TRUE);
InterlockedDecrement (&thread_interruption_requested);
- thread->interruption_requested = FALSE;
#ifndef PLATFORM_WIN32
/* Clear the interrupted flag of the thread so it can wait again */
wapi_clear_interruption ();