private TcpListener tcpListener;
private readonly IPEndPoint _localEndPoint;
private Thread listenThread;
+ private Socket listenSocket;
private SocketRequestHandler _requestHandler;
- private bool _stopped = true;
+ private int _state = 0;
private readonly object _syncRoot = new object ();
private const int SOCKET_CLOSED = 10004;
private const int SOCKET_INVALID_ARGS = 10022;
+ private const int STATE_UNINITIALIZED = 0;
+ private const int STATE_RUNNING = 1;
+ private const int STATE_STOPPED = 2;
+
public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
{
_localEndPoint = localEP;
get
{
lock (_syncRoot) {
- return _stopped;
+ return _state != STATE_RUNNING;
}
}
}
public void Start ()
{
lock (_syncRoot) {
- if (!_stopped)
- return;
- _stopped = false;
+ if (_state != STATE_UNINITIALIZED)
+ throw new InvalidOperationException ("cannot restart SocketResponder");
+ _state = STATE_RUNNING;
tcpListener = new TcpListener (LocalEndPoint);
tcpListener.Start ();
listenThread = new Thread (new ThreadStart (Listen));
public void Stop ()
{
lock (_syncRoot) {
- if (_stopped)
+ if (_state != STATE_RUNNING)
return;
- _stopped = true;
+ _state = STATE_STOPPED;
if (tcpListener != null) {
tcpListener.Stop ();
tcpListener = null;
+ if (listenSocket != null)
+ listenSocket.Close ();
+#if MONO_FEATURE_THREAD_ABORT
listenThread.Abort ();
+#else
+ listenThread.Interrupt ();
+#endif
listenThread.Join ();
listenThread = null;
Thread.Sleep (50);
private void Listen ()
{
- while (!_stopped) {
- Socket socket = null;
+ while (_state == STATE_RUNNING) {
+ listenSocket = null;
try {
- socket = tcpListener.AcceptSocket ();
- socket.Send (_requestHandler (socket));
+ listenSocket = tcpListener.AcceptSocket ();
+ listenSocket.Send (_requestHandler (listenSocket));
try {
- socket.Shutdown (SocketShutdown.Receive);
- socket.Shutdown (SocketShutdown.Send);
+ listenSocket.Shutdown (SocketShutdown.Receive);
+ listenSocket.Shutdown (SocketShutdown.Send);
} catch {
}
} catch (SocketException ex) {
// ignore interruption of blocking call
- if (ex.ErrorCode != SOCKET_CLOSED && ex.ErrorCode != SOCKET_INVALID_ARGS)
+ if (ex.ErrorCode != SOCKET_CLOSED && ex.ErrorCode != SOCKET_INVALID_ARGS && _state != STATE_STOPPED)
+ throw;
+ } catch (ObjectDisposedException ex) {
+ Console.WriteLine (ex);
+ if (_state != STATE_STOPPED)
throw;
+#if !MONO_FEATURE_THREAD_ABORT
+ } catch (ThreadInterruptedException) {
+ break;
+#endif
#if MOBILE
} catch (InvalidOperationException ex) {
// This breaks some tests running on Android. The problem is that the stack trace
Console.WriteLine (ex);
#endif
} finally {
+#if MONO_FEATURE_THREAD_ABORT
Thread.Sleep (500);
- if (socket != null)
- socket.Close ();
+#else
+ try {
+ Thread.Sleep (500);
+ } catch (ThreadInterruptedException) {
+ // nothing to do
+ }
+#endif
+ if (listenSocket != null)
+ listenSocket.Close ();
}
}
}