title: How do I check whether the other end has closed my socket stream, from a single thread?
body: <p>The <a href="http://common-lisp.net/project/usocket/api-docs.shtml#faqs" rel="nofollow">usocket FAQ</a> suggests that the way I should do this is by reading from a <code>socket-stream</code> and checking for an <code>end-of-file</code> result. That works in the case where I've got one thread active per socket, but it doesn't seem to satisfy for the case where I'm trying to service multiple sockets in the same thread. </p>
  
  <p>Consider something like</p>
  
  <pre><code>(defparameter *socket* (socket-listen "127.0.0.1" 123456))
  (defparameter *client-connections*
     (list (socket-accept *socket*)
           (socket-accept *socket*)
           (socket-accept *socket*)
           (socket-accept *socket*)))
  </code></pre>
  
  <p>For this exercise, assume that I've actually got four clients connecting there. It seems like the way to go about serving them from one thread is something like</p>
  
  <pre><code>(wait-for-input *client-connections*)
  (loop for sock in *client-connections*
        for stream = (socket-stream sock)
        when (listen stream)
          do (let ((line (read-line stream nil :eof)))
                (if (eq line :eof)
                    (progn (delete sock *client-connections*)
                           (socket-close sock))
                    (handle sock line))))
  </code></pre>
  
  <p>Except that this won't work, because a disconnected socket still returns <code>nil</code> to <code>listen</code>, and an attempt to <code>read</code> from an active socket with no messages will block <strong>but</strong> <code>wait-for-intput</code> returns immediately when there's a closed socket in the mix, even when no other socket has a message ready (though it seems to fail to specify which sockets caused it to return).</p>
  
  <p>In the situation where no client has spoken in a little while, and third client disconnects, there doesn't seem to be a good way of finding that out and closing that specific socket connection. I'd have to read them in sequence, except that since <code>read</code> blocks on no input, that would cause the thread to wait until the first two clients both sent a message.</p>
  
  <p>The solutions I've got in mind, but haven't found after some determined googling, are (in descending order of preference):</p>
  
  <ol>
  <li>A function otherwise equivalent to <code>listen</code> that returns <code>t</code> if a read on the targets' stream would return an <code>end-of-file</code> marker. <em>(Replacing <code>listen</code> above with this notional function would let the rest of it work as written)</em></li>
  <li>A function otherwise equivalent to <code>wait-for-input</code> that returns a list of closed sockets that cause it to trip. <em>(In this case, I could iterate through the list of closed sockets, check that they're actually closed with the suggested <code>read</code> technique, and close/pop them as needed)</em></li>
  <li>A function otherwise equivalent to <code>wait-for-input</code> that returns the first closed socket that caused it to trip. <em>(As #2, but slower, because it prunes at most one inactive connection per iteration)</em></li>
  <li>Keeping track of how long its been since I've received input from each socket connection, and closing them out regardless after a certain period of inactivity. <em>(Which I'd probably want to do anyway, but doing <strong>just</strong> this would potentially keep a bunch of dead connections around much longer than necessary)</em></li>
  <li>A function that attempts to <code>read-char</code> from a stream with an instant timeout, returns <code>t</code> if it encounters an <code>:eof</code>, and <code>unread-char</code>s anything else (returning <code>nil</code> after either timing out or unreading). <em>(Which is a last resort since it seems like it would be trivially easy to break in a non-obvious-but-lethal way)</em>.</li>
  </ol>
  
  <p>Also, if I'm thinking about this in precisely the wrong way, point that out too.</p>