What are people using serve-event for, and what features of it do they use?
In the course of attempting (with at best qualified success, which I
blame on me at least as much as on sbcl) to write software which is
robust in the face of the internet, I have been rubbing up against bits
of serve-event and fd-streams and suchlike, and I suspect it to be
over-complex for most uses it gets put to. Herewith a bunch of random
observations about which experienced fd-handler programmers could
probably say "sure, we could have told you that":
* 'bogus' handlers (those on descriptors for which fstat() returns
false) never get unmarked or removed except by restarts. A handler may
go bogus if, say, the socket it refers to is closed. It will not be
unbogused - as far as I can tell at a glance, anyway - even if the fd is
reused for something else (say, an fd-stream created by CL:OPEN)
* user-installed 'ready for output' handlers may get trodden on by
frob-output-later, if the fd is one under the care of fd-streams. "So
don't do that then"
* bogus handlers are detected and signalled in serve-event - which in a
typical program is as likely at a random unexpected time (e.g. while
waiting at the repl) than when doing file io on the associated stream.
The condition which is signalled has no type more specialised than
ERROR, so we can't pick it off selectively either with a
finely-specialised handler visible to most of the program or with a
coarsely-specialised handler bound around only a very small part of the
* oh, and what leads me to think I may not be alone in my assessment of
this stuff as "cruft": this comment from serve-event.lisp which has all
the hallmarks of 1999-era WHN doing CMUCL archeology -
;; FIXME: unused. At some point this used to be set to T
;; around the call to the handler-function, but that was commented
;; out with the verbose explantion "Doesn't work -- ACK".
(I haven't checked CVS logs, I'm just guessing from the text style)
In the back of my mind I also have Eric Marsden's presentation (at an
LSM sometime?) demonstrating among other things the Bad Things that may
happen if serve-event handlers - even nice unobtrusive ready-for-input
serve-evet handlers - are called recursively.
For my own entertainment/edification I am thinking about gutting
fd-streams and replacing with something shorter and simpler that (a)
serves the needs of ordinary ansi cl functions, and (b) provides
sufficient hooks for "tell me when input is available" that one could
write, say, a reasonably traditional network daemon or an event loop for
a gui or similar with it. However, I'm obviously not about to entertain
the idea of a long-term fork of sbcl to do so, and so I wonder if other
people have similar ideas/radically different ideas/uses for serve-event
that require it to be kept in its full complexity.
(The only actual /need/ for serve-event in fd-streams is so that
force-output can return without having written the buffers it's forcing.
ANSI language lawyers are welcome to comment on the necessity for this,
but my feeling is that in the absence of any portable way of determining
whether a stream is buffered or not, "does not wait" in the standard is
merely an unclear way of writing "does not necessarily wait" rather than
a requirement that function returns before the write finishes.
I've only recently resubscribed to sbcl-devel: I'm aware of (and have
skimmed but not fully digested) the recent talk about replacing the
serve-event internals poll() or epoll() or kevent, but if there's also
been discussion of its external api then apologies, I haven't found that