On Fri, Dec 28, 2007, Stanislaw Halik wrote:
On Wed, Dec 26, 2007, Erik Huelsmann wrote:
usocket trunk supports a select() like interface to determine which sockets are available for reading. With that code, you could implement the 10 socket readers in 1 thread instead of in 10. The interface returns the sockets which are ready for reading. If the timeout exceeds, an empty list is returned. The interface is called WAIT-FOR-INPUT.
How about wrapping the socket in a gray stream when timeouts are used, and doing WAIT-FOR-INPUT before read operations? That sounds better than changing every place Drakma and Chunga read from sockets.
This can't be done this easily. WAIT-FOR-INPUT interacts badly with buffering. Consider this:
CL-USER> (usocket:socket-connect "ananke" 25) #<USOCKET:STREAM-USOCKET {B550781}>
CL-USER> (usocket:wait-for-input '#<USOCKET:STREAM-USOCKET {B550781}> :timeout 3) (#<USOCKET:STREAM-USOCKET {B550781}>) 3 CL-USER> (usocket:wait-for-input '#<USOCKET:STREAM-USOCKET {B550781}> :timeout 3) (#<USOCKET:STREAM-USOCKET {B550781}>) 3
CL-USER> (read-char (usocket:socket-stream (car '(#<USOCKET:STREAM-USOCKET {B550781}>)))) #\2
CL-USER> (usocket:wait-for-input '#<USOCKET:STREAM-USOCKET {B550781}> :timeout 3) NIL NIL
The SMTP banner has already been slurped into the buffer and select(2) returns 0. This could work with :buffering :none. usocket doesn't give an option as whether to enable input buffering.
As for read timeout support for usocket, only SBCL and LispWorks support it. CLISP has WITH-TIMEOUT, but that would require wrapping the socket in a gray stream with WITH-TIMEOUT. Note that WITH-TIMEOUT in CLISP depends on threads, not enabled by default nor in Debian package.