public Connection OnAccept(Socket socket) { if (socket == null) { throw new ArgumentNullException("socket"); } Logger.Write(LogLevel.Debug, "ChildInfo.OnAccept"); if (Process == null || Process.HasExited) { if (TrySpawn()) { var process = Process; int id = process.Id; Logger.Write(LogLevel.Notice, "Started fastcgi daemon [dynamic] with pid {0} and config file {1}", id, Path.GetFileName(Name)); process.EnableRaisingEvents = true; process.Exited += (sender, e) => Logger.Write(LogLevel.Notice, "Fastcgi daemon [dynamic] with pid {0} exited [it is {1}ly dead]", id, process.HasExited.ToString().ToLowerInvariant()); // Let the daemon start Thread.Sleep(300); } else { throw new Exception("Couldn't spawn child!"); } } else { Logger.Write(LogLevel.Debug, "Recycling child with pid {0}", Process.Id); } Logger.Write(LogLevel.Debug, "Will connect to backend"); var onDemandSocket = new UnixClient(); Logger.Write(LogLevel.Debug, "Connecting to backend on {0}", OnDemandSock); if (OnDemandSock.StartsWith("\\0", StringComparison.Ordinal)) { onDemandSocket.Connect('\0' + OnDemandSock.Substring(2)); } else { Uri uri; if (Uri.TryCreate(OnDemandSock, UriKind.Absolute, out uri)) { onDemandSocket.Connect(uri.PathAndQuery); } else { onDemandSocket.Connect(OnDemandSock); } } SocketPassing.SendTo(onDemandSocket.Client.Handle, socket.Handle); Logger.Write(LogLevel.Debug, "Sent fd {0} via fd {1}", socket.Handle, onDemandSocket.Client.Handle); onDemandSocket.Close(); return(new Connection(socket)); }
public static Process SpawnOndemandChild(string socketFile) { CompatArraySegment <byte>?torelease = null; try { Logger.Write(LogLevel.Debug, "Spawning via the shim {0}", socketFile); var client = new UnixClient(); client.Connect(socketFile); CompatArraySegment <byte> buffer = buffers.ClaimBuffer(); torelease = buffer; int receivedCount; using (NetworkStream socket = client.GetStream()) { socket.Write(spawnString, 0, spawnString.Length); receivedCount = socket.Read(buffer.Array, buffer.Offset, buffer.Count); if (receivedCount < 0) { throw new Exception("Didn't receive the child pid"); } } string received = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, receivedCount); string clean = received.Trim(); int pid; if (!Int32.TryParse(clean, out pid)) { throw new Exception("Couldn't parse the pid \"" + clean + "\""); } if (pid < 0) { throw new Exception("Invalid pid: " + pid); } return(Process.GetProcessById(pid)); } catch (Exception e) { Logger.Write(LogLevel.Error, "Error while talking to the shim for socket file {0}", socketFile); Logger.Write(e); return(null); } finally { if (torelease != null) { buffers.ReturnBuffer(torelease.Value); } } }
protected override Stream RequestStream() { string filename = Environment.GetEnvironmentVariable("OPTIMIZATION_UNIX_SOCKET"); if (filename == null) { return(null); } if (d_client != null) { return(null); } // Open unix socket... d_client = new UnixClient(); try { d_client.Connect(filename); } catch (Exception e) { Console.Error.WriteLine("Could not open unix socket: " + e.Message); return(null); } int ctx = 0; while (!d_client.GetStream().DataAvailable&& ctx < 10) { System.Threading.Thread.Sleep(100); ++ctx; } byte[] all = new byte[] {}; while (d_client.GetStream().DataAvailable) { byte[] buffer = new byte[1024]; int ret; try { ret = d_client.GetStream().Read(buffer, 0, buffer.Length); } catch (Exception e) { Console.Error.WriteLine("Failed to read: " + e.Message); return(null); } if (ret == 0) { break; } int prev = all.Length; Array.Resize(ref all, all.Length + ret); Array.Copy(buffer, 0, all, prev, ret); } return(new MemoryStream(all)); }