public void Start() { ifStats(s => s.Reset()); // configure the ThreadPool // TODO: Numbers may need serious adjustment var tps = Settings.ThreadPool; ThreadPool.SetMaxThreads(tps.MaxThreads, tps.MaxIOThreads); ThreadPool.SetMinThreads(tps.MinThreads, tps.MinIOThreads); // setup the request processing loop _stopEvent = new ManualResetEvent(false); _processorCounter = new Counter(0); _listenerCounter = new Semaphore( Settings.ListenerThreads, Settings.ListenerThreads); // Foreground thread prevents application from terminating // we don't want the app to end until the server is stopped _spawnThread = new Thread(spawnLoop) { Priority = ThreadPriority.AboveNormal, IsBackground = false, }; _listener = new HttpListener(); foreach (var rawHost in Settings.Hosts) { var host = rawHost; if (!rawHost.StartsWith("http")) host = "http://" + host; if (!rawHost.EndsWith("/")) host = host + "/"; _listener.Prefixes.Add(host); } // fire up the server _spawnThread.Start(); IsServing = true; }
public void Stop() { if (!IsServing) return; // 1. Signal everything to begin shutting down _stopEvent.Set(); // 2. Stop the main spawn thread first. _spawnThread.Join(); // 3. Stops any future listener from starting. _listener.Abort(); // 4. Wait until all started listeners stop for (var i = 0; i < Settings.ListenerThreads; i++) _listenerCounter.WaitOne(); // 5. Wait until all request processors have stopped _processorCounter.WaitForZero(); // All threads are terminated by this point _processorCounter = null; _listenerCounter = null; _spawnThread = null; _listener = null; IsServing = false; }