void OnAccept(IAsyncResult ares) { Logger.Write(LogLevel.Debug, Strings.Server_Accepting); T connection = default(T); bool created = false; lock (accept_lock) { accepting = false; } try { try { Socket accepted = listen_socket.EndAccept(ares); if (stopped) { Logger.Write(LogLevel.Debug, "Shutting down..."); accepted.Close(); return; } connection = serverCallback.OnAccept(accepted); created = true; lock (connections_lock) connections.Add(connection); connection.RequestReceived += RequestReceived; } catch (System.Net.Sockets.SocketException e) { Logger.Write(LogLevel.Error, Strings.Server_AcceptFailed, e.Message); if (e.ErrorCode == 10022) { Stop(); } } catch (ObjectDisposedException) { Logger.Write(LogLevel.Debug, Strings.Server_ConnectionClosed); return; // Already done (e.g., shutdown) } if (CanAccept) { BeginAccept(); } } catch (Exception e) { Logger.Write(LogLevel.Error, Strings.Server_AcceptFailed, e.Message); throw; } if (!created) { return; } try { connection.Run(); } catch (Exception e) { Logger.Write(LogLevel.Error, Strings.Server_ConnectionFailed); Logger.Write(e); try { // Upon catastrophic failure, forcefully stop // all remaining connection activity, since no // specific error-handling kicked in to rescue // the connection or its requests and the // connection's main loop has now terminated. // This prevents abandoned FastCGI connections // from staying open indefinitely. EndConnection(connection); Logger.Write(LogLevel.Debug, Strings.Server_ConnectionClosed); } catch { // Ignore at this point -- too bad } } }