First, the documentation for wait-for-input says that only integer are
accepted, but code seems to think reals should work. (Tested on
SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem
is that a wait-for-input on a TCP server socket which has already accepted
one client will continue to return that the socket is ready to accept more
clients even though it isn't, and thus cause an error when I try to call
socket-accept. Here is the code that breaks it:
(defvar *port* 12345)
(defvar *socket-server-listen*
(socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*)
(setf
*socket-server-connection*
(when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t)
(socket-accept *socket-server-listen*)))
(format t "First time (before client connects) is ~s.~%"
*socket-server-connection*)
(defvar *socket-client-connection*)
(setf *socket-client-connection*
(socket-connect "localhost" *port* :protocol :stream
:element-type '(unsigned-byte 8) :timeout 0))
(setf
*socket-server-connection*
(when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t)
(socket-accept *socket-server-listen*)))
(format t "Second time (after client connects) is ~s.~%"
*socket-server-connection*)
(setf
*socket-server-connection*
(when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t)
(socket-accept *socket-server-listen*)))
(format t "Third time (before second client) is ~s.~%"
*socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL.
Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error
first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled.
[Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [ABORT] Return to SLIME's top level.
2: [ABORT] Abort
3: [CLOSE-CONNECTION] Close SLIME connection
4: [ABORT] Exit debugger, returning to top level.
Backtrace:
0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>
#<STREAM-SERVER-USOCKET {256F7C19}>)
1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>)
2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept")
3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept")
4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT
(SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument>
#<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>)
5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused
argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}>
:ELEMENT-TYPE NIL)
6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)
#<NULL-LEXENV>)
7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT
*SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>)
8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT
*SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT
*SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>)
9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN #
#)) #<NULL-LEXENV>)
--
Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict
the future is to invent it." - Alan Kay