[Mono-dev] [PATCH] TcpChannel hang on Windows.
billholmes54 at gmail.com
Wed Dec 17 15:03:10 EST 2008
Over the past week I have been asking some of you how to correct a
hang on exit with TcpChannels on Windows. To recap instantiating a
TcpChannel runs a background thread which calls Socket.Accept and
blocks. During shutdown a call to mono_thread_manage executes an APC
on the waiting thread and then (mono_thread_manage) waits for the
blocking thread to exit. The problem is that the APC call does not
cause the accept call to break.
There were a couple of suggestions about how to solve this problem.
Some were specific to accept and others were general patterns
'un-stick' blocking calls in the runtime. I believe that have tried
them all. Some did not work while others caused other complications.
The one I decided on was to call select with a timeout to determine if
a following accept call would succeed immediately. Consider it a peek
on the socket. If the select times out and no connection is present I
check the thread state for StopRequested. (Not Abort intentionally.)
Finally this is an a infinite loop until a connection is present or
the thread is stopped. The loop is only applicable to Windows as I do
not observe a problem on Linux.
One thing that I had to change was the signature to the internal
accept call. I need to know the blocking state of the socket. If a
socket is in blocking mode I can go into the loop. If the socket is
in non-blocking mode I can not use the loop because it will cause the
call to accept to block on a non-blocking socket. The reason I have
to pass it into the internal call is because after much searching I
can not find a way to query the blocking state of a socket. (There is
no ret = fcntl(fd, F_GETFL, 0); on Windows?) If anyone knows how to
query this state let me know and I will be happy to change it.
2008-12-17 Bill Holmes <billholmes54 at gmail.com>
* Socket.cs (Accept_internal) : Changing the signature to pass
the blocking state.
* 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 6268 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20081217/c2fb1a50/attachment-0001.bin
More information about the Mono-devel-list