diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2009-06-08 19:45:51 +0400 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2009-06-08 19:45:51 +0400 |
commit | 3075fb3f7c745c63b8819e8bf9793a1ba867bcd2 (patch) | |
tree | 21a2659519ce7e79d6ca0d2ec544f5232827c2b7 | |
parent | aa667d9821277cc52f2e7d164882432176450254 (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/ChangeLog | 15 | ||||
-rw-r--r-- | mono/metadata/threads.c | 16 |
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 (); |