Author: gonzalo
Date: 2005-06-01 10:10:17 -0400 (Wed, 01 Jun 2005)
New Revision: 45299
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/icall.c
trunk/mono/mono/metadata/socket-io.c
trunk/mono/mono/metadata/socket-io.h
Log:
2005-06-01 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
* icall.c:
* socket-io.[ch]: Select_internal uses poll() now when available, thus
removing the 1024 limit from select(). Runtime part of the fix for
bug #71203.
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2005-06-01 14:10:13 UTC (rev 45298)
+++ trunk/mono/mono/metadata/ChangeLog 2005-06-01 14:10:17 UTC (rev 45299)
@@ -1,3 +1,10 @@
+2005-06-01 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
+
+ * icall.c:
+ * socket-io.[ch]: Select_internal uses poll() now when available, thus
+ removing the 1024 limit from select(). Runtime part of the fix for
+ bug #71203.
+
2005-05-30 Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
* socket-io.c: when resolving the addresses for the same
Modified: trunk/mono/mono/metadata/icall.c
===================================================================
--- trunk/mono/mono/metadata/icall.c 2005-06-01 14:10:13 UTC (rev 45298)
+++ trunk/mono/mono/metadata/icall.c 2005-06-01 14:10:17 UTC (rev 45299)
@@ -6310,7 +6310,7 @@
{"Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)",
ves_icall_System_Net_Sockets_Socket_Receive_internal},
{"RecvFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)",
ves_icall_System_Net_Sockets_Socket_RecvFrom_internal},
{"RemoteEndPoint_internal(intptr,int&)",
ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal},
-
{"Select_internal(System.Net.Sockets.Socket[]&,System.Net.Sockets.Socket[]&,System.Net.Sockets.Socket[]&,int,int&)",
ves_icall_System_Net_Sockets_Socket_Select_internal},
+ {"Select_internal(System.Net.Sockets.Socket[]&,int,int&)",
ves_icall_System_Net_Sockets_Socket_Select_internal},
{"SendTo_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&)",
ves_icall_System_Net_Sockets_Socket_SendTo_internal},
{"Send_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)",
ves_icall_System_Net_Sockets_Socket_Send_internal},
{"SetSocketOption_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object,byte[],int,int&)",
ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal},
Modified: trunk/mono/mono/metadata/socket-io.c
===================================================================
--- trunk/mono/mono/metadata/socket-io.c 2005-06-01 14:10:13 UTC (rev
45298)
+++ trunk/mono/mono/metadata/socket-io.c 2005-06-01 14:10:17 UTC (rev
45299)
@@ -1,10 +1,12 @@
/*
* socket-io.c: Socket IO internal calls
*
- * Author:
+ * Authors:
* Dick Porter ([EMAIL PROTECTED])
+ * Gonzalo Paniagua Javier ([EMAIL PROTECTED])
*
* (C) 2001 Ximian, Inc.
+ * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
*/
#include <config.h>
@@ -22,6 +24,7 @@
#include <mono/metadata/assembly.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/threads.h>
+#include <mono/utils/mono-poll.h>
/* FIXME change this code to not mess so much with the internals */
#include <mono/metadata/class-internals.h>
#include <mono/metadata/threadpool-internals.h>
@@ -1273,165 +1276,124 @@
return(sock);
}
-void ves_icall_System_Net_Sockets_Socket_Select_internal(MonoArray
**read_socks, MonoArray **write_socks, MonoArray **err_socks, gint32 timeout,
gint32 *error)
+#define POLL_ERRORS (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)
+void ves_icall_System_Net_Sockets_Socket_Select_internal(MonoArray **sockets,
gint32 timeout, gint32 *error)
{
- fd_set readfds, writefds, errfds;
- fd_set *readptr = NULL, *writeptr = NULL, *errptr = NULL;
- struct timeval tv;
- div_t divvy;
+ MonoThread *thread = NULL;
+ MonoObject *obj;
+ mono_pollfd *pfds;
+ int nfds, idx;
int ret;
- int readarrsize = 0, writearrsize = 0, errarrsize = 0;
- MonoDomain *domain=mono_domain_get();
+ int i, count;
+ int mode;
MonoClass *sock_arr_class;
MonoArray *socks;
- int count;
- int i;
- SOCKET handle;
+ time_t start;
MONO_ARCH_SAVE_REGS;
- if (*read_socks)
- readarrsize=mono_array_length(*read_socks);
-
- *error = 0;
-
- if(readarrsize>FD_SETSIZE) {
- *error = WSAEFAULT;
- return;
- }
-
- if (readarrsize) {
- readptr = &readfds;
- FD_ZERO(&readfds);
- for(i=0; i<readarrsize; i++) {
- handle = Socket_to_SOCKET(mono_array_get(*read_socks,
MonoObject *, i));
- _wapi_FD_SET(handle, &readfds);
+ /* *sockets -> READ, null, WRITE, null, ERROR, null */
+ count = mono_array_length (*sockets);
+ nfds = count - 3; /* NULL separators */
+ pfds = g_new0 (mono_pollfd, nfds);
+ mode = idx = 0;
+ for (i = 0; i < count; i++) {
+ obj = mono_array_get (*sockets, MonoObject *, i);
+ if (obj == NULL) {
+ mode++;
+ continue;
}
- }
-
- if (*write_socks)
- writearrsize=mono_array_length(*write_socks);
- if(writearrsize>FD_SETSIZE) {
- *error = WSAEFAULT;
- return;
+ pfds [idx].fd = GPOINTER_TO_INT (Socket_to_SOCKET (obj));
+ pfds [idx].events = (mode == 0) ? MONO_POLLIN : (mode == 1) ?
MONO_POLLOUT : POLL_ERRORS;
+ idx++;
}
-
- if (writearrsize) {
- writeptr = &writefds;
- FD_ZERO(&writefds);
- for(i=0; i<writearrsize; i++) {
- handle = Socket_to_SOCKET(mono_array_get(*write_socks,
MonoObject *, i));
- _wapi_FD_SET(handle, &writefds);
- }
- }
-
- if (*err_socks)
- errarrsize=mono_array_length(*err_socks);
- if(errarrsize>FD_SETSIZE) {
- *error = WSAEFAULT;
- return;
- }
-
- if (errarrsize) {
- errptr = &errfds;
- FD_ZERO(&errfds);
- for(i=0; i<errarrsize; i++) {
- handle = Socket_to_SOCKET(mono_array_get(*err_socks,
MonoObject *, i));
- _wapi_FD_SET(handle, &errfds);
+ timeout = (timeout >= 0) ? (timeout / 1000) : -1;
+ start = time (NULL);
+ do {
+ *error = 0;
+ ret = mono_poll (pfds, nfds, timeout);
+ if (timeout > 0 && ret < 0) {
+ int err = errno;
+ int sec = time (NULL) - start;
+
+ timeout -= sec * 1000;
+ if (timeout < 0)
+ timeout = 0;
+ errno = err;
}
- }
- /* Negative timeout meaning block until ready is only
- * specified in Poll, not Select
- */
+ /* FIXME: is this ok for non-windows Thread.Abort support?
+ if (ret == -1 && errno == EINTR) {
+ int leave = 0;
+ if (thread == NULL)
+ thread = mono_thread_current ();
- divvy = div (timeout, 1000000);
-
- do {
- if(timeout>=0) {
- tv.tv_sec=divvy.quot;
- tv.tv_usec=divvy.rem;
-
- ret = _wapi_select (0, readptr, writeptr, errptr, &tv);
- } else {
- ret = _wapi_select (0, readptr, writeptr, errptr, NULL);
+ mono_monitor_enter (thread->synch_lock);
+ leave = ((thread->state & ThreadState_AbortRequested)
!= 0 ||
+ (thread->state & ThreadState_StopRequested) !=
0)
+ mono_monitor_exit (thread->synch_lock);
+ if (leave != 0) {
+ g_free (pfds);
+ *sockets = NULL;
+ return;
+ }
+ errno = EINTR;
}
- } while ((ret==SOCKET_ERROR) && (WSAGetLastError() == WSAEINTR));
+ */
+#ifdef PLATFORM_WIN32
+ } while (ret == -1 && WSAGetLastError() == WSAEINTR);
+#else
+ } while (ret == -1 && errno == EINTR);
+#endif
- if(ret==SOCKET_ERROR) {
+ if (ret == -1) {
+#ifdef PLATFORM_WIN32
*error = WSAGetLastError ();
+#else
+ *error = errno_to_WSA (errno, __func__);
+#endif
+ g_free (pfds);
return;
}
- if (readarrsize) {
- sock_arr_class=((MonoObject *)*read_socks)->vtable->klass;
-
- count=0;
- for(i=0; i<readarrsize; i++) {
-
if(_wapi_FD_ISSET(Socket_to_SOCKET(mono_array_get(*read_socks, MonoObject *,
i)), &readfds)) {
- count++;
- }
- }
- socks=mono_array_new_full(domain, sock_arr_class, &count, NULL);
- count=0;
- for(i=0; i<readarrsize; i++) {
- MonoObject *sock=mono_array_get(*read_socks, MonoObject
*, i);
-
- if(_wapi_FD_ISSET(Socket_to_SOCKET(sock), &readfds)) {
- mono_array_set(socks, MonoObject *, count,
sock);
- count++;
- }
- }
- *read_socks=socks;
- } else {
- *read_socks = NULL;
+ if (ret == 0) {
+ g_free (pfds);
+ *sockets = NULL;
+ return;
}
- if (writearrsize) {
- sock_arr_class=((MonoObject *)*write_socks)->vtable->klass;
- count=0;
- for(i=0; i<writearrsize; i++) {
-
if(_wapi_FD_ISSET(Socket_to_SOCKET(mono_array_get(*write_socks, MonoObject *,
i)), &writefds)) {
- count++;
- }
+ sock_arr_class= ((MonoObject *)*sockets)->vtable->klass;
+ ret += 3; /* space for the NULL delimiters */
+ socks = mono_array_new_full (mono_domain_get (), sock_arr_class, &ret,
NULL);
+ ret -= 3;
+ mode = idx = 0;
+ for (i = 0; i < count && ret > 0; i++) {
+ mono_pollfd *pfd;
+
+ obj = mono_array_get (*sockets, MonoObject *, i);
+ if (obj == NULL) {
+ mode++;
+ continue;
}
- socks=mono_array_new_full(domain, sock_arr_class, &count, NULL);
- count=0;
- for(i=0; i<writearrsize; i++) {
- MonoObject *sock=mono_array_get(*write_socks,
MonoObject *, i);
-
- if(_wapi_FD_ISSET(Socket_to_SOCKET(sock), &writefds)) {
- mono_array_set(socks, MonoObject *, count,
sock);
- count++;
- }
- }
- *write_socks=socks;
- } else {
- *write_socks = NULL;
- }
- if (errarrsize) {
- sock_arr_class=((MonoObject *)*err_socks)->vtable->klass;
- count=0;
- for(i=0; i<errarrsize; i++) {
-
if(_wapi_FD_ISSET(Socket_to_SOCKET(mono_array_get(*err_socks, MonoObject *,
i)), &errfds)) {
- count++;
- }
+ pfd = &pfds [i - mode];
+ if (pfd->revents == 0)
+ continue;
+
+ ret--;
+ if (mode == 0 && (pfd->revents & (MONO_POLLIN | POLL_ERRORS))
!= 0) {
+ mono_array_set (socks, MonoObject *, idx++, obj);
+ } else if (mode == 1 && (pfd->revents & (MONO_POLLOUT |
POLL_ERRORS)) != 0) {
+ mono_array_set (socks, MonoObject *, idx++, obj);
+ } else if ((pfd->revents & POLL_ERRORS) != 0) {
+ mono_array_set (socks, MonoObject *, idx++, obj);
}
- socks=mono_array_new_full(domain, sock_arr_class, &count, NULL);
- count=0;
- for(i=0; i<errarrsize; i++) {
- MonoObject *sock=mono_array_get(*err_socks, MonoObject
*, i);
-
- if(_wapi_FD_ISSET(Socket_to_SOCKET(sock), &errfds)) {
- mono_array_set(socks, MonoObject *, count,
sock);
- count++;
- }
- }
- *err_socks=socks;
}
+
+ *sockets = socks;
+ g_free (pfds);
}
static MonoObject* int_to_object (MonoDomain *domain, int val)
Modified: trunk/mono/mono/metadata/socket-io.h
===================================================================
--- trunk/mono/mono/metadata/socket-io.h 2005-06-01 14:10:13 UTC (rev
45298)
+++ trunk/mono/mono/metadata/socket-io.h 2005-06-01 14:10:17 UTC (rev
45299)
@@ -184,7 +184,7 @@
extern gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET
sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject
**sockaddr, gint32 *error);
extern gint32 ves_icall_System_Net_Sockets_Socket_Send_internal(SOCKET sock,
MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error);
extern gint32 ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock,
MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject
*sockaddr, gint32 *error);
-extern void ves_icall_System_Net_Sockets_Socket_Select_internal(MonoArray
**read_socks, MonoArray **write_socks, MonoArray **err_socks, gint32 timeout,
gint32 *error);
+extern void ves_icall_System_Net_Sockets_Socket_Select_internal(MonoArray
**sockets, gint32 timeout, gint32 *error);
extern void ves_icall_System_Net_Sockets_Socket_Shutdown_internal(SOCKET sock,
gint32 how, gint32 *error);
extern void
ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET sock,
gint32 level, gint32 name, MonoObject **obj_val, gint32 *error);
extern void
ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal(SOCKET sock,
gint32 level, gint32 name, MonoArray **byte_val, gint32 *error);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches