$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-11-06 07:40:40
Anthony Williams wrote:
> The interruption points are:
>
> thread::join, thread::timed_join
> this_thread::sleep
> condition_variable::wait, condition_variable::timed_wait
> condition_variable_any::wait, condition_variable_any::timed_wait
> this_thread::interruption_point
Am I the only one who thinks that not having cancellation points at 
blocking I/O makes this fairly useless?  Perhaps I am!  I'm curious to 
hear about use-cases where Anthony or Preston's proposals are appropriate.
> "Preston A. Elder" <prez_at_[hidden]> writes:
>> Third, interruption should also apply to locks - which would in part 
>> solve the above situation.  The problem with this of course is that it is 
>> less efficient to use a mutex/condition crafted to work with 
>> interruptions at the lock level.
>
> Yes, and that's why it doesn't happen. All the interruption points are where
> the thread is waiting for some event (e.g. a condition to be notified, a
> thread to finish, or a time to elapse). Locks should only be held for a short
> period, so blocking for a lock should not be a long wait. I don't agree that
> it should be an interruption point.
I think I agree with Preston.  Yes, many locks are only held for short 
periods, but that's not the only way they can be used.
One possibility would be to make lock acquisition a cancellation point 
iff that lock acquisition would block.  This is straightforward with 
the futex code that I posted, and would not slow down the fast 
un-contended case.
As I proposed when I presented my mutex benchmark results, it may make 
sense to offer different types of locks for applications with very low 
probability of contention and for non-trivial probabilities of contention.
One application for cancellation is to cleanly kill off threads or 
groups of threads when something goes wrong.  For example, I may 
observe no activity and assume that a deadlock has occurred.  This 
would require that lock-acquisition be a cancellation point.
>> If you want to continue to offer interruption (which, by the way, I fully 
>> support!) - I believe it should be done one of two ways.
>>
>> 1) Use a signal on POSIX systems and find some equivalent mechanism on 
>> other systems.  This will then actually mean what the user thinks - 
>> thread::interrupt() interrupts the thread, not just breaks out of a 
>> condition if it happens to be in one.
>
> If a thread is waiting on a condition variable, a signal is not guaranteed to
> abort the wait:
>
> "If a signal is delivered to a thread waiting for a condition variable, upon
> return from the signal handler the thread resumes waiting for the condition
> variable as if it was not interrupted, or it shall return zero due to spurious
> wakeup."
I think that, even if this problem could be avoided, delivering a 
signal to the right thread is very hard.
> The only way I know to ensure that the thread being interrupted wakes from the
> condition variable is to broadcast the condition variable. The alternative is
> that boost::condition_variable does not actually use a pthread_cond_t in the
> implementation, and I'm not keen on that idea at all.
Interesting; I was planning to look at implementing conditions, 
bypassing the pthreads layer, as I did for my futex code.  What have 
you discovered that has put you off that idea?
>> 2) Move interruption to its own series of structures.  Like I did, with 
>> an interruptable_mutex.  The advantage of this is twofold:
>>    1) It can be implemented in a non-platform specific manner, using 
>> existing data structures, so you implement the interruptable version once 
>> (utilizing boost::mutex and boost::condition) and you don't have to care 
>> about the underlying platform.  This means it doesn't require any OS 
>> specific support.
>>    2) It works exactly as the user thinks.  An interruptable_mutex can be 
>> interrupted while blocked on something to do with it (meaning when trying 
>> to acquire a lock on it, OR when waiting on a condition with it).
>
> I'm not keen on this approach, as it really does mean that the thread can only
> be interrupted at the defined points.
It's even further from being able to cancel at blocking I/O....
Can I suggest that we don't entirely forget about
3) use pthread_cancel
It has some disadvantages, but it's the only solution that offers 
cancellation at blocking I/O.
Regards,  Phil.