diff --git a/HTTPServer.cs b/HTTPServer.cs index 69b1331..7e73a80 100644 --- a/HTTPServer.cs +++ b/HTTPServer.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; -using ln.http.threads; using System.IO; using System.Text; using ln.http.resources.session; +using ln.logging; +using ln.types.threads; namespace ln.http @@ -19,17 +20,21 @@ namespace ln.http public HttpApplication DefaultApplication { get; set; } + public SessionCache SessionCache { get; set; } + + public bool IsRunning => (currentListenerThreads.Count > 0) || (threadPool.NumThreads > 0); + + + bool shutdown = false; Dictionary tcpListeners = new Dictionary(); Dictionary applications = new Dictionary(); + Dictionary currentListenerThreads = new Dictionary(); + Pool threadPool = new Pool(); - public SessionCache SessionCache { get; set; } - - - public HTTPServer() { SessionCache = new SessionCache(); @@ -64,7 +69,9 @@ namespace ln.http foreach (TcpListener tcpListener in this.tcpListeners.Values) { tcpListener.Start(backlog); - this.threadPool.Enqueue(() => AcceptConnections(tcpListener)); + + Thread listenerThread = new Thread(() => AcceptConnections(tcpListener)); + listenerThread.Start(); } } @@ -74,20 +81,49 @@ namespace ln.http lock (this) { this.shutdown = true; + + foreach (TcpListener tcpListener in tcpListeners.Values) + { + tcpListener.Stop(); + } + + threadPool.NumThreads = 0; + + while (IsRunning) + { + Thread.Sleep(50); + } } } private void AcceptConnections(TcpListener tcpListener) { - while (true) + lock (this) { - lock(this) + if (currentListenerThreads.ContainsKey(tcpListener)) { - if (this.shutdown) { - return; - } + throw new Exception("HTTP listener thread already running"); } - AcceptConnection(tcpListener); + currentListenerThreads.Add(tcpListener, Thread.CurrentThread); + } + + try + { + + while (!this.shutdown) + { + AcceptConnection(tcpListener); + } + + } catch (Exception e) + { + Logging.Log(LogLevel.ERROR, "HTTPServer: Listener thread caught exception {0}",e); + Logging.Log(e); + } + + lock (this) + { + currentListenerThreads.Remove(tcpListener); } } diff --git a/ln.http.csproj b/ln.http.csproj index 5cf3101..47add93 100644 --- a/ln.http.csproj +++ b/ln.http.csproj @@ -34,7 +34,6 @@ - @@ -50,8 +49,17 @@ - + + + {D471A566-9FB6-41B2-A777-3C32874ECD0E} + ln.logging + + + {8D9AB9A5-E513-4BA7-A450-534F6456BF28} + ln.types + + \ No newline at end of file diff --git a/threads/Pool.cs b/threads/Pool.cs deleted file mode 100644 index 9c30c28..0000000 --- a/threads/Pool.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Threading; -using System.Collections.Generic; -namespace ln.http.threads -{ - public delegate void JobDelegate(); - - public class Pool - { - public int Timeout { get; set; } = 15000; - - ISet threads = new HashSet(); - Queue queuedJobs = new Queue(); - HashSet idleThreads = new HashSet(); - - public Pool() - { - } - - private void AllocateThread() - { - Thread thread = new Thread(pool_thread); - thread.Start(); - } - - public void Enqueue(JobDelegate job) - { - lock (this) - { - queuedJobs.Enqueue(job); - - if (idleThreads.Count == 0) - { - AllocateThread(); - } - else - { - Monitor.Pulse(this); - } - } - } - - - private void pool_thread() - { - Thread me = Thread.CurrentThread; - - try - { - JobDelegate job = null; - do - { - lock (this) - { - if (queuedJobs.Count == 0) - { - idleThreads.Add(me); - bool s = Monitor.Wait(this, Timeout); - idleThreads.Remove(me); - if (!s) - break; - } - job = queuedJobs.Dequeue(); - } - - job(); - - } while (true); - - } - catch (Exception e) - { - Console.WriteLine("Exception in worker thread: {0}", e); - } - - lock (this) - { - threads.Remove(me); - } - } - } -}