Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#5754 closed Bugs (duplicate)

Bug/design issue with boost::thread::id

Reported by: ZenJu <zhnmju123@…> Owned by: viboes
Milestone: To Be Determined Component: thread
Version: Boost 1.47.0 Severity: Showstopper
Keywords: thread::id Cc: viboes

Description

Hi,

I have just run into a nasty memory leak which was caused by a circular reference due to boost::thread::id.

The situation is as follows:

  1. Main thread controls several worker thread.
  2. Only one worker thread shall be allowed to report its current status, so we need some identifier.
  3. The information which thread shall report, is placed as a boost::thread::id into a structure which is shared by main thread and all worker threads (via std::shared_ptr)
  1. We happily and unwittingly(!) introduced a circular reference!

Analysis: Main thread successfully joins all worker threads, still there is a circular reference. Simple reason: boost::thread::id has partial ownership of the corresponding thread local storage! Technically it's implemented as an intrusive_ptr on boost::detail::thread_data which owns the TLS, in my case it's the data of a full blown function object, which I had passed to boost::thread.

In the example above, one of the worker threads shares ownership to the shared structure containing a thread::id which shares ownership of...surprise ...himself!

This is IMHO a design bug! A thread::id should not have any ownership of its corresponding thread's data, but should be a plain vanilla value type without any side-effects.

Fix is simple, just remove the thread::id's ownership semantics. I really hope this gets addresses (soon), since it's fundamental, and IMHO in contrast to reasonable expectations.

Tested with boost v1.47 on MingW/GCC and VC 2010 64-bit

Best regards, ZenJu

Change History (4)

comment:1 by viboes, 11 years ago

Keywords: thread::id added
Owner: changed from Anthony Williams to viboes
Status: newassigned

I was wondering what prevent from making thread::id an opaque type around the thread::native_handle, Anthony? Shouldn't the native handle solve this issue?

comment:2 by viboes, 11 years ago

Cc: viboes added
Type: BugsSupport Requests

Can this be considered a duplicate of #4345 thread::id and joining problem with cascade of threads?

Moved to support request until clarified.

comment:3 by viboes, 11 years ago

Resolution: duplicate
Status: assignedclosed
Type: Support RequestsBugs

duplicate of #4345 thread::id and joining problem with cascade of threads

in reply to:  3 comment:4 by anonymous, 11 years ago

Replying to viboes:

duplicate of #4345 thread::id and joining problem with cascade of threads

I have encountered another manifestation of this issue. I have produced a very simple test program that will exhibit the issue:

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
void GetThreadId(boost::shared_ptr<boost::thread::id> tidPtr)
{
    *tidPtr = boost::this_thread::get_id();
}
int main(int argc, char* argv[])
{
    for(;;)
    {
        boost::shared_ptr<boost::thread::id> tidPtr(new boost::thread::id());
        boost::thread thread(GetThreadId, tidPtr);
        tidPtr.reset(); // force necessity to pass tidPtr by value
        thread.join();
    }
    return 0;
}

This program leaks memory every time around the for loop in main.

Note: See TracTickets for help on using tickets.