Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-10-22 07:46:38


Johan Nilsson:

> "Peter Dimov" <pdimov_at_[hidden]> skrev i meddelandet
> news:010601c811a7$df700410$6407a80a_at_pdimov2...

>> bool f( abstime const & dl )
>> {
>> return g( dl ) && h( dl );
>> }
>>
>> (guaranteed wait-free rollback on failed h omitted for simplicity :-) ).
>>
>> Even for the simple condvar wait case, you have a preceding mutex lock
>> which
>> needs to also respect the deadline.
>
> So the decision to use absolute times are due to implementation details?
> Ok, sounds reasonable.

No. It has nothing to do with implementation details. f is a user function,
not a Boost.Threads function. The point is that absolute timeouts are
composable, and relative timeouts are not. Consider:

bool f( abstime const & dl )
{
    if( !m1.timed_lock( dl ) ) return false;
    if( !m2.timed_lock( dl ) ) return false;
    // do something with the data protected by m1 and m2
}

(RAII omitted for brevity.) Rewrite this with a relative timeout timed_lock
and you'll see what I mean.

The same principle applies to every function which needs to perform more
than one time-consuming or potentially blocking operation.

bool f2( abstime const & dl )
{
    if( !m1.timed_lock( dl ) ) return false;
    if( !cn.timed_wait( m1, dl, pred() ) ) return false;
    // do something
}

bool timed_lock( timed_mutex & m1, timed_mutex & m2, abstime const & dl )
{
    for( ;; )
    {
        if( !m1.timed_lock( dl ) ) return false;
        if( m2.try_lock() ) return true;
        m1.unlock();

        if( !m2.timed_lock( dl ) ) return false;
        if( m1.try_lock() ) return true;
        m2.unlock();
    }
}


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