shared_ptr thread safety on destruction

91 Views Asked by At

For given program:

#include <iostream>
#include <memory>
#include <thread>

void threadFunction(std::shared_ptr<int> ptr) {
    std::cout << "Worker thread: " << *ptr << std::endl;
}

int main() {
    auto sharedInt = std::make_shared<int>(42);

    std::cout << "Main thread: " << *sharedInt << std::endl;

    std::thread t(threadFunction, sharedInt);

    sharedInt.reset();

    t.join();

    return 0;
}

I get valgrind (helgrind tool) erros:

 
==12797== Possible data race during write of size 4 at 0x4E38088 by thread #1
==12797== Locks held: none
==12797==    at 0x10A4B9: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:343)
==12797==    by 0x10A794: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:1071)
==12797==    by 0x10A663: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1524)
==12797==    by 0x10A8EF: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::reset() (shared_ptr_base.h:1642)
==12797==    by 0x10A300: main (shared_ptr.cpp:17)
==12797== 
==12797== This conflicts with a previous read of size 4 by thread #2
==12797== Locks held: none
==12797==    at 0x10A49E: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:337)
==12797==    by 0x10A794: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:1071)
==12797==    by 0x10A663: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1524)
==12797==    by 0x10A67F: std::shared_ptr<int>::~shared_ptr() (shared_ptr.h:175)
==12797==    by 0x10BB2D: void std::__invoke_impl<void, void (*)(std::shared_ptr<int>), std::shared_ptr<int> >(std::__invoke_other, void (*&&)(std::shared_ptr<int>), std::shared_ptr<int>&&) (invoke.h:61)
==12797==    by 0x10BA74: std::__invoke_result<void (*)(std::shared_ptr<int>), std::shared_ptr<int> >::type std::__invoke<void (*)(std::shared_ptr<int>), std::shared_ptr<int> >(void (*&&)(std::shared_ptr<int>), std::shared_ptr<int>&&) (invoke.h:96)
==12797==    by 0x10B9E4: void std::thread::_Invoker<std::tuple<void (*)(std::shared_ptr<int>), std::shared_ptr<int> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (std_thread.h:292)
==12797==    by 0x10B985: std::thread::_Invoker<std::tuple<void (*)(std::shared_ptr<int>), std::shared_ptr<int> > >::operator()() (std_thread.h:299)
==12797==  Address 0x4e38088 is 8 bytes inside a block of size 24 alloc'd
==12797==    at 0x4846023: operator new(unsigned long) (vg_replace_malloc.c:483)
==12797==    by 0x10B51E: std::__new_allocator<std::_Sp_counted_ptr_inplace<int, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (new_allocator.h:147)
==12797==    by 0x10B10F: allocate (alloc_traits.h:482)
==12797==    by 0x10B10F: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<int, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<int, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<int, std::allocator<void>, (__gnu_cxx::_Lock_policy)2> >&) (allocated_ptr.h:98)
==12797==    by 0x10AF48: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<int, std::allocator<void>, int>(int*&, std::_Sp_alloc_shared_tag<std::allocator<void> >, int&&) (shared_ptr_base.h:969)
==12797==    by 0x10AD29: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<void>, int>(std::_Sp_alloc_shared_tag<std::allocator<void> >, int&&) (shared_ptr_base.h:1712)
==12797==    by 0x10AA60: std::shared_ptr<int>::shared_ptr<std::allocator<void>, int>(std::_Sp_alloc_shared_tag<std::allocator<void> >, int&&) (shared_ptr.h:464)
==12797==    by 0x10A753: std::shared_ptr<std::enable_if<!std::is_array<int>::value, int>::type> std::make_shared<int, int>(int&&) (shared_ptr.h:1010)
==12797==    by 0x10A294: main (shared_ptr.cpp:11)
==12797==  Block was alloc'd by thread #1

Where line 17 is sharedInt.reset();

According to my understanding this program should be perfectly fine as both threads operate on a different instances of shared_ptr object.

Am I right?

0

There are 0 best solutions below