Edi Weitz wrote:
That one went over my head. Does it mean that if I put a function like this:
(defun cancel-all-threads () (mapcar (lambda (thread) (sb-thread:interrupt-thread thread (lambda () (throw 'hunchentoot::handler-done "")))) (sb-thread:list-all-threads)))
into, say, request.lisp (in hunchentoot), that it would find the tag?
Why don't you try it out yourself?
CL-USER> (defun endless () (format #.*standard-output* "Interrupted by someone throwing ~S.~%" (catch 'foo (loop (sleep 1))))) ENDLESS CL-USER> (defun stop () (throw 'foo 42)) STOP CL-USER> (sb-thread:make-thread 'endless) #<SB-THREAD:THREAD {AEB0E11}> CL-USER> (sb-thread:interrupt-thread * 'stop) Interrupted by someone throwing 42.
But as I already said the catch tag has to be established for this to work. Look at the code, specifically at server.lisp, and you'll see that you can't simply throw HANDLER-DONE at any time during the lifetime of a Hunchentoot thread. Or simply read the docs where it says that you can throw this tag "during the lifetime of a handler."
I didn't try it out at that point because I didn't understand it well enough to formulate an intelligent test case. Thank you for providing one.
I have in place some machinery now that should enable me to identify all the threads in play and their state the next time it hangs as per Zach's suggestions, so I'll have to wait and see. Can't troubleshoot it until it breaks unfortunately.
Thanks for the ideas. --Jeff