I was using WITH-TIMEOUT the other day and it seems that it doesn't quite hide the underlying implementation quite enough: on SBCL it signals an SBCL-specific condition when it times out. Thus to handle the timeout you have to either handle that specific condition or something too broad (like CONDITION). Perhaps BT:WITH-TIMEOUT should handle the underlying condition and signal a BT-defined condition so this code can be written portably. I could provide a patch for SBCL (and probably Allegro) if folks think this is a good idea.
-Peter
On Fri, 18 Dec 2009 08:34:15 -0800, Peter Seibel said:
I was using WITH-TIMEOUT the other day and it seems that it doesn't quite hide the underlying implementation quite enough: on SBCL it signals an SBCL-specific condition when it times out. Thus to handle the timeout you have to either handle that specific condition or something too broad (like CONDITION). Perhaps BT:WITH-TIMEOUT should handle the underlying condition and signal a BT-defined condition so this code can be written portably. I could provide a patch for SBCL (and probably Allegro) if folks think this is a good idea.
I think it would be better to remove WITH-TIMEOUT completely, because it is too dangerous to use in production code. It causes a throw from a random point in the program, so there is no way to use it safely with UNWIND-PROTECT without extra code to prevent that.
Well, the use I had for it was I needed to wait on a condition variable with a timeout. I.e. wait until the condition was notified or a certain amount of time had passed. In Allegro there was a direct way of doing that but there wasn't in Bordeaux Threads so I had to roll my own. If Bordeaux Threads wants to provide a way of doing that I'll be happy (at least for now). Though I'm not sure I see that WITH-TIMEOUT deserves to be totally removed--you may need to exercise some care about what you put inside a WITH-TIMEOUT but it seems that it shouldn't be drastically worse than any code that, say, calls a user-provided function (which could also signal a condition at a more or less random time.) Unless you're saying it's hard/impossible to implement safely within the Lisp implementation. That I wouldn't know about.
-Peter
On Fri, Dec 18, 2009 at 10:48 AM, Martin Simmons martin@lispworks.com wrote:
On Fri, 18 Dec 2009 08:34:15 -0800, Peter Seibel said:
I was using WITH-TIMEOUT the other day and it seems that it doesn't quite hide the underlying implementation quite enough: on SBCL it signals an SBCL-specific condition when it times out. Thus to handle the timeout you have to either handle that specific condition or something too broad (like CONDITION). Perhaps BT:WITH-TIMEOUT should handle the underlying condition and signal a BT-defined condition so this code can be written portably. I could provide a patch for SBCL (and probably Allegro) if folks think this is a good idea.
I think it would be better to remove WITH-TIMEOUT completely, because it is too dangerous to use in production code. It causes a throw from a random point in the program, so there is no way to use it safely with UNWIND-PROTECT without extra code to prevent that.
-- Martin Simmons LispWorks Ltd http://www.lispworks.com/
Good luck with that -- handling arbitrary throws in the condition variable implementation is very difficult to get right :-(
Adding a timeout argument to condition-wait is the best option.
The difference between WITH-TIMEOUT and code that calls user-provided functions is that you know where these functions are called.
E.g. the call to CLEANUP-2 will be skipped if the timeout occurs inside CLEANUP-1:
(unwind-protect ... (cleanup-1) (cleanup-2))
Even worse, code like the example below is flawed because the timeout might occur inside allocate-temp-object, before the variable is set, but after the temp object has been allocated:
(let (object) (unwind-protect (progn (setq object (allocate-temp-object)) ...use object...) (when object (deallocate-temp-object object))))
Fixing these common idioms to work with WITH-TIMEOUT requires some changes to the code, possibly using macros that block interrupts.
__Martin
On Fri, 18 Dec 2009 11:57:33 -0800, Peter Seibel said:
Well, the use I had for it was I needed to wait on a condition variable with a timeout. I.e. wait until the condition was notified or a certain amount of time had passed. In Allegro there was a direct way of doing that but there wasn't in Bordeaux Threads so I had to roll my own. If Bordeaux Threads wants to provide a way of doing that I'll be happy (at least for now). Though I'm not sure I see that WITH-TIMEOUT deserves to be totally removed--you may need to exercise some care about what you put inside a WITH-TIMEOUT but it seems that it shouldn't be drastically worse than any code that, say, calls a user-provided function (which could also signal a condition at a more or less random time.) Unless you're saying it's hard/impossible to implement safely within the Lisp implementation. That I wouldn't know about.
-Peter
On Fri, Dec 18, 2009 at 10:48 AM, Martin Simmons martin@lispworks.com wrote:
> On Fri, 18 Dec 2009 08:34:15 -0800, Peter Seibel said:
I was using WITH-TIMEOUT the other day and it seems that it doesn't quite hide the underlying implementation quite enough: on SBCL it signals an SBCL-specific condition when it times out. Thus to handle the timeout you have to either handle that specific condition or something too broad (like CONDITION). Perhaps BT:WITH-TIMEOUT should handle the underlying condition and signal a BT-defined condition so this code can be written portably. I could provide a patch for SBCL (and probably Allegro) if folks think this is a good idea.
I think it would be better to remove WITH-TIMEOUT completely, because it is too dangerous to use in production code. It causes a throw from a random point in the program, so there is no way to use it safely with UNWIND-PROTECT without extra code to prevent that.
-- Martin Simmons LispWorks Ltd http://www.lispworks.com/
-- Peter Seibel http://www.codersatwork.com/ http://www.gigamonkeys.com/blog/
Bordeaux-threads-devel mailing list Bordeaux-threads-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/bordeaux-threads-devel
On Fri, 2009-12-18 at 11:57 -0800, Peter Seibel wrote:
Well, the use I had for it was I needed to wait on a condition variable with a timeout. I.e. wait until the condition was notified or a certain amount of time had passed. In Allegro there was a direct way of doing that but there wasn't in Bordeaux Threads so I had to roll my own. If Bordeaux Threads wants to provide a way of doing that I'll be happy (at least for now). Though I'm not sure I see that WITH-TIMEOUT deserves to be totally removed--you may need to exercise some care about what you put inside a WITH-TIMEOUT but it seems that it shouldn't be drastically worse than any code that, say, calls a user-provided function (which could also signal a condition at a more or less random time.) Unless you're saying it's hard/impossible to implement safely within the Lisp implementation. That I wouldn't know about.
The problem is that the only general way to implement timeouts is to use alarm(2) which asks the kernel to send SIGALRM after a certain amount of time, and mixing signals and condition variables is very prone to errors - the example given by Martin is a typical case of resource leak caused by asynchronous unwinds
On Fri, 2009-12-18 at 08:34 -0800, Peter Seibel wrote:
I was using WITH-TIMEOUT the other day and it seems that it doesn't quite hide the underlying implementation quite enough: on SBCL it signals an SBCL-specific condition when it times out. Thus to handle the timeout you have to either handle that specific condition or something too broad (like CONDITION). Perhaps BT:WITH-TIMEOUT should handle the underlying condition and signal a BT-defined condition so this code can be written portably. I could provide a patch for SBCL (and probably Allegro) if folks think this is a good idea.
I've fixed this: now with-timeout will always signal bt:timeout - which on SBCL is an alias for sb-ext:timeout
bordeaux-threads-devel@common-lisp.net