Boost logo

Boost :

Subject: Re: [boost] [thread 1.48] Multiple interrupt/timed_join leads to deadlock
From: Gaetano Mendola (mendola_at_[hidden])
Date: 2012-12-05 12:39:15


On 05/12/2012 18.08, Anthony Williams wrote:
> On 05/12/12 15:59, Gaetano Mendola wrote:
>> On 05/12/2012 16.29, Vicente Botet wrote:
>>> template<typename TimeDuration>
>>> bool timed_join(TimeDuration const& rel_time);
>>>
>>> Preconditions:
>>>
>>> this->get_id()!=boost::this_thread::get_id()
>>>
>>> Postconditions:
>>>
>>> If *this refers to a thread of execution on entry, and timed_join
>>> returns true, that thread of execution has completed, and *this no longer
>>> refers to any thread of execution. If this call to timed_join returns
>>> false,
>>> *this is unchanged.
>>> "
>>>
>>> Your second call doesn't satisfy the pre-conditions, so that the
>>> outcome of
>>> this second call is undefined.
>>
>> That precondition tests that your are not interrupting yourself doesn't
>> say anything about thread safety. Am I missing something ?
>
> Your code had two bugs. Firstly, it called interrupt and timed_join on
> the same thread object from multiple threads. Secondly, it called
> interrupt and timed_join in a loop without ever checking the result of
> timed_join.
>
> Vicente's quote from the docs addresses the second issue: if timed_join
> returns true then looping round to call interrupt and timed_join again
> is now a precondition violation, and thus undefined behaviour.

Then I'm not reading well the precondition.

this->get_id(): the thread id of the instance on which I'm calling the
boost::thread::interrupt().

boost::this_thread::get_id(): gives the caller thread id.

from documentation I'm reading that if an instance of boost::thread
doesn't refer to a thread of execution then it returns a
default-constructed boost::thread::id that represents Not-a-Thread.

This means that in case of an already joined thread this->get_id()
returns a default-constructed boost::thread::id, how can that be equal
to current (caller) thread id?

I'm reading the precondition as: "you can not time_join your self"

Indeed looking at 1.52 code in the interrupt method I can read:

if (this_thread::get_id() == get_id()) {
   boost::throw_exception(
     thread_resource_error(
       system::errc::resource_deadlock_would_occur,
       "boost thread: trying joining itself"));
}

**boost thread: trying joining itself**

I'm sure I'm still missing something.

Regards
Gaetano Mendola


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