2008-12-30 Bill Holmes <billholmes54@gmail.com>
authorBill Holmes <holmes@mono-cvs.ximian.com>
Tue, 30 Dec 2008 16:58:15 +0000 (16:58 -0000)
committerBill Holmes <holmes@mono-cvs.ximian.com>
Tue, 30 Dec 2008 16:58:15 +0000 (16:58 -0000)
* socket-io.h : Changing the signature of
  ves_icall_System_Net_Sockets_Socket_Accept_internal to pass
  the blocking state.

* icall-def.h :  Changing the signature of
  System.Net.Sockets.Socket.Accept_internal to pass the blocking state.

* socket-io.c (ves_icall_System_Net_Sockets_Socket_Accept_internal) :
  For Windows only.  Avoid blocking when calling accept by
  querying for a connection via select.  The loop also queries
  the thread state every 1000 micro seconds for the thread
  stop state.  This will avoid the process hanging on shutdown
  when using a TcpChannel that is never connected to.

* Socket.cs (Accept_internal) :  Changing the signature to pass
  the blocking state.

Code is contributed under MIT/X11 license.

svn path=/trunk/mono/; revision=122252

mono/metadata/ChangeLog
mono/metadata/icall-def.h
mono/metadata/socket-io.c
mono/metadata/socket-io.h

index a24840b9378e866e7392612062fd3d407e987bac..34a362c5433b8cee6284ad999a76fcaa1fe19202 100644 (file)
@@ -1,3 +1,21 @@
+2008-12-30  Bill Holmes  <billholmes54@gmail.com>
+
+       * socket-io.h : Changing the signature of
+         ves_icall_System_Net_Sockets_Socket_Accept_internal to pass
+         the blocking state.
+
+       * icall-def.h :  Changing the signature of
+         System.Net.Sockets.Socket.Accept_internal to pass the blocking state.
+
+       * socket-io.c (ves_icall_System_Net_Sockets_Socket_Accept_internal) :
+         For Windows only.  Avoid blocking when calling accept by
+         querying for a connection via select.  The loop also queries
+         the thread state every 1000 micro seconds for the thread
+         stop state.  This will avoid the process hanging on shutdown
+         when using a TcpChannel that is never connected to.
+
+       Code is contributed under MIT/X11 license.
+
 2008-12-30  Marek Safar  <marek.safar@gmail.com>
 
        * tabledefs.h: Add METHOD_ATTRIBUTE_CHECK_ACCESS_ON_OVERRIDE.
index 71a33b82f3f13a4962fcfc344efbdc407cf89e9c..c27bbcf7333be5bafd03257a3630020348c5c3fa 100644 (file)
@@ -402,7 +402,7 @@ ICALL(NDNS_2, "GetHostByName_internal(string,string&,string[]&,string[]&)", ves_
 ICALL(NDNS_3, "GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal)
 
 ICALL_TYPE(SOCK, "System.Net.Sockets.Socket", SOCK_1)
-ICALL(SOCK_1, "Accept_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Accept_internal)
+ICALL(SOCK_1, "Accept_internal(intptr,int&,bool)", ves_icall_System_Net_Sockets_Socket_Accept_internal)
 ICALL(SOCK_2, "Available_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Available_internal)
 ICALL(SOCK_3, "Bind_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Bind_internal)
 ICALL(SOCK_4, "Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal)
index 3720704f84ab4ed3204438ce1302c22d9232cac2..8cab54e66c6c34654297cce3b8a8fecb45ac410a 100644 (file)
@@ -811,13 +811,41 @@ void ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock,
 }
 
 gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock,
-                                                            gint32 *error)
+                                                            gint32 *error,
+                                                            gboolean blocking)
 {
        SOCKET newsock;
        
        MONO_ARCH_SAVE_REGS;
 
        *error = 0;
+
+#ifdef PLATFORM_WIN32
+       /* Several applications are getting stuck during shutdown on Windows 
+        * when an accept call is on a background thread.
+        * 
+        */
+       if (blocking) {
+               MonoThread* curthread = mono_thread_current ();
+
+               if (curthread) {
+                       for (;;) {
+                               int selectret;
+                               TIMEVAL timeout; 
+                               fd_set readfds;
+                               FD_ZERO (&readfds);
+                               FD_SET(sock, &readfds);
+                               timeout.tv_sec = 0;
+                               timeout.tv_usec = 1000;
+                               selectret = select (0, &readfds, NULL, NULL, &timeout);
+                               if (selectret > 0)
+                                       break;
+                               if (curthread->state & ThreadState_StopRequested)
+                                       return NULL;
+                       }
+               }
+       }
+#endif
        
        newsock = _wapi_accept (sock, NULL, 0);
        if(newsock==INVALID_SOCKET) {
index 26b970b71111c465492e0e820cf1710e00a24e3d..012f91cbc7ea1ca973454e2bfdffa5d254b69115 100644 (file)
@@ -194,7 +194,7 @@ extern void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock, gint
 extern gint32 ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal(void) MONO_INTERNAL;
 extern gint32 ves_icall_System_Net_Sockets_Socket_Available_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;
 extern void ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock, gboolean block, gint32 *error) MONO_INTERNAL;
-extern gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;
+extern gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock, gint32 *error, gboolean blocking) MONO_INTERNAL;
 extern void ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock, guint32 backlog, gint32 *error) MONO_INTERNAL;
 extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;
 extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;