valis / Reference / API reference
Listener - API reference
Exported surface for the listener subsystem. Part of the API reference.
Package valis/src/listener
Classes
listener
Handle for a running listener. Holds the multiplexer, the event-loop thread, and the sources registered with the mux so stop-listener has everything it needs to shut down cleanly. The listener is opaque to protocol plugins: they interact with the multiplexer through valis/src/multiplexer's abstract generics and never read the listener handle directly.
Generic functions
listener-mux
(listener-mux object)
Undocumented: this exported symbol needs a docstring.
listener-sources
(listener-sources object)
Undocumented: this exported symbol needs a docstring.
listener-thread
(listener-thread object)
Undocumented: this exported symbol needs a docstring.
Functions
start-listener
(start-listener &key sources (mux (funcall *default-multiplexer-factory*)))
Register SOURCES with MUX, spawn a background thread running the event loop, and return a listener handle. SOURCES is a list of pre-built event-source objects (created via make-stream-source / make-datagram-source on the chosen backend); each source already carries its executor. MUX defaults to a fresh multiplexer produced by default-multiplexer-factory — bind that var to override the backend choice. Does NOT accept an executor keyword: source ownership of the executor is the contract, so a listener-level executor would be either redundant or contradictory. The listener retains SOURCES so stop-listener can close their underlying OS resources after the loop joins.
If any step fails before the listener handle is constructed (register-source signals fd-already-registered, an iolib error from set-io-handler, or make-thread fails), the unwind-protect cleanup deregisters every source already wired up, closes their sockets, and closes the multiplexer. Otherwise a partial start would leak every already-bound listening socket plus the mux's three fds with no recovery path: the caller never received a handle so stop-listener cannot reach them.
stop-listener
(stop-listener &optional (listener *listener*))
Signal LISTENER's multiplexer to exit, join the event-loop thread, close each registered source's underlying OS resource, then close the multiplexer itself. Safe to call with NIL (no-op) and idempotent on a stopped listener: the second call observes a dead thread and skips the wakeup and join, while the close-source / close-mux paths already tolerate already-closed fds. Returns LISTENER. The join completes promptly because stop-loop on the epoll backend wakes the loop via its self-pipe wakeup; without that wakeup, an idle loop with no traffic would block indefinitely in epollwait. close-source runs after the join so no source-ready callback races a closed socket; close-multiplexer runs last so the wakeup pipe and event-base stay alive while sources are being closed.
Variables
*default-multiplexer-factory*
A function of no arguments returning a fresh multiplexer instance. Defaults to the epoll backend. This is the single backend-selection point in the assembly layer — rebind to select a different backend (e.g. an iouring multiplexer in a future phase) without changing any call site. Tests rebind it to inject a mock or to pre-allocate a mux with extra inspection hooks.
*listener*
The process-wide listener instance, or NIL if not yet started. run-foreground sets this after start-listener returns so stop-listener can default to the running listener without the caller threading a handle through every code path.