(defun test-cleanup () (let* ((cleanedp nil) (thread (threads:make-thread (lambda () (unwind-protect (sleep 999) (setf cleanedp t)))))) (sleep 0.5) (threads:destroy-thread thread) (sleep 0.5) cleanedp))
(test-cleanup)
ABCL-1.0.0 and ABCL-0.27.0 return NIL.
Other implementations I tested all return T -- Allegro, Clozure, LispWorks, SBCL (changing "threads" to "bordeaux-threads").
Of course this isn't a bug since ABCL is free to do what it wishes. Does ABCL wish that?
On Oct 23, 2011, at 20:05 , James Lawrence wrote:
(threads:destroy-thread thread) (sleep 0.5) cleanedp))
(test-cleanup)
ABCL-1.0.0 and ABCL-0.27.0 return NIL.
Other implementations I tested all return T -- Allegro, Clozure, LispWorks, SBCL (changing "threads" to "bordeaux-threads").
Of course this isn't a bug since ABCL is free to do what it wishes. Does ABCL wish that?
Unfortunately, we probably do want NIL here: we can't guarantee that the thread has been destroyed when this application returns. So, I would argue we can't plausibly return T. Unless T means just: "the user has requested the thread destroyed" type contract?
Feel free to [fork your semantics as you see fit][1].
On Mon, Oct 24, 2011 at 9:19 AM, Mark Evenson evenson.not.org@gmail.com wrote:
Unfortunately, we probably do want NIL here: we can't guarantee that the thread has been destroyed when this application returns. So, I would argue we can't plausibly return T. Unless T means just: "the user has requested the thread destroyed" type contract?
Thanks for the response.
That seems like a different issue. The purpose is not to guarantee that the thread is destroyed.
The behavior sought is: when the protected form stops executing, run the cleanup forms.
In fact it's fine if the thread is never destroyed. But if the protected form happens to stop, at that moment execute cleanup. As I understand it, this is the behavior of the other implementations.
Whether or when the corresponding thread dies is not directly relevant; as long as the cleanup runs, it doesn't matter.
In my case I am only interested in detecting the termination of a thread without polling. Maybe there is an ABCL-specific way to do that.
On Sun, Oct 23, 2011 at 8:05 PM, James Lawrence llmjjmll@gmail.com wrote:
(defun test-cleanup () (let* ((cleanedp nil) (thread (threads:make-thread (lambda () (unwind-protect (sleep 999) (setf cleanedp t)))))) (sleep 0.5) (threads:destroy-thread thread) (sleep 0.5) cleanedp))
(test-cleanup)
ABCL-1.0.0 and ABCL-0.27.0 return NIL.
Other implementations I tested all return T -- Allegro, Clozure, LispWorks, SBCL (changing "threads" to "bordeaux-threads").
Of course this isn't a bug since ABCL is free to do what it wishes. Does ABCL wish that?
I don't think we should wish that. It's inconsistent not only with other Lisp implementations, but with Java thread semantics as well. The problems are two: first, that destroy-thread doesn't really destroy the thread, it just sets a flag, so the sleep is not aborted (when it ends, the next form is not evaluated and the thread just terminates); second, that sleep swallows the ThreadInterrupted exception anyway, so even if it were interrupted, the thread would then continue normally. I think thread-destroy should be reimplemented to call Thread.interrupt() and that we should properly handle InterruptedException as a Lisp condition.
Hi all,
Reviving an old thread because of some private discussion with James which spun off the LispWorks users list.
The comment by Alessio below is one that I've been wondering about for quite some time. What's our ThreadInterrupted "protocol"? Can we design one, if we can't deduce one from code base?
I'm thinking about a protocol which works for the current code in the libraries as well as all code that the compiler generates. Reading up on the documentation for interrupts, it looks like we should be invoking Thread.interrupted() in random places to see if we've been interrupted. Presumably we need to do something with the interrupted information as well, then though.
What more would there be to designing a protocol? We currently seem to be executing lambda expressions which get pushed into a thread-local queue. However, that's far from actually stopping the thread and destroying it.
Well?
Bye,
Erik.
On Mon, Oct 24, 2011 at 11:34 PM, Alessio Stalla alessiostalla@gmail.comwrote:
On Sun, Oct 23, 2011 at 8:05 PM, James Lawrence llmjjmll@gmail.com wrote:
(defun test-cleanup () (let* ((cleanedp nil) (thread (threads:make-thread (lambda () (unwind-protect (sleep 999) (setf cleanedp t)))))) (sleep 0.5) (threads:destroy-thread thread) (sleep 0.5) cleanedp))
(test-cleanup)
ABCL-1.0.0 and ABCL-0.27.0 return NIL.
Other implementations I tested all return T -- Allegro, Clozure, LispWorks, SBCL (changing "threads" to "bordeaux-threads").
Of course this isn't a bug since ABCL is free to do what it wishes. Does ABCL wish that?
I don't think we should wish that. It's inconsistent not only with other Lisp implementations, but with Java thread semantics as well. The problems are two: first, that destroy-thread doesn't really destroy the thread, it just sets a flag, so the sleep is not aborted (when it ends, the next form is not evaluated and the thread just terminates); second, that sleep swallows the ThreadInterrupted exception anyway, so even if it were interrupted, the thread would then continue normally. I think thread-destroy should be reimplemented to call Thread.interrupt() and that we should properly handle InterruptedException as a Lisp condition.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
Yes, in the original bug report I am unaware that the thread isn't interrupted in the first place, so whether or not cleanup forms are executed is moot.
Also note a compiled (LOOP) is also impervious to interruption.
(defun launch-and-destroy () (let ((thread (threads:make-thread (lambda () (loop)))) (sleep 0.5) (threads:destroy-thread thread) (sleep 0.5)))
(compile 'launch-and-destroy) (print (threads:mapcar-threads #'threads:thread-alive-p)) (launch-and-destroy) (print (threads:mapcar-threads #'threads:thread-alive-p))
output:
(T) (T T)
Removing the COMPILE call produces the expected behavior.
On Wed, Aug 8, 2012 at 2:08 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
Reviving an old thread because of some private discussion with James which spun off the LispWorks users list.
The comment by Alessio below is one that I've been wondering about for quite some time. What's our ThreadInterrupted "protocol"? Can we design one, if we can't deduce one from code base?
I'm thinking about a protocol which works for the current code in the libraries as well as all code that the compiler generates. Reading up on the documentation for interrupts, it looks like we should be invoking Thread.interrupted() in random places to see if we've been interrupted. Presumably we need to do something with the interrupted information as well, then though.
What more would there be to designing a protocol? We currently seem to be executing lambda expressions which get pushed into a thread-local queue. However, that's far from actually stopping the thread and destroying it.
Well?
Bye,
Erik.
On Mon, Oct 24, 2011 at 11:34 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Sun, Oct 23, 2011 at 8:05 PM, James Lawrence llmjjmll@gmail.com wrote:
(defun test-cleanup () (let* ((cleanedp nil) (thread (threads:make-thread (lambda () (unwind-protect (sleep 999) (setf cleanedp t)))))) (sleep 0.5) (threads:destroy-thread thread) (sleep 0.5) cleanedp))
(test-cleanup)
ABCL-1.0.0 and ABCL-0.27.0 return NIL.
Other implementations I tested all return T -- Allegro, Clozure, LispWorks, SBCL (changing "threads" to "bordeaux-threads").
Of course this isn't a bug since ABCL is free to do what it wishes. Does ABCL wish that?
I don't think we should wish that. It's inconsistent not only with other Lisp implementations, but with Java thread semantics as well. The problems are two: first, that destroy-thread doesn't really destroy the thread, it just sets a flag, so the sleep is not aborted (when it ends, the next form is not evaluated and the thread just terminates); second, that sleep swallows the ThreadInterrupted exception anyway, so even if it were interrupted, the thread would then continue normally. I think thread-destroy should be reimplemented to call Thread.interrupt() and that we should properly handle InterruptedException as a Lisp condition.
armedbear-devel mailing list armedbear-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel@common-lisp.net