/// <summary> /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.Runner.RunnerInstance"/> class. /// </summary> /// <param name="wrapper">The wrapper used to process requests.</param> /// <param name="address">The address to listen on</param> /// <param name="port">The port to listen on.</param> /// <param name="usessl">If set to <c>true</c> use ssl.</param> /// <param name="config">The server configuration.</param> public RunnerInstance(IAppDomainWrappedRunner wrapper, string address, int port, bool usessl, ServerConfig config) { FieldInfo safe_handle_field = null; var monoRuntime = Type.GetType("Mono.Runtime"); var monoVersion = new Version(0, 0); if (monoRuntime != null) { var displayName = monoRuntime.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static); if (displayName != null) { var displayString = (displayName.Invoke(null, null) as string) ?? string.Empty; var versionstring = displayString.Split(' ').FirstOrDefault(); Version.TryParse(versionstring, out monoVersion); } } // This bug is supposedly fixed in mono, but seems to have issues still if (monoRuntime != null /* && monoVersion <= new Version(4, 6, 2) */) { safe_handle_field = typeof(Socket).GetField("safe_handle", BindingFlags.NonPublic | BindingFlags.Instance); if (safe_handle_field == null) { safe_handle_field = typeof(Socket).GetField("m_Handle", BindingFlags.NonPublic | BindingFlags.Instance); } } var pid = System.Diagnostics.Process.GetCurrentProcess().Id; if (safe_handle_field == null) { m_handler = (socket, addr, id) => { Wrapper.HandleRequest(socket.DuplicateAndClose(pid), addr, id); }; } else { m_handler = (socket, addr, id) => { // Bugfix workaround for: https://bugzilla.xamarin.com/show_bug.cgi?id=47425 var prev_sh = safe_handle_field.GetValue(socket); var s = socket.DuplicateAndClose(pid); if (prev_sh != null) { GC.SuppressFinalize(prev_sh); } Wrapper.HandleRequest(s, addr, id); }; } RestartAsync(wrapper, address, port, usessl, config); }
/// <summary> /// Restarts this instance /// </summary> /// <param name="address">The address to listen on</param> /// <param name="port">The port to listen on.</param> /// <param name="usessl">If set to <c>true</c> use ssl.</param> /// <param name="config">The server configuration.</param> public async Task RestartAsync(IAppDomainWrappedRunner wrapper, string address, int port, bool usessl, ServerConfig config) { if (RunnerTask != null) { await StopAsync(); } m_token = new CancellationTokenSource(); Port = port; Config = config; UseSSL = usessl; Wrapper = wrapper; Address = address; ShouldStop = false; RunnerTask = HttpServer.ListenToSocketAsync( ParseUtil.ParseEndPoint(address, port), usessl, m_token.Token, config, m_handler ); }