Boost logo

Boost Users :

Subject: [Boost-users] thread::id holding resources after thread has exited
From: Oliver Seiler (oseiler_at_[hidden])
Date: 2011-06-10 23:43:22


Hi all -- Long time boost user with some unexpected behaviour related
to the use of thread::id; as this isn't in any way obvious from the
documentation, I thought it might be of some interest here.

In the case where this came up, we had a deadlock which was traced to
a thread::id member variable being reassigned. The basic flow goes
something like this:

* we have a shared resource protected with a mutex that happens to
store a thread::id
* thread 1 is started using a bind call with a shared_ptr to some
resource A; destruction of A will call our shared resource, which in
turn requires locking the mutex
* the thread::id of thread 1 is stored in the shared resource
* thread 1 exits; the unexpected bit is that the last reference to A
is held by the function object used to start this thread, which is now
being kept active by the thread::id we are still storing
* another thread, thread 2, has the mutex of our shared resource
locked and assigns its thread id to it
* the assignment results in the destruction of the thread::id
associated with thread 1, which results in the destruction of A, which
in turn tries to lock (again) the mutex in our shared resource,
resulting in a deadlock.

Initially when I saw the fix for this deadlock I thought that the
thread::id was preventing the thread itself from exiting properly, but
the deadlock was clear in the thread backtraces we had. This is a
somewhat surprising result, and isn't at all apparent from the
boost.thread documentation; it makes more sense looking through the
code, though. This appears to have the same behaviour across all
versions I've looked at (1.36, 1.42, 1.46.1).

I wonder if this is a bug; I suspect it would be possible to reset the
function object holding the thread entry point when the thread exits,
ensuring that any resources held by it are released; it certainly
isn't obvious to me that this would be prevented by holding a stray
thread::id somewhere.

If this is a confusing description, I'm sure I could bang together
some code that demonstrates the issue; not typing this at a
development box right now.

Cheers
Oliver


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net