#pragma once ///@file #include "file-descriptor.hh" #ifdef _WIN32 # include "windows-async-pipe.hh" #endif #ifndef _WIN32 # include #else # include # include "windows-error.hh" #endif namespace nix { /** * An "muxable pipe" is a type of pipe supporting endpoints that wait * for events on multiple pipes at once. * * On Unix, this is just a regular anonymous pipe. On Windows, this has * to be a named pipe because we need I/O Completion Ports to wait on * multiple pipes. */ using MuxablePipe = #ifndef _WIN32 Pipe #else windows::AsyncPipe #endif ; /** * Use pool() (Unix) / I/O Completion Ports (Windows) to wait for the * input side of any logger pipe to become `available'. Note that * `available' (i.e., non-blocking) includes EOF. */ struct MuxablePipePollState { #ifndef _WIN32 std::vector pollStatus; std::map fdToPollStatus; #else OVERLAPPED_ENTRY oentries[0x20] = {0}; ULONG removed; bool gotEOF = false; #endif /** * Check for ready (Unix) / completed (Windows) operations */ void poll( #ifdef _WIN32 HANDLE ioport, #endif std::optional timeout); using CommChannel = #ifndef _WIN32 Descriptor #else windows::AsyncPipe * #endif ; /** * Process for ready (Unix) / completed (Windows) operations, * calling the callbacks as needed. * * @param handleRead callback to be passed read data. * * @param handleEOF callback for when the `MuxablePipe` has closed. */ void iterate( std::set & channels, std::function handleRead, std::function handleEOF); }; }