+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.
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)
}
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) {
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;