Boost logo

Boost :

Subject: Re: [boost] [Thread][Release] Boost.Thread and 1.45 release
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-10-29 08:30:26


----- Original Message -----
From: "Anthony Williams" <anthony.ajw_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, October 29, 2010 8:52 AM
Subject: Re: [boost] [Thread][Release] Boost.Thread and 1.45 release

>
> "vicente.botet" <vicente.botet_at_[hidden]> writes:
>
>> From: "Anthony Williams" <anthony.ajw_at_[hidden]>
>
>>> I've fixed all the outstanding "showstopper" bugs in boost.thread on
>>> trunk (including the thread interruption issue, #2330),
>
>> I have take a look at the modification associated to this ticket #2330
>> thread::interrupt() can be lost if condition_variable::wait() in
>> progress and I don't reach to understand why do you need to have an
>> internal mutex on condition_variable. The associated patch don't
>> modifies this point. The resolution don't states nothing more than the
>> ticket has been solved but no how. Please could you explain this
>> addition? Is this related to another ticket?
>
> The patch attached to the ticket is incomplete. There is no requirement
> that the same mutex is used with the same condition variable instance
> for every wait. Therefore, if a thread waits with one mutex, wakes,
> destroys the mutex and then waits with another then there is a race
> condition with another thread that tries to interrupt it --- the
> interrupting thread might try and lock a just-destroyed mutex.

Oh, I see. So to support interruptions, the condition variable needs to be associated to a single mutex which must be locked before any condition variable wait.
I don't understand however why do you need to lock the mutex each time you signal the condition

    inline void condition_variable::notify_one()
    {
*** boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
        BOOST_VERIFY(!pthread_cond_signal(&cond));
    }
        
    inline void condition_variable::notify_all()
    {
*** boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
        BOOST_VERIFY(!pthread_cond_broadcast(&cond));
    }

    void thread::interrupt()
    {
        detail::thread_data_ptr const local_thread_info=(get_thread_info)();
        if(local_thread_info)
        {
            lock_guard<mutex> lk(local_thread_info->data_mutex);
            local_thread_info->interrupt_requested=true;
            if(local_thread_info->current_cond)
            {
*** boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
                BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
            }
        }
    }

Please, could you clarify what are you protecting with the lock (***)?

I was wondering why do we need to pass a unique_lock to the wait operations if it is not needed at all?
 
> The internal mutex is necessary to eliminate this race condition. This
> mutex could be global, but that would introduce a point of contention
> between all cond vars.

 
>> This will make condition_variable and condition_variable_any almost
>> equivalent. What will be the adavantage to use condition_variable
>> respect to condition_variable_any?
>
> The only difference now is that condition_variable_any will accept any
> type of mutex in the wait functions. There is no difference between
> them in terms of performance.

If I remember the restriction on condition_variable was to be able to be as efficient as if we used the underlying platform. If we don't have any advantage for condition_variable, why to have it? As not all applications use the interruption mechanism, I will preserv a condition_variable class that is not an interruption point and is as efficient as possible.
 
Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk