* Makefile.am: Build `docs` after `runtime`, so that it can depend
[mono.git] / mcs / class / System / Test / System.Net / SocketResponder.cs
index 47f5409db2f684e4fc72f199252714b18150b547..07525a78db380949e71c4a938884c1a268439479 100644 (file)
@@ -1,5 +1,5 @@
 //
-// SocketResponsder.cs - Utility class for tests that require a listener
+// SocketResponder.cs - Utility class for tests that require a listener
 //
 // Author:
 //     Gert Driesen (drieseng@users.sourceforge.net)
@@ -34,55 +34,89 @@ using System.Net.Sockets;
 using System.Text;
 using System.Threading;
 
-public delegate byte[] SocketRequestHandler (Socket socket);
-
-public class SocketResponder : IDisposable
+namespace MonoTests.System.Net
 {
-       private TcpListener tcpListener;
-       private readonly IPEndPoint _localEndPoint;
-       private Thread listenThread;
-       private SocketRequestHandler _requestHandler;
+       public delegate byte [] SocketRequestHandler (Socket socket);
 
-       public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
+       public class SocketResponder : IDisposable
        {
-               _localEndPoint = localEP;
-               _requestHandler = requestHandler;
-       }
+               private TcpListener tcpListener;
+               private readonly IPEndPoint _localEndPoint;
+               private Thread listenThread;
+               private SocketRequestHandler _requestHandler;
+               private bool _stopped = true;
+               private readonly object _syncRoot = new object ();
 
-       public IPEndPoint LocalEndPoint
-       {
-               get { return _localEndPoint; }
-       }
+               private const int SOCKET_CLOSED = 10004;
 
-       public void Dispose ()
-       {
-               Stop ();
-       }
+               public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
+               {
+                       _localEndPoint = localEP;
+                       _requestHandler = requestHandler;
+               }
 
-       public void Start ()
-       {
-               tcpListener = new TcpListener (LocalEndPoint);
-               tcpListener.Start ();
-               listenThread = new Thread (new ThreadStart (Listen));
-               listenThread.Start ();
-       }
+               public IPEndPoint LocalEndPoint
+               {
+                       get { return _localEndPoint; }
+               }
 
-       public void Stop ()
-       {
-               if (tcpListener != null)
-                       tcpListener.Stop ();
+               public void Dispose ()
+               {
+                       Stop ();
+               }
 
-               try {
-                       if (listenThread != null && listenThread.ThreadState == ThreadState.Running) {
-                               listenThread.Abort ();
+               public bool IsStopped
+               {
+                       get
+                       {
+                               lock (_syncRoot) {
+                                       return _stopped;
+                               }
                        }
-               } catch {
                }
-       }
 
-       private void Listen ()
-       {
-               Socket socket = tcpListener.AcceptSocket ();
-               socket.Send(_requestHandler(socket));
+               public void Start ()
+               {
+                       lock (_syncRoot) {
+                               if (!_stopped)
+                                       return;
+                               _stopped = false;
+                               listenThread = new Thread (new ThreadStart (Listen));
+                               listenThread.Start ();
+                               Thread.Sleep (20); // allow listener to start
+                       }
+               }
+
+               public void Stop ()
+               {
+                       lock (_syncRoot) {
+                               if (_stopped)
+                                       return;
+                               _stopped = true;
+                               if (tcpListener != null) {
+                                       tcpListener.Stop ();
+                                       tcpListener = null;
+                               }
+                       }
+               }
+
+               private void Listen ()
+               {
+                       tcpListener = new TcpListener (LocalEndPoint);
+                       tcpListener.Start ();
+                       while (!_stopped) {
+                               try {
+                                       Socket socket = tcpListener.AcceptSocket ();
+                                       socket.Send (_requestHandler (socket));
+                                       socket.Shutdown (SocketShutdown.Send);
+                                       Thread.Sleep (500);
+                                       socket.Close ();
+                               } catch (SocketException ex) {
+                                       // ignore interruption of blocking call
+                                       if (ex.ErrorCode != SOCKET_CLOSED)
+                                               throw;
+                               }
+                       }
+               }
        }
 }