2011/3/29 Chun Tian (binghe) binghe.lisp@gmail.com:
I know SBCL's WITH-TIMEOUT cannot nest, I learn this from GBBopen's portable-threads.lisp [1], and it also give a nested version SBCL's WITH-TIMEOUT, much shorter than yours:
Amusingly, neither SBCL's own, nor GBBopen's WITH-TIMEOUT is asynch unwind safe. The one I posted is -- that's what the WITHOUT-INTERRUPTS and WITH-LOCAL-INTERRUPTS were for. :) But yeah, it's miles saner than the SB-EXT:WITH-TIMEOUT.
The GBBopen's WITH-TIMEOUT also suffers from the minor defect that the dynamic context (special variables, handlers, restarts, etc) the timeout-body runs in is unpredictable -- for most cases this does not matter, but it can lead to hard to reproduce bugs.
I didn't use this version simply because I think the WITH-TIMEOUT form in usocket's SOCKET-CONNECT has no chance to be nested.
It has. A function in a library cannot know if it will be nested in some dynamic context or not. The corrollary is that library code should never use SB-EXT;WITH-TIMEOUT.
(defun foo () ...stuff that uses socket-connect with a local timeout > 1.0 somewhere in its guts...)
(with-timeout 1.0 (handler-case (foo) (error () :bad-foo)))
If the fetch takes longer than intended, the outer timeout can get converted into an USOCKET-TIMEOUT-ERROR (whatever the exact name), which in turn gets swallowed by the HANDLER-CASE.
Cheers,
-- Nikodemus