jhughes February 2016

Boost interprocess_mutex copy/move constructor?

I'm trying to create a vector of objects in shared memory that each own an interprocess_mutex as follows:

struct test
{
    test(){}
    interprocess_mutex mutex;
};

using namespace boost::interprocess;
managed_shared_memory seg(open_or_create, "MySharedMemory", 65536);
allocator<void, managed_shared_memory::segment_manager> void_alloc_(seg.get_segment_manager());
vector<test, allocator<test, managed_shared_memory::segment_manager>> vec(void_alloc_);
vec.push_back(test());

However interprocess_mutex is explicitly missing a copy/move constructor and clang fails to compile with this error:

copy constructor of 'test' is implicitly deleted because field 'mutex' has an inaccessible copy constructor
interprocess_mutex mutex;

Is there a reason for this? It looks like boost::thread mutex has a copy constructor. How can I accomplish this using interprocess_mutex?

Answers


Collin Dauphinee February 2016

No standard or Boost mutex-type class provides a copy constructor. If you need to copy classes containing a mutex member, the mutex needs to be turned into a pointer, and you need to provide a copy constructor to deal with the mutex appropriately.

What would copying a mutex even do? Would both instances refer to the same mutex? Would each instance have it's own mutex? What if the mutex is already locked during the copy?

Aside from these questions, a mutex member is often used to protect the object's other members. If you support copying on a class with a mutex member, you very likely want to lock that mutex at some point during the copy.


jhughes February 2016

I solved the problem by changing the vector to contain shared_ptr instead of test directly. test() gets called only once and the object is owned by the shared_ptr object, which is move/copyable:

    using namespace boost::interprocess;

    typedef managed_shared_memory::segment_manager SegmentManager;
    typedef allocator<void, SegmentManager> test_allocator;
    typedef deleter<test, SegmentManager> test_deleter;
    typedef shared_ptr<test, test_allocator, test_deleter> test_pointer;
    typedef vector<test_pointer, allocator<test_pointer, SegmentManager>> test_pointer_vector;

    managed_shared_memory seg(open_or_create, "MySharedMemory", 65536);

    test_allocator alloc(seg.get_segment_manager());
    test_deleter del(seg.get_segment_manager());

    test_pointer& p = *seg.construct<test_pointer>(anonymous_instance)(seg.construct<test>(anonymous_instance)(), alloc, del);
    test_pointer_vector& vec = *seg.construct<test_pointer_vector>(anonymous_instance)(alloc);

    vec.push_back(p);
    p.get()->mutex_.try_lock();

Post Status

Asked in February 2016
Viewed 1,643 times
Voted 4
Answered 2 times

Search




Leave an answer