Created
June 27, 2012 14:57
-
-
Save kumpera/3004626 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs | |
| index f45f6f8..30d9f65 100644 | |
| --- a/mcs/class/System/System.Net.Sockets/Socket.cs | |
| +++ b/mcs/class/System/System.Net.Sockets/Socket.cs | |
| @@ -543,14 +543,9 @@ namespace System.Net.Sockets | |
| int error = 0; | |
| IntPtr sock = (IntPtr) (-1); | |
| - blocking_thread = Thread.CurrentThread; | |
| try { | |
| + blocking_thread = Thread.CurrentThread; | |
| sock = Accept_internal(socket, out error, blocking); | |
| - } catch (ThreadAbortException) { | |
| - if (disposed) { | |
| - Thread.ResetAbort (); | |
| - error = (int) SocketError.Interrupted; | |
| - } | |
| } finally { | |
| blocking_thread = null; | |
| } | |
| @@ -573,15 +568,10 @@ namespace System.Net.Sockets | |
| int error = 0; | |
| IntPtr sock = (IntPtr)(-1); | |
| - blocking_thread = Thread.CurrentThread; | |
| try { | |
| + blocking_thread = Thread.CurrentThread; | |
| sock = Accept_internal (socket, out error, blocking); | |
| - } catch (ThreadAbortException) { | |
| - if (disposed) { | |
| - Thread.ResetAbort (); | |
| - error = (int)SocketError.Interrupted; | |
| - } | |
| } finally { | |
| blocking_thread = null; | |
| } | |
| diff --git a/mcs/class/System/System.Net.Sockets/Socket_2_1.cs b/mcs/class/System/System.Net.Sockets/Socket_2_1.cs | |
| index 0e93212..2aa7ad2 100644 | |
| --- a/mcs/class/System/System.Net.Sockets/Socket_2_1.cs | |
| +++ b/mcs/class/System/System.Net.Sockets/Socket_2_1.cs | |
| @@ -1145,6 +1145,8 @@ namespace System.Net.Sockets { | |
| return; */ | |
| } | |
| } | |
| + [MethodImplAttribute(MethodImplOptions.InternalCall)] | |
| + static extern void abort_thread_syscall (Thread thread); | |
| protected virtual void Dispose (bool disposing) | |
| { | |
| @@ -1161,7 +1163,7 @@ namespace System.Net.Sockets { | |
| socket = (IntPtr) (-1); | |
| Thread th = blocking_thread; | |
| if (th != null) { | |
| - th.Abort (); | |
| + abort_thread_syscall (th); | |
| blocking_thread = null; | |
| } | |
| @@ -1237,14 +1239,9 @@ namespace System.Net.Sockets { | |
| int error = 0; | |
| - blocking_thread = Thread.CurrentThread; | |
| try { | |
| + blocking_thread = Thread.CurrentThread; | |
| Connect_internal (socket, serial, out error); | |
| - } catch (ThreadAbortException) { | |
| - if (disposed) { | |
| - Thread.ResetAbort (); | |
| - error = (int) SocketError.Interrupted; | |
| - } | |
| } finally { | |
| blocking_thread = null; | |
| } | |
| @@ -1754,8 +1751,12 @@ namespace System.Net.Sockets { | |
| // FIXME: this is canceling a synchronous connect, not an async one | |
| Socket s = e.ConnectSocket; | |
| - if ((s != null) && (s.blocking_thread != null)) | |
| - s.blocking_thread.Abort (); | |
| + if (s != null) { | |
| + Thread th = s.blocking_thread; | |
| + if (th != null) | |
| + abort_thread_syscall (s.blocking_thread); | |
| + } | |
| + } | |
| } | |
| #endif | |
| [MethodImplAttribute (MethodImplOptions.InternalCall)] | |
| diff --git a/mcs/class/corlib/System.Threading/Thread.cs b/mcs/class/corlib/System.Threading/Thread.cs | |
| index 89b1a5a..b12fad9 100644 | |
| --- a/mcs/class/corlib/System.Threading/Thread.cs | |
| +++ b/mcs/class/corlib/System.Threading/Thread.cs | |
| @@ -103,6 +103,7 @@ namespace System.Threading { | |
| private IntPtr unused4; | |
| private IntPtr unused5; | |
| internal int managed_id; | |
| + int ignore_next_signal; | |
| #endregion | |
| #pragma warning restore 169, 414, 649 | |
| diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs | |
| index eec3176..2919180 100644 | |
| --- a/mcs/class/corlib/System/Environment.cs | |
| +++ b/mcs/class/corlib/System/Environment.cs | |
| @@ -56,7 +56,7 @@ namespace System { | |
| * of icalls, do not require an increment. | |
| */ | |
| #pragma warning disable 169 | |
| - private const int mono_corlib_version = 102; | |
| + private const int mono_corlib_version = 103; | |
| #pragma warning restore 169 | |
| [ComVisible (true)] | |
| diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c | |
| index 817b847..285a179 100644 | |
| --- a/mono/io-layer/sockets.c | |
| +++ b/mono/io-layer/sockets.c | |
| @@ -335,7 +335,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr, | |
| (gpointer *)&socket_handle); | |
| if (ok == FALSE) { | |
| /* ECONNRESET means the socket was closed by another thread */ | |
| - if (errnum != WSAECONNRESET) | |
| + /* Async close on mac raises ECONNABORTED. */ | |
| + if (errnum != WSAECONNRESET && errnum != WSAENETDOWN) | |
| g_warning ("%s: error looking up socket handle %p (error %d)", __func__, handle, errnum); | |
| } else { | |
| socket_handle->saved_error = errnum; | |
| diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c | |
| index 95ac5ee..1b9ac9a 100644 | |
| --- a/mono/metadata/appdomain.c | |
| +++ b/mono/metadata/appdomain.c | |
| @@ -75,7 +75,7 @@ | |
| * Changes which are already detected at runtime, like the addition | |
| * of icalls, do not require an increment. | |
| */ | |
| -#define MONO_CORLIB_VERSION 102 | |
| +#define MONO_CORLIB_VERSION 103 | |
| typedef struct | |
| { | |
| diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h | |
| index cb6e8b4..7cddab1 100644 | |
| --- a/mono/metadata/icall-def.h | |
| +++ b/mono/metadata/icall-def.h | |
| @@ -466,6 +466,7 @@ ICALL(SOCK_18, "SetSocketOption_internal(intptr,System.Net.Sockets.SocketOptionL | |
| ICALL(SOCK_19, "Shutdown_internal(intptr,System.Net.Sockets.SocketShutdown,int&)", ves_icall_System_Net_Sockets_Socket_Shutdown_internal) | |
| ICALL(SOCK_20, "Socket_internal(System.Net.Sockets.AddressFamily,System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType,int&)", ves_icall_System_Net_Sockets_Socket_Socket_internal) | |
| ICALL(SOCK_21, "WSAIoctl(intptr,int,byte[],byte[],int&)", ves_icall_System_Net_Sockets_Socket_WSAIoctl) | |
| +ICALL(SOCK_21a, "abort_thread_syscall", icall_abort_thread_syscall) | |
| ICALL(SOCK_22, "socket_pool_queue", icall_append_io_job) | |
| ICALL_TYPE(SOCKEX, "System.Net.Sockets.SocketException", SOCKEX_1) | |
| diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h | |
| index bad45034..567eadc 100644 | |
| --- a/mono/metadata/object-internals.h | |
| +++ b/mono/metadata/object-internals.h | |
| @@ -411,6 +411,7 @@ struct _MonoInternalThread { | |
| gpointer android_tid; | |
| gpointer thread_pinning_ref; | |
| gint32 managed_id; | |
| + gint32 ignore_next_signal; | |
| /* | |
| * These fields are used to avoid having to increment corlib versions | |
| * when a new field is added to the unmanaged MonoThread structure. | |
| diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h | |
| index 26ab1f4..9d2fdc3f 100644 | |
| --- a/mono/metadata/threads-types.h | |
| +++ b/mono/metadata/threads-types.h | |
| @@ -224,4 +224,6 @@ gpointer mono_get_special_static_data_for_thread (MonoInternalThread *thread, gu | |
| MonoException* mono_thread_resume_interruption (void) MONO_INTERNAL; | |
| void mono_threads_perform_thread_dump (void) MONO_INTERNAL; | |
| +void icall_abort_thread_syscall (MonoThread *thread) MONO_INTERNAL; | |
| + | |
| #endif /* _MONO_METADATA_THREADS_TYPES_H_ */ | |
| diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c | |
| index e3b9e1a..8adc1a7 100644 | |
| --- a/mono/metadata/threads.c | |
| +++ b/mono/metadata/threads.c | |
| @@ -4655,3 +4655,19 @@ resume_thread_internal (MonoInternalThread *thread) | |
| LeaveCriticalSection (thread->synch_cs); | |
| return TRUE; | |
| } | |
| + | |
| +void | |
| +icall_abort_thread_syscall (MonoThread *thread) | |
| +{ | |
| + MonoInternalThread *internal = thread->internal_thread; | |
| + | |
| + if (mono_thread_info_new_interrupt_enabled ()) { | |
| + mono_thread_info_abort_syscall ((MonoNativeThreadId)(gsize)internal->tid); | |
| + } else { | |
| +#ifndef HOST_WIN32 | |
| + internal->ignore_next_signal = TRUE; | |
| + mono_thread_kill (internal, mono_thread_get_abort_signal ()); | |
| +#endif | |
| + } | |
| +} | |
| + | |
| diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c | |
| index 9fec75e..605a1ff 100644 | |
| --- a/mono/mini/mini-posix.c | |
| +++ b/mono/mini/mini-posix.c | |
| @@ -213,6 +213,11 @@ SIG_HANDLER_SIGNATURE (sigusr1_signal_handler) | |
| /* FIXME: Specify the synchronization with start_wrapper () in threads.c */ | |
| return; | |
| + if (thread->ignore_next_signal) { | |
| + thread->ignore_next_signal = FALSE; | |
| + return; | |
| + } | |
| + | |
| if (thread->thread_dump_requested) { | |
| thread->thread_dump_requested = FALSE; | |
| diff --git a/mono/utils/mono-threads-mach.c b/mono/utils/mono-threads-mach.c | |
| index ddc8ae1..fabef28 100644 | |
| --- a/mono/utils/mono-threads-mach.c | |
| +++ b/mono/utils/mono-threads-mach.c | |
| @@ -34,6 +34,17 @@ mono_threads_core_interrupt (MonoThreadInfo *info) | |
| thread_abort (info->native_handle); | |
| } | |
| +void | |
| +mono_threads_core_abort_syscall (MonoThreadInfo *info) | |
| +{ | |
| +} | |
| + | |
| +gboolean | |
| +mono_threads_core_needs_abort_syscall (void) | |
| +{ | |
| + return FALSE; | |
| +} | |
| + | |
| gboolean | |
| mono_threads_core_suspend (MonoThreadInfo *info) | |
| { | |
| diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c | |
| index ffb5e34..bb19d0f 100644 | |
| --- a/mono/utils/mono-threads-posix.c | |
| +++ b/mono/utils/mono-threads-posix.c | |
| @@ -84,7 +84,14 @@ static void | |
| suspend_signal_handler (int _dummy, siginfo_t *info, void *context) | |
| { | |
| MonoThreadInfo *current = mono_thread_info_current (); | |
| - gboolean ret = mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (¤t->suspend_state, context); | |
| + gboolean ret; | |
| + | |
| + if (current->syscall_signal) { | |
| + current->syscall_signal = FALSE; | |
| + return; | |
| + } | |
| + | |
| + ret = mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (¤t->suspend_state, context); | |
| g_assert (ret); | |
| @@ -163,6 +170,20 @@ mono_threads_pthread_kill (MonoThreadInfo *info, int signum) | |
| } | |
| + | |
| +void | |
| +mono_threads_core_abort_syscall (MonoThreadInfo *info) | |
| +{ | |
| + info->syscall_signal = TRUE; | |
| + mono_threads_pthread_kill (info, mono_thread_get_abort_signal ()); | |
| +} | |
| + | |
| +gboolean | |
| +mono_threads_core_needs_abort_syscall (void) | |
| +{ | |
| + return TRUE; | |
| +} | |
| + | |
| gboolean | |
| mono_threads_core_suspend (MonoThreadInfo *info) | |
| { | |
| diff --git a/mono/utils/mono-threads-windows.c b/mono/utils/mono-threads-windows.c | |
| index 720ee39..ae039da 100644 | |
| --- a/mono/utils/mono-threads-windows.c | |
| +++ b/mono/utils/mono-threads-windows.c | |
| @@ -26,6 +26,17 @@ mono_threads_core_interrupt (MonoThreadInfo *info) | |
| } | |
| void | |
| +mono_threads_core_abort_syscall (MonoThreadInfo *info) | |
| +{ | |
| +} | |
| + | |
| +gboolean | |
| +mono_threads_core_needs_abort_syscall (void) | |
| +{ | |
| + return FALSE; | |
| +} | |
| + | |
| +void | |
| mono_threads_core_self_suspend (MonoThreadInfo *info) | |
| { | |
| g_assert (0); | |
| diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c | |
| index c208637..6b55df8 100644 | |
| --- a/mono/utils/mono-threads.c | |
| +++ b/mono/utils/mono-threads.c | |
| @@ -540,6 +540,34 @@ mono_thread_info_disable_new_interrupt (gboolean disable) | |
| { | |
| disable_new_interrupt = disable; | |
| } | |
| + | |
| +void | |
| +mono_thread_info_abort_syscall (MonoNativeThreadId tid) | |
| +{ | |
| + MonoThreadHazardPointers *hp; | |
| + MonoThreadInfo *info; | |
| + | |
| + if (tid == mono_native_thread_id_get ()) | |
| + return; | |
| + | |
| + hp = mono_hazard_pointer_get (); | |
| + info = mono_thread_info_lookup (tid); /*info on HP1*/ | |
| + if (!info) | |
| + return; | |
| + | |
| + if (mono_thread_info_run_state (info) > STATE_RUNNING) { | |
| + mono_hazard_pointer_clear (hp, 1); | |
| + return; | |
| + } | |
| + | |
| + mono_thread_info_suspend_lock (); | |
| + | |
| + mono_threads_core_abort_syscall (info); | |
| + | |
| + mono_hazard_pointer_clear (hp, 1); | |
| + mono_thread_info_suspend_unlock (); | |
| +} | |
| + | |
| /* | |
| Disabled by default for now. | |
| To enable this we need mini to implement the callbacks by MonoThreadInfoRuntimeCallbacks | |
| diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h | |
| index 67fe542..fc56d0f 100644 | |
| --- a/mono/utils/mono-threads.h | |
| +++ b/mono/utils/mono-threads.h | |
| @@ -108,6 +108,7 @@ typedef struct { | |
| /* only needed by the posix backend */ | |
| #if (defined(_POSIX_VERSION) || defined(__native_client__)) && !defined (__MACH__) | |
| MonoSemType suspend_semaphore; | |
| + gboolean syscall_signal; | |
| #endif | |
| /*In theory, only the posix backend needs this, but having it on mach/win32 simplifies things a lot.*/ | |
| @@ -217,6 +218,8 @@ mono_threads_unregister_current_thread (THREAD_INFO_TYPE *info) MONO_INTERNAL; | |
| void | |
| mono_thread_info_disable_new_interrupt (gboolean disable) MONO_INTERNAL; | |
| +void | |
| +mono_thread_info_abort_syscall (MonoNativeThreadId tid) MONO_INTERNAL; | |
| #if !defined(HOST_WIN32) | |
| @@ -244,6 +247,8 @@ gboolean mono_threads_core_resume (MonoThreadInfo *info) MONO_INTERNAL; | |
| void mono_threads_platform_register (MonoThreadInfo *info) MONO_INTERNAL; //ok | |
| void mono_threads_platform_free (MonoThreadInfo *info) MONO_INTERNAL; | |
| void mono_threads_core_interrupt (MonoThreadInfo *info) MONO_INTERNAL; | |
| +void mono_threads_core_abort_syscall (MonoThreadInfo *info) MONO_INTERNAL; | |
| +gboolean mono_threads_core_needs_abort_syscall (void) MONO_INTERNAL; | |
| MonoNativeThreadId mono_native_thread_id_get (void) MONO_INTERNAL; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment