Ver Fonte

Revert "[w32handle] Remove use of w32handle for File, Console, Pipe and Socket (#5283)" (#5318)

This reverts commit 78735091b62b8d7f65da2c83d36ca314a23009f4.
Ludovic Henry há 8 anos atrás
pai
commit
6e23736a07

+ 2 - 4
mcs/class/System/System.Net.Sockets/Socket.cs

@@ -2265,9 +2265,6 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
 
 #region DuplicateAndClose
 
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		static extern bool Duplicate_internal(IntPtr handle, int targetProcessId, out IntPtr duplicateHandle, out MonoIOError error);
-
 		[MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
 		public SocketInformation DuplicateAndClose (int targetProcessId)
 		{
@@ -2278,8 +2275,9 @@ m_Handle, buffer, offset + sent, size - sent, socketFlags, out nativeError, is_b
 				(is_blocking       ? 0 : SocketInformationOptions.NonBlocking) |
 				(useOverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
 
+			MonoIOError error;
 			IntPtr duplicateHandle;
-			if (!Duplicate_internal (Handle, targetProcessId, out duplicateHandle, out MonoIOError error))
+			if (!MonoIO.DuplicateHandle (System.Diagnostics.Process.GetCurrentProcess ().Handle, Handle, new IntPtr (targetProcessId), out duplicateHandle, 0, 0, 0x00000002 /* DUPLICATE_SAME_ACCESS */, out error))
 				throw MonoIO.GetException (error);
 
 			si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)addressFamily, (int)socketType, (int)protocolType, is_bound ? 1 : 0, (long)duplicateHandle);

+ 1 - 3
mono/metadata/Makefile.am

@@ -281,9 +281,7 @@ common_sources = \
 	sre.c	\
 	sre-encode.c	\
 	sre-save.c	\
-	custom-attrs.c	\
-	fdhandle.h	\
-	fdhandle.c
+	custom-attrs.c
 
 # These source files have compile time dependencies on GC code
 gc_dependent_sources = \

+ 0 - 142
mono/metadata/fdhandle.c

@@ -1,142 +0,0 @@
-
-#include "fdhandle.h"
-#include "utils/mono-lazy-init.h"
-#include "utils/mono-coop-mutex.h"
-
-static GHashTable *fds;
-static MonoCoopMutex fds_mutex;
-static MonoFDHandleCallback fds_callback[MONO_FDTYPE_COUNT];
-static mono_lazy_init_t fds_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
-
-static const gchar *types_str[] = {
-	"File",
-	"Console",
-	"Pipe",
-	"Socket",
-	NULL
-};
-
-static void
-fds_remove (gpointer data)
-{
-	MonoFDHandle* fdhandle;
-
-	fdhandle = (MonoFDHandle*) data;
-	g_assert (fdhandle);
-
-	g_assert (fds_callback [fdhandle->type].close);
-	fds_callback [fdhandle->type].close (fdhandle);
-
-	mono_refcount_dec (fdhandle);
-}
-
-static void
-initialize (void)
-{
-	fds = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, fds_remove);
-	mono_coop_mutex_init (&fds_mutex);
-}
-
-void
-mono_fdhandle_register (MonoFDType type, MonoFDHandleCallback *callback)
-{
-	mono_lazy_initialize (&fds_init, initialize);
-	memcpy (&fds_callback [type], callback, sizeof (MonoFDHandleCallback));
-}
-
-static void
-fdhandle_destroy (gpointer data)
-{
-	MonoFDHandle* fdhandle;
-
-	fdhandle = (MonoFDHandle*) data;
-	g_assert (fdhandle);
-
-	g_assert (fds_callback [fdhandle->type].destroy);
-	fds_callback [fdhandle->type].destroy (fdhandle);
-}
-
-void
-mono_fdhandle_init (MonoFDHandle *fdhandle, MonoFDType type, gint fd)
-{
-	mono_refcount_init (fdhandle, fdhandle_destroy);
-	fdhandle->type = type;
-	fdhandle->fd = fd;
-}
-
-void
-mono_fdhandle_insert (MonoFDHandle *fdhandle)
-{
-	mono_coop_mutex_lock (&fds_mutex);
-
-	if (g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fdhandle->fd), NULL, NULL))
-		g_error("%s: duplicate %s fd %d", __func__, types_str [fdhandle->type], fdhandle->fd);
-
-	g_hash_table_insert (fds, GINT_TO_POINTER(fdhandle->fd), fdhandle);
-
-	mono_coop_mutex_unlock (&fds_mutex);
-}
-
-gboolean
-mono_fdhandle_try_insert (MonoFDHandle *fdhandle)
-{
-	mono_coop_mutex_lock (&fds_mutex);
-
-	if (g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fdhandle->fd), NULL, NULL)) {
-		/* we raced between 2 invocations of mono_fdhandle_try_insert */
-		mono_coop_mutex_unlock (&fds_mutex);
-
-		return FALSE;
-	}
-
-	g_hash_table_insert (fds, GINT_TO_POINTER(fdhandle->fd), fdhandle);
-
-	mono_coop_mutex_unlock (&fds_mutex);
-
-	return TRUE;
-}
-
-gboolean
-mono_fdhandle_lookup_and_ref (gint fd, MonoFDHandle **fdhandle)
-{
-	mono_coop_mutex_lock (&fds_mutex);
-
-	if (!g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fd), NULL, (gpointer*) fdhandle)) {
-		mono_coop_mutex_unlock (&fds_mutex);
-		return FALSE;
-	}
-
-	mono_refcount_inc (*fdhandle);
-
-	mono_coop_mutex_unlock (&fds_mutex);
-
-	return TRUE;
-}
-
-void
-mono_fdhandle_unref (MonoFDHandle *fdhandle)
-{
-	mono_refcount_dec (fdhandle);
-}
-
-gboolean
-mono_fdhandle_close (gint fd)
-{
-	MonoFDHandle *fdhandle;
-	gboolean removed;
-
-	mono_coop_mutex_lock (&fds_mutex);
-
-	if (!g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fd), NULL, (gpointer*) &fdhandle)) {
-		mono_coop_mutex_unlock (&fds_mutex);
-
-		return FALSE;
-	}
-
-	removed = g_hash_table_remove (fds, GINT_TO_POINTER(fdhandle->fd));
-	g_assert (removed);
-
-	mono_coop_mutex_unlock (&fds_mutex);
-
-	return TRUE;
-}

+ 0 - 50
mono/metadata/fdhandle.h

@@ -1,50 +0,0 @@
-
-#ifndef __MONO_METADATA_FDHANDLE_H__
-#define __MONO_METADATA_FDHANDLE_H__
-
-#include <config.h>
-#include <glib.h>
-
-#include "utils/refcount.h"
-
-typedef enum {
-	MONO_FDTYPE_FILE,
-	MONO_FDTYPE_CONSOLE,
-	MONO_FDTYPE_PIPE,
-	MONO_FDTYPE_SOCKET,
-	MONO_FDTYPE_COUNT
-} MonoFDType;
-
-typedef struct {
-	MonoRefCount ref;
-	MonoFDType type;
-	gint fd;
-} MonoFDHandle;
-
-typedef struct {
-	void (*close) (MonoFDHandle *fdhandle);
-	void (*destroy) (MonoFDHandle *fdhandle);
-} MonoFDHandleCallback;
-
-void
-mono_fdhandle_register (MonoFDType type, MonoFDHandleCallback *callback);
-
-void
-mono_fdhandle_init (MonoFDHandle *fdhandle, MonoFDType type, gint fd);
-
-void
-mono_fdhandle_insert (MonoFDHandle *fdhandle);
-
-gboolean
-mono_fdhandle_try_insert (MonoFDHandle *fdhandle);
-
-gboolean
-mono_fdhandle_lookup_and_ref (gint fd, MonoFDHandle **fdhandle);
-
-void
-mono_fdhandle_unref (MonoFDHandle *fdhandle);
-
-gboolean
-mono_fdhandle_close (gint fd);
-
-#endif /* __MONO_METADATA_FDHANDLE_H__ */

+ 1 - 2
mono/metadata/icall-def.h

@@ -459,8 +459,7 @@ HANDLES(ICALL(SOCK_3, "Bind_internal(intptr,System.Net.SocketAddress,int&)", ves
 HANDLES(ICALL(SOCK_4, "Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal))
 HANDLES(ICALL(SOCK_5, "Close_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Close_internal))
 HANDLES(ICALL(SOCK_6, "Connect_internal(intptr,System.Net.SocketAddress,int&,bool)", ves_icall_System_Net_Sockets_Socket_Connect_internal))
-HANDLES(ICALL(SOCK_6a, "Disconnect_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Disconnect_internal))
-HANDLES(ICALL(SOCK_6b, "Duplicate_internal", ves_icall_System_Net_Sockets_Socket_Duplicate_internal))
+HANDLES(ICALL (SOCK_6a, "Disconnect_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Disconnect_internal))
 HANDLES(ICALL(SOCK_7, "GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal))
 HANDLES(ICALL(SOCK_8, "GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal))
 HANDLES(ICALL(SOCK_21, "IOControl_internal(intptr,int,byte[],byte[],int&)", ves_icall_System_Net_Sockets_Socket_IOControl_internal))

Diff do ficheiro suprimidas por serem muito extensas
+ 476 - 153
mono/metadata/w32file-unix.c


+ 9 - 7
mono/metadata/w32file.c

@@ -1065,22 +1065,24 @@ MonoBoolean
 ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE source_handle,
 		HANDLE target_process_handle, HANDLE *target_handle, gint32 access, gint32 inherit, gint32 options, gint32 *error)
 {
-#ifndef HOST_WIN32
-	*target_handle = mono_w32handle_duplicate (source_handle);
-#else
+	/* This is only used on Windows */
 	gboolean ret;
-
+	
+#ifdef HOST_WIN32
 	MONO_ENTER_GC_SAFE;
 	ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
 	MONO_EXIT_GC_SAFE;
+#else
+	*target_handle = mono_w32handle_duplicate (source_handle);
+	ret = TRUE;
+#endif
 
-	if (!ret) {
+	if(ret==FALSE) {
 		*error = mono_w32error_get_last ();
 		/* FIXME: throw an exception? */
 		return(FALSE);
 	}
-#endif
-
+	
 	return(TRUE);
 }
 

+ 160 - 31
mono/metadata/w32handle.c

@@ -51,7 +51,10 @@ static MonoW32HandleOps *handle_ops [MONO_W32HANDLE_COUNT];
 #define SLOT_OFFSET(x)	(x % HANDLE_PER_SLOT)
 
 static MonoW32HandleBase *private_handles [SLOT_MAX];
-static guint32 private_handles_size = 0;
+static guint32 private_handles_count = 0;
+static guint32 private_handles_slots_count = 0;
+
+guint32 mono_w32handle_fd_reserve;
 
 /*
  * This is an internal handle which is used for handling waiting for multiple handles.
@@ -65,6 +68,20 @@ static mono_mutex_t scan_mutex;
 
 static gboolean shutting_down = FALSE;
 
+static gboolean
+type_is_fd (MonoW32HandleType type)
+{
+	switch (type) {
+	case MONO_W32HANDLE_FILE:
+	case MONO_W32HANDLE_CONSOLE:
+	case MONO_W32HANDLE_SOCKET:
+	case MONO_W32HANDLE_PIPE:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
 static gboolean
 mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
 {
@@ -262,6 +279,19 @@ mono_w32handle_init (void)
 	g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
 		  == MONO_W32HANDLE_COUNT);
 
+	/* This is needed by the code in mono_w32handle_new_internal */
+	mono_w32handle_fd_reserve = (eg_getdtablesize () + (HANDLE_PER_SLOT - 1)) & ~(HANDLE_PER_SLOT - 1);
+
+	do {
+		/*
+		 * The entries in private_handles reserved for fds are allocated lazily to
+		 * save memory.
+		 */
+
+		private_handles_count += HANDLE_PER_SLOT;
+		private_handles_slots_count ++;
+	} while(mono_w32handle_fd_reserve > private_handles_count);
+
 	mono_os_mutex_init (&scan_mutex);
 
 	mono_os_cond_init (&global_signal_cond);
@@ -285,6 +315,22 @@ mono_w32handle_cleanup (void)
 static gsize
 mono_w32handle_ops_typesize (MonoW32HandleType type);
 
+static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
+			       MonoW32HandleType type, gpointer handle_specific)
+{
+	g_assert (handle->ref == 0);
+
+	handle->type = type;
+	handle->signalled = FALSE;
+	handle->ref = 1;
+
+	mono_os_cond_init (&handle->signal_cond);
+	mono_os_mutex_init (&handle->signal_mutex);
+
+	if (handle_specific)
+		handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
+}
+
 /*
  * mono_w32handle_new_internal:
  * @type: Init handle to this type
@@ -306,16 +352,15 @@ static guint32 mono_w32handle_new_internal (MonoW32HandleType type,
 	 * descriptors
 	 */
 
-	if (last == 0) {
-		/* We need to go from 1 since a handle of value 0 can be considered invalid in managed code */
-		last = 1;
+	if (last < mono_w32handle_fd_reserve) {
+		last = mono_w32handle_fd_reserve;
 	} else {
 		retry = TRUE;
 	}
 
 again:
 	count = last;
-	for(i = SLOT_INDEX (count); i < private_handles_size; i++) {
+	for(i = SLOT_INDEX (count); i < private_handles_slots_count; i++) {
 		if (private_handles [i]) {
 			for (k = SLOT_OFFSET (count); k < HANDLE_PER_SLOT; k++) {
 				MonoW32HandleBase *handle = &private_handles [i][k];
@@ -323,18 +368,7 @@ again:
 				if(handle->type == MONO_W32HANDLE_UNUSED) {
 					last = count + 1;
 
-					g_assert (handle->ref == 0);
-
-					handle->type = type;
-					handle->signalled = FALSE;
-					handle->ref = 1;
-
-					mono_os_cond_init (&handle->signal_cond);
-					mono_os_mutex_init (&handle->signal_mutex);
-
-					if (handle_specific)
-						handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
-
+					mono_w32handle_init_handle (handle, type, handle_specific);
 					return (count);
 				}
 				count++;
@@ -342,50 +376,108 @@ again:
 		}
 	}
 
-	if (retry) {
+	if(retry && last > mono_w32handle_fd_reserve) {
 		/* Try again from the beginning */
-		last = 1;
-		retry = FALSE;
+		last = mono_w32handle_fd_reserve;
 		goto again;
 	}
 
 	/* Will need to expand the array.  The caller will sort it out */
 
-	return G_MAXUINT32;
+	return(0);
 }
 
 gpointer
 mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
 {
-	guint32 handle_idx;
+	guint32 handle_idx = 0;
 	gpointer handle;
 
 	g_assert (!shutting_down);
 
+	g_assert(!type_is_fd(type));
+
 	mono_os_mutex_lock (&scan_mutex);
 
-	while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == G_MAXUINT32) {
+	while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
 		/* Try and expand the array, and have another go */
-		if (private_handles_size >= SLOT_MAX) {
-			mono_os_mutex_unlock (&scan_mutex);
-
-			/* We ran out of slots */
-			mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
-			return INVALID_HANDLE_VALUE;
+		int idx = SLOT_INDEX (private_handles_count);
+		if (idx >= SLOT_MAX) {
+			break;
 		}
 
-		private_handles [private_handles_size ++] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+		private_handles [idx] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+
+		private_handles_count += HANDLE_PER_SLOT;
+		private_handles_slots_count ++;
 	}
 
 	mono_os_mutex_unlock (&scan_mutex);
 
+	if (handle_idx == 0) {
+		/* We ran out of slots */
+		handle = INVALID_HANDLE_VALUE;
+		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
+		goto done;
+	}
+
+	/* Make sure we left the space for fd mappings */
+	g_assert (handle_idx >= mono_w32handle_fd_reserve);
+
 	handle = GUINT_TO_POINTER (handle_idx);
 
 	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
 
+done:
 	return(handle);
 }
 
+gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
+			      gpointer handle_specific)
+{
+	MonoW32HandleBase *handle_data;
+	int fd_index, fd_offset;
+
+	g_assert (!shutting_down);
+
+	g_assert(type_is_fd(type));
+
+	if (fd >= mono_w32handle_fd_reserve) {
+		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is too big", __func__, mono_w32handle_ops_typename (type));
+
+		return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
+	}
+
+	fd_index = SLOT_INDEX (fd);
+	fd_offset = SLOT_OFFSET (fd);
+
+	mono_os_mutex_lock (&scan_mutex);
+	/* Initialize the array entries on demand */
+	if (!private_handles [fd_index]) {
+		if (!private_handles [fd_index])
+			private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+	}
+
+	handle_data = &private_handles [fd_index][fd_offset];
+
+	if (handle_data->type != MONO_W32HANDLE_UNUSED) {
+		mono_os_mutex_unlock (&scan_mutex);
+		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is already in use", __func__, mono_w32handle_ops_typename (type));
+		/* FIXME: clean up this handle?  We can't do anything
+		 * with the fd, cos thats the new one
+		 */
+		return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
+	}
+
+	mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), GUINT_TO_POINTER(fd));
+
+	mono_w32handle_init_handle (handle_data, type, handle_specific);
+
+	mono_os_mutex_unlock (&scan_mutex);
+
+	return(GUINT_TO_POINTER(fd));
+}
+
 static gboolean
 mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data);
 
@@ -404,6 +496,8 @@ mono_w32handle_duplicate (gpointer handle)
 		return handle;
 	if (!mono_w32handle_lookup_data (handle, &handle_data))
 		return INVALID_HANDLE_VALUE;
+	if (handle == (gpointer) 0 && handle_data->type != MONO_W32HANDLE_CONSOLE)
+		return handle;
 
 	if (!mono_w32handle_ref_core (handle, handle_data))
 		g_error ("%s: failed to ref handle %p", __func__, handle);
@@ -421,6 +515,14 @@ mono_w32handle_close (gpointer handle)
 		return FALSE;
 	if (!mono_w32handle_lookup_data (handle, &handle_data))
 		return FALSE;
+	if (handle == (gpointer) 0 && handle_data->type != MONO_W32HANDLE_CONSOLE) {
+		/* Problem: because we map file descriptors to the
+		 * same-numbered handle we can't tell the difference
+		 * between a bogus handle and the handle to stdin.
+		 * Assume that it's the console handle if that handle
+		 * exists... */
+		return FALSE;
+	}
 
 	destroy = mono_w32handle_unref_core (handle, handle_data);
 	if (destroy)
@@ -460,7 +562,7 @@ mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpoi
 
 	mono_os_mutex_lock (&scan_mutex);
 
-	for (i = SLOT_INDEX (0); i < private_handles_size; i++) {
+	for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
 		if (!private_handles [i])
 			continue;
 		for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
@@ -628,6 +730,15 @@ mono_w32handle_unref (gpointer handle)
 		w32handle_destroy (handle);
 }
 
+static void
+mono_w32handle_ops_close (gpointer handle, gpointer data);
+
+void
+mono_w32handle_force_close (gpointer handle, gpointer data)
+{
+	mono_w32handle_ops_close (handle, data);
+}
+
 void
 mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops)
 {
@@ -668,6 +779,24 @@ static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer
 	return (NULL);
 }
 
+static void
+mono_w32handle_ops_close (gpointer handle, gpointer data)
+{
+	MonoW32HandleBase *handle_data;
+	MonoW32HandleType type;
+
+	if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+		return;
+	}
+
+	type = handle_data->type;
+
+	if (handle_ops[type] != NULL &&
+	    handle_ops[type]->close != NULL) {
+		handle_ops[type]->close (handle, data);
+	}
+}
+
 static void
 mono_w32handle_ops_details (MonoW32HandleType type, gpointer data)
 {

+ 13 - 0
mono/metadata/w32handle.h

@@ -24,11 +24,16 @@
 
 typedef enum {
 	MONO_W32HANDLE_UNUSED = 0,
+	MONO_W32HANDLE_FILE,
+	MONO_W32HANDLE_CONSOLE,
+	MONO_W32HANDLE_THREAD,
 	MONO_W32HANDLE_SEM,
 	MONO_W32HANDLE_MUTEX,
 	MONO_W32HANDLE_EVENT,
+	MONO_W32HANDLE_SOCKET,
 	MONO_W32HANDLE_FIND,
 	MONO_W32HANDLE_PROCESS,
+	MONO_W32HANDLE_PIPE,
 	MONO_W32HANDLE_NAMEDMUTEX,
 	MONO_W32HANDLE_NAMEDSEM,
 	MONO_W32HANDLE_NAMEDEVENT,
@@ -94,6 +99,8 @@ typedef enum {
 	MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
 } MonoW32HandleCapability;
 
+extern guint32 mono_w32handle_fd_reserve;
+
 void
 mono_w32handle_init (void);
 
@@ -106,6 +113,9 @@ mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops);
 gpointer
 mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
 
+gpointer
+mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
+
 gpointer
 mono_w32handle_duplicate (gpointer handle);
 
@@ -133,6 +143,9 @@ mono_w32handle_register_capabilities (MonoW32HandleType type, MonoW32HandleCapab
 gboolean
 mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
 
+void
+mono_w32handle_force_close (gpointer handle, gpointer data);
+
 void
 mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
 

+ 1 - 1
mono/metadata/w32process-unix.c

@@ -1945,7 +1945,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
 		dup2 (err_fd, 2);
 
 		/* Close all file descriptors */
-		for (i = eg_getdtablesize() - 1; i > 2; i--)
+		for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
 			close (i);
 
 #ifdef DEBUG_ENABLED

+ 0 - 3
mono/metadata/w32socket-internals.h

@@ -148,7 +148,4 @@ mono_w32socket_get_last_error (void);
 gint32
 mono_w32socket_convert_error (gint error);
 
-gboolean
-mono_w32socket_duplicate (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle);
-
 #endif // __MONO_METADATA_W32SOCKET_INTERNALS_H__

Diff do ficheiro suprimidas por serem muito extensas
+ 221 - 315
mono/metadata/w32socket-unix.c


+ 13 - 70
mono/metadata/w32socket-win32.c

@@ -137,19 +137,15 @@ SOCKET mono_w32socket_accept (SOCKET s, struct sockaddr *addr, socklen_t *addrle
 {
 	MonoInternalThread *curthread = mono_thread_internal_current ();
 	SOCKET newsock = INVALID_SOCKET;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_ACCEPT_BIT, blocking, TRUE, newsock, accept, s, addr, addrlen);
-	MONO_EXIT_GC_SAFE;
 	return newsock;
 }
 
 int mono_w32socket_connect (SOCKET s, const struct sockaddr *name, int namelen, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_CONNECT_BIT, blocking, FALSE, ret, connect, s, name, namelen);
 	ret = WSAGetLastError () != 0 ? SOCKET_ERROR : 0;
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
@@ -157,54 +153,42 @@ int mono_w32socket_recv (SOCKET s, char *buf, int len, int flags, gboolean block
 {
 	MonoInternalThread *curthread = mono_thread_internal_current ();
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, recv, s, buf, len, flags);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
 int mono_w32socket_recvfrom (SOCKET s, char *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, recvfrom, s, buf, len, flags, from, fromlen);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
 int mono_w32socket_recvbuffers (SOCKET s, WSABUF *lpBuffers, guint32 dwBufferCount, guint32 *lpNumberOfBytesRecvd, guint32 *lpFlags, gpointer lpOverlapped, gpointer lpCompletionRoutine, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, WSARecv, s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
 int mono_w32socket_send (SOCKET s, char *buf, int len, int flags, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, send, s, buf, len, flags);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
 int mono_w32socket_sendto (SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, sendto, s, buf, len, flags, to, tolen);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
 int mono_w32socket_sendbuffers (SOCKET s, WSABUF *lpBuffers, guint32 dwBufferCount, guint32 *lpNumberOfBytesRecvd, guint32 lpFlags, gpointer lpOverlapped, gpointer lpCompletionRoutine, gboolean blocking)
 {
 	int ret = SOCKET_ERROR;
-	MONO_ENTER_GC_SAFE;
 	ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, WSASend, s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
-	MONO_EXIT_GC_SAFE;
 	return ret;
 }
 
@@ -213,17 +197,12 @@ BOOL mono_w32socket_transmit_file (SOCKET hSocket, gpointer hFile, TRANSMIT_FILE
 {
 	LOGDEBUG (g_message ("%06d - Performing %s TransmitFile () on socket %d", GetCurrentThreadId (), blocking ? "blocking" : "non-blocking", hSocket));
 
-	int error = 0, ret;
-
-	MONO_ENTER_GC_SAFE;
-
+	int error = 0;
 	if (blocking) {
 		OVERLAPPED overlapped = { 0 };
 		overlapped.hEvent = WSACreateEvent ();
-		if (overlapped.hEvent == WSA_INVALID_EVENT) {
-			ret = FALSE;
-			goto done;
-		}
+		if (overlapped.hEvent == WSA_INVALID_EVENT)
+			return FALSE;
 		if (!TransmitFile (hSocket, hFile, 0, 0, &overlapped, lpTransmitBuffers, dwReserved)) {
 			error = WSAGetLastError ();
 			if (error == WSA_IO_PENDING) {
@@ -251,11 +230,7 @@ BOOL mono_w32socket_transmit_file (SOCKET hSocket, gpointer hFile, TRANSMIT_FILE
 		blocking ? "blocking" : "non-blocking", hSocket, error == 0, error));
 	WSASetLastError (error);
 
-	ret = error == 0;
-
-done:
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return error == 0;
 }
 #endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
@@ -268,8 +243,6 @@ mono_w32socket_disconnect (SOCKET sock, gboolean reuse)
 	DWORD output_bytes;
 	gint ret;
 
-	MONO_ENTER_GC_SAFE;
-
 	/* Use the SIO_GET_EXTENSION_FUNCTION_POINTER to determine
 	 * the address of the disconnect method without taking
 	 * a hard dependency on a single provider
@@ -286,54 +259,36 @@ mono_w32socket_disconnect (SOCKET sock, gboolean reuse)
 	GUID disconnect_guid = WSAID_DISCONNECTEX;
 	ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnect_guid, sizeof (GUID), &disconnect, sizeof (LPFN_DISCONNECTEX), &output_bytes, NULL, NULL);
 	if (ret == 0) {
-		if (!disconnect (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0)) {
-			ret = WSAGetLastError ();
-			goto done;
-		}
+		if (!disconnect (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0))
+			return WSAGetLastError ();
 
-		ret = 0;
-		goto done;
+		return 0;
 	}
 
 	GUID transmit_file_guid = WSAID_TRANSMITFILE;
 	ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmit_file_guid, sizeof (GUID), &transmit_file, sizeof (LPFN_TRANSMITFILE), &output_bytes, NULL, NULL);
 	if (ret == 0) {
-		if (!transmit_file (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0))) {
-			ret = WSAGetLastError ();
-			goto done;
-		}
+		if (!transmit_file (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0)))
+			return WSAGetLastError ();
 
-		ret = 0;
-		goto done;
+		return 0;
 	}
 
-	ret = ERROR_NOT_SUPPORTED;
-
-done:
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return ERROR_NOT_SUPPORTED;
 }
 #endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
 gint
 mono_w32socket_set_blocking (SOCKET sock, gboolean blocking)
 {
-	gint ret;
 	gulong nonblocking_long = !blocking;
-	MONO_ENTER_GC_SAFE;
-	ret = ioctlsocket (sock, FIONBIO, &nonblocking_long);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return ioctlsocket (sock, FIONBIO, &nonblocking_long);
 }
 
 gint
 mono_w32socket_get_available (SOCKET sock, guint64 *amount)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = ioctlsocket (sock, FIONREAD, (int*) amount);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return ioctlsocket (sock, FIONREAD, (int*) amount);
 }
 
 void
@@ -360,15 +315,3 @@ ves_icall_System_Net_Sockets_Socket_SupportPortReuse (MonoProtocolType proto, Mo
 	error_init (error);
 	return TRUE;
 }
-
-gboolean
-mono_w32socket_duplicate (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle)
-{
-	gboolean ret;
-
-	MONO_ENTER_GC_SAFE;
-	ret = DuplicateHandle (GetCurrentProcess(), handle, GINT_TO_POINTER(targetProcessId), duplicate_handle, 0, 0, 0x00000002 /* DUPLICATE_SAME_ACCESS */);
-	MONO_EXIT_GC_SAFE;
-
-	return ret;
-}

+ 70 - 68
mono/metadata/w32socket.c

@@ -116,101 +116,61 @@ create_sockaddr_from_handle (MonoObjectHandle saddr_obj, socklen_t *sa_size, gin
 static SOCKET
 mono_w32socket_socket (int domain, int type, int protocol)
 {
-	SOCKET ret;
-	MONO_ENTER_GC_SAFE;
-	ret = WSASocket (domain, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return WSASocket (domain, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
 }
 
 static gint
 mono_w32socket_bind (SOCKET sock, struct sockaddr *addr, socklen_t addrlen)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = bind (sock, addr, addrlen);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return bind (sock, addr, addrlen);
 }
 
 static gint
 mono_w32socket_getpeername (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = getpeername (sock, name, namelen);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return getpeername (sock, name, namelen);
 }
 
 static gint
 mono_w32socket_getsockname (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = getsockname (sock, name, namelen);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return getsockname (sock, name, namelen);
 }
 
 static gint
 mono_w32socket_getsockopt (SOCKET sock, gint level, gint optname, gpointer optval, socklen_t *optlen)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = getsockopt (sock, level, optname, optval, optlen);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return getsockopt (sock, level, optname, optval, optlen);
 }
 
 static gint
 mono_w32socket_setsockopt (SOCKET sock, gint level, gint optname, const gpointer optval, socklen_t optlen)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = setsockopt (sock, level, optname, optval, optlen);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return setsockopt (sock, level, optname, optval, optlen);
 }
 
 static gint
 mono_w32socket_listen (SOCKET sock, gint backlog)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = listen (sock, backlog);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return listen (sock, backlog);
 }
 
 static gint
 mono_w32socket_shutdown (SOCKET sock, gint how)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = shutdown (sock, how);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return shutdown (sock, how);
 }
 
 static gint
 mono_w32socket_ioctl (SOCKET sock, gint32 command, gchar *input, gint inputlen, gchar *output, gint outputlen, glong *written)
 {
-	gint ret;
-	MONO_ENTER_GC_SAFE;
-	ret = WSAIoctl (sock, command, input, inputlen, output, outputlen, written, NULL, NULL);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return WSAIoctl (sock, command, input, inputlen, output, outputlen, written, NULL, NULL);
 }
 
 static gboolean
 mono_w32socket_close (SOCKET sock)
 {
-	gboolean ret;
-	MONO_ENTER_GC_SAFE;
-	ret = CloseHandle (sock);
-	MONO_EXIT_GC_SAFE;
-	return ret;
+	return CloseHandle (sock);
 }
 
 #endif /* HOST_WIN32 */
@@ -785,7 +745,9 @@ ves_icall_System_Net_Sockets_Socket_Close_internal (gsize sock, gint32 *werror,
 	 * polling system does not notify when the socket is closed */
 	mono_threadpool_io_remove_socket (GPOINTER_TO_INT (sock));
 
+	MONO_ENTER_GC_SAFE;
 	mono_w32socket_close ((SOCKET) sock);
+	MONO_EXIT_GC_SAFE;
 }
 
 gint32
@@ -843,7 +805,10 @@ ves_icall_System_Net_Sockets_Socket_Accept_internal (gsize sock, gint32 *werror,
 		return NULL;
 	}
 
+	MONO_ENTER_GC_SAFE;
 	newsock = mono_w32socket_accept (sock, NULL, 0, blocking);
+	MONO_EXIT_GC_SAFE;
+
 	if (newsock == INVALID_SOCKET)
 		*werror = mono_w32socket_get_last_error ();
 
@@ -865,7 +830,12 @@ ves_icall_System_Net_Sockets_Socket_Listen_internal(gsize sock, guint32 backlog,
 	error_init (error);
 	*werror = 0;
 
+	MONO_ENTER_GC_SAFE;
+
 	ret = mono_w32socket_listen (sock, backlog);
+
+	MONO_EXIT_GC_SAFE;
+
 	if (ret == SOCKET_ERROR)
 		*werror = mono_w32socket_get_last_error ();
 }
@@ -1061,7 +1031,12 @@ ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal (gsize sock, gint32 a
 	}
 	sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
 
+	MONO_ENTER_GC_SAFE;
+
 	ret = mono_w32socket_getsockname (sock, (struct sockaddr *)sa, &salen);
+
+	MONO_EXIT_GC_SAFE;
+	
 	if (ret == SOCKET_ERROR) {
 		*werror = mono_w32socket_get_last_error ();
 		if (salen > 128)
@@ -1095,7 +1070,12 @@ ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal (gsize sock, gint32
 	sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
 	/* Note: linux returns just 2 for AF_UNIX. Always. */
 
+	MONO_ENTER_GC_SAFE;
+
 	ret = mono_w32socket_getpeername (sock, (struct sockaddr *)sa, &salen);
+
+	MONO_EXIT_GC_SAFE;
+
 	if (ret == SOCKET_ERROR) {
 		*werror = mono_w32socket_get_last_error ();
 		if (salen > 128)
@@ -1378,7 +1358,10 @@ ves_icall_System_Net_Sockets_Socket_Connect_internal (gsize sock, MonoObjectHand
 		return;
 	}
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_connect (sock, sa, sa_size, blocking);
+	MONO_EXIT_GC_SAFE;
+
 	if (ret == SOCKET_ERROR)
 		*werror = mono_w32socket_get_last_error ();
 
@@ -1406,7 +1389,9 @@ ves_icall_System_Net_Sockets_Socket_Disconnect_internal (gsize sock, MonoBoolean
 		return;
 	}
 
+	MONO_ENTER_GC_SAFE;
 	*werror = mono_w32socket_disconnect (sock, reuse);
+	MONO_EXIT_GC_SAFE;
 
 	mono_thread_info_uninstall_interrupt (&interrupted);
 	if (interrupted)
@@ -1414,20 +1399,6 @@ ves_icall_System_Net_Sockets_Socket_Disconnect_internal (gsize sock, MonoBoolean
 }
 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
 
-MonoBoolean
-ves_icall_System_Net_Sockets_Socket_Duplicate_internal (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle, gint32 *werror, MonoError *error)
-{
-	error_init (error);
-
-	*werror = 0;
-	if (!mono_w32socket_duplicate (handle, targetProcessId, duplicate_handle)) {
-		*werror = mono_w32error_get_last ();
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
 gint32
 ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
 {
@@ -1457,7 +1428,9 @@ ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandl
 	uint32_t gchandle;
 	gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_recv (sock, buf, count, recvflags, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 	
@@ -1502,7 +1475,9 @@ ves_icall_System_Net_Sockets_Socket_Receive_array_internal (gsize sock, MonoArra
 	uint32_t gchandle;
 	WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_recvbuffers (sock, wsabufs, count, &recv, &recvflags, NULL, NULL, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 
@@ -1559,7 +1534,9 @@ ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (gsize sock, MonoArrayH
 	uint32_t gchandle;
 	buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_recvfrom (sock, buf, count, recvflags, sa, &sa_size, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 
@@ -1629,7 +1606,9 @@ ves_icall_System_Net_Sockets_Socket_Send_internal (gsize sock, MonoArrayHandle b
 	uint32_t gchandle;
 	gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_send (sock, buf, count, sendflags, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 
@@ -1674,7 +1653,9 @@ ves_icall_System_Net_Sockets_Socket_Send_array_internal (gsize sock, MonoArrayHa
 	uint32_t gchandle;
 	WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_sendbuffers (sock, wsabufs, count, &sent, sendflags, NULL, NULL, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 
@@ -1734,7 +1715,9 @@ ves_icall_System_Net_Sockets_Socket_SendTo_internal (gsize sock, MonoArrayHandle
 	uint32_t gchandle;
 	gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_sendto (sock, buf, count, sendflags, sa, sa_size, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	mono_gchandle_free (gchandle);
 
@@ -1982,6 +1965,8 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (gsize sock, gi
 		return;
 	}
 
+	MONO_ENTER_GC_SAFE;
+
 	/* No need to deal with MulticastOption names here, because
 	 * you cant getsockopt AddMembership or DropMembership (the
 	 * int getsockopt will error, causing an exception)
@@ -2007,6 +1992,8 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (gsize sock, gi
 		ret = mono_w32socket_getsockopt (sock, system_level, system_name, &val, &valsize);
 	}
 
+	MONO_EXIT_GC_SAFE;
+
 	if (ret == SOCKET_ERROR) {
 		*werror = mono_w32socket_get_last_error ();
 		return;
@@ -2124,8 +2111,12 @@ ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal (gsize sock, gi
 	uint32_t gchandle;
 	guchar *buf = MONO_ARRAY_HANDLE_PIN (byte_val, guchar, 0, &gchandle);
 
+	MONO_ENTER_GC_SAFE;
+
 	ret = mono_w32socket_getsockopt (sock, system_level, system_name, buf, &valsize);
 
+	MONO_EXIT_GC_SAFE;
+
 	mono_gchandle_free (gchandle);
 
 	if (ret == SOCKET_ERROR)
@@ -2434,8 +2425,13 @@ ves_icall_System_Net_Sockets_Socket_Shutdown_internal (gsize sock, gint32 how, g
 		return;
 	}
 
+	MONO_ENTER_GC_SAFE;
+
 	/* Currently, the values for how (recv=0, send=1, both=2) match the BSD API */
 	ret = mono_w32socket_shutdown (sock, how);
+
+	MONO_EXIT_GC_SAFE;
+
 	if (ret == SOCKET_ERROR)
 		*werror = mono_w32socket_get_last_error ();
 
@@ -2480,8 +2476,12 @@ ves_icall_System_Net_Sockets_Socket_IOControl_internal (gsize sock, gint32 code,
 		o_buffer = MONO_ARRAY_HANDLE_PIN (output, gchar, 0, &o_gchandle);
 	}
 
+	MONO_ENTER_GC_SAFE;
+
 	ret = mono_w32socket_ioctl (sock, code, i_buffer, i_len, o_buffer, o_len, &output_bytes);
 
+	MONO_EXIT_GC_SAFE;
+
 	if (i_gchandle)
 		mono_gchandle_free (i_gchandle);
 	if (o_gchandle)
@@ -2709,14 +2709,14 @@ ves_icall_System_Net_Dns_GetHostByAddr_internal (MonoStringHandle addr, MonoStri
 
 	g_free (address);
 
+	MONO_ENTER_GC_SAFE;
+
 	switch (family) {
 	case AF_INET: {
 #if HAVE_SOCKADDR_IN_SIN_LEN
 		saddr.sin_len = sizeof (saddr);
 #endif
-		MONO_ENTER_GC_SAFE;
 		ret = getnameinfo ((struct sockaddr*)&saddr, sizeof (saddr), hostname, sizeof (hostname), NULL, 0, 0) == 0;
-		MONO_EXIT_GC_SAFE;
 		break;
 	}
 #ifdef HAVE_STRUCT_SOCKADDR_IN6
@@ -2724,9 +2724,7 @@ ves_icall_System_Net_Dns_GetHostByAddr_internal (MonoStringHandle addr, MonoStri
 #if HAVE_SOCKADDR_IN6_SIN_LEN
 		saddr6.sin6_len = sizeof (saddr6);
 #endif
-		MONO_ENTER_GC_SAFE;
 		ret = getnameinfo ((struct sockaddr*)&saddr6, sizeof (saddr6), hostname, sizeof (hostname), NULL, 0, 0) == 0;
-		MONO_EXIT_GC_SAFE;
 		break;
 	}
 #endif
@@ -2734,6 +2732,8 @@ ves_icall_System_Net_Dns_GetHostByAddr_internal (MonoStringHandle addr, MonoStri
 		g_assert_not_reached ();
 	}
 
+	MONO_EXIT_GC_SAFE;
+
 	if (!ret)
 		return FALSE;
 
@@ -2807,7 +2807,9 @@ ves_icall_System_Net_Sockets_Socket_SendFile_internal (gsize sock, MonoStringHan
 		buffers.TailLength = mono_array_handle_length (post_buffer);
 	}
 
+	MONO_ENTER_GC_SAFE;
 	ret = mono_w32socket_transmit_file (sock, file, &buffers, flags, blocking);
+	MONO_EXIT_GC_SAFE;
 
 	if (pre_buffer_gchandle)
 		mono_gchandle_free (pre_buffer_gchandle);

+ 0 - 3
mono/metadata/w32socket.h

@@ -278,9 +278,6 @@ ves_icall_System_Net_Sockets_Socket_Poll_internal (gsize sock, gint mode, gint t
 void
 ves_icall_System_Net_Sockets_Socket_Disconnect_internal (gsize sock, MonoBoolean reuse, gint32 *werror, MonoError *error);
 
-MonoBoolean
-ves_icall_System_Net_Sockets_Socket_Duplicate_internal (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle, gint32 *werror, MonoError *error);
-
 gboolean
 ves_icall_System_Net_Sockets_Socket_SendFile_internal (gsize sock, MonoStringHandle filename,
 						       MonoArrayHandle pre_buffer, MonoArrayHandle post_buffer,

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff