>>>>> "Kick" == Kick Damien-DKICK1 <[EMAIL PROTECTED]> writes:
Kick> Why does it seem to get stuck?
>> I think because the underlying system call (select(2)/poll(2)) is
>> only sensitive to status change. Your handler is expected to read
>> all available input each time it is called.
Kick> I don't think that it true. From the man page for select on my
Kick> Solairs 2.6 (though I believe that this is the POSIX specified
Kick> behavior)
Thanks for the rather generous quotes from the Solaris man page and
W. Richard Stevens. You are indeed right that select/poll is sensitive
to *state*, *not* state *change*. I was confused by Linux man 2
select:
The functions select and pselect wait for a number of file descriptors
to change status.
Nevertheless, SYS:ADD-FD-HANDLER does hook into the top-level
poll/select, as this simple example should show (use a disposable
CMUCL session)
* (let ((stream (process-pty (run-program "/bin/ls" nil :wait nil :pty :stream))))
(flet ((input (fd)
(declare (ignore fd))
(write-char #\.)))
(sys:add-fd-handler (sys:fd-stream-fd stream) :input #'input)))
* ...........................................................
Kick> AFAIK, that fact that READ-CHAR was returning characters without
Kick> blocking would seem to indicate that select would tell us that
Kick> the descriptor is readable.
We are overlooking the fact that READ-CHAR does not operate directly
on the descriptor, but on a *buffered* FD-STREAM. Here is how I
interpret your experiment:
1. The toplevel poll/select invokes your handler.
2. READ-SEQUENCE (or whatever STREAM function you're using) decides to
fill up the buffer, resulting in a read() system call that depletes
the descriptor of all available data.
3. Subsequent calls to READ-CHAR return characters already in the
buffer
4. Subsequent calls to SYS:WAIT-UNTIL-FD-USABLE fail because there is
no new data at the descriptor level
Kick> And even if it is true that one's handler is expected to read
Kick> all available input each time it is called,
It is obviously not mandatory but perhaps good practice? - if for
nothing else, it makes the handler compatible with SIGIO.
Kick> how would one know how much data is available?
1. PEEK-CHAR
2. READ-SEQUENCE or perhaps READ-N-BYTES
3. Use UNIX:UNIX-READ directly on the descriptor
Kick> But if this was the case, how would one differentiate between
Kick> EOF and there not being an data currently available?
Use SYS:ADD-FD-HANDLER or SYS:WAIT-UNTIL-FD-USABLE... If the handler
gets called but finds no data it means the remote end has closed down.
Then you'd better know how to get out of it (SYS:INVALIDATE-DESCRIPTOR
FD) as the toplevel poll/select will call you again and again...
Kick> BTW, both SERVE-EVENTS and WAIT-UNTIL-FD-USABLE have a timeout
Kick> that is of a granualarity of seconds?
CL-USER> (time (sys:wait-until-fd-usable 0 :input 1/5))
; Evaluation took:
; 0.22 seconds of real time
Regards, Ole