[Mono-dev] [PATCH] TcpChannel hang on Windows.

Kornél Pál kornelpal at gmail.com
Wed Dec 17 16:44:27 EST 2008


You did a great job at implementing support for this functionality but 
I'm afraid that this very functionality is not supported by MS.NET either.

The difference seems to be in terminating the background threads on exit 
rather that in socket handling.

Please see the attached test case that hangs on MS.NET as well. I 
haven't try your patch but I believe that it would not cause this test 
case to hang either.


Bill Holmes wrote:
> Hi,
> 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.
> -bill
> 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.
> ------------------------------------------------------------------------
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: BlockingAccept.cs
Url: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20081217/165ab667/attachment.pl 

More information about the Mono-devel-list mailing list