Skip to content

Instantly share code, notes, and snippets.

@kumpera
Created June 27, 2012 14:57
Show Gist options
  • Save kumpera/3004626 to your computer and use it in GitHub Desktop.
Save kumpera/3004626 to your computer and use it in GitHub Desktop.
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 (&current->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 (&current->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