5

Is it safe to copy and reset shared_ptr at the same time?

Namely consider the following code

// Main thread (before creating any other threads)
shared_ptr<A> a(new A(1));

// Thread 1
shared_ptr<A> a_copy = a;

// Thread 2
a.reset(new(A(2));

where thread 1 and 2 run in parallel. Can I be sure, that a_copy will store pointer either to the older A(1) or to the newer A(2) shared object?

Mihran Hovsepyan
  • 10,810
  • 14
  • 61
  • 111
  • As I remember when I read Jossuttis, he always pointed that STL-containers are not thread-safe / developer should always care about their safety. – VP. Aug 10 '15 at 07:12
  • @VictorPolevoy shared_ptr is not a container, and dislike container it has an atomic member (counter), so I beleive the pointer is also atomic. – Mihran Hovsepyan Aug 10 '15 at 07:17

2 Answers2

7

From cppreference:

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of shared_ptr without additional synchronization even if these instances are copies and share ownership of the same object.

So, the answer is no — these operations are not thread-safe because both the copy and the reset are applied to the same instance, a. The result is a data race, which leads to undefined behavior.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 1
    You are right: data race in this context could mean that `a_copy` will have ref_counter from original `a` and pointer to data from `a` after reset. I had to RTFS to get this... – PiotrNycz Aug 10 '15 at 07:57
  • @PiotrNycz Sorry for copying your post… – Potatoswatter Aug 10 '15 at 08:02
  • @PiotrNycz So why did you delete your post? – VP. Aug 10 '15 at 08:04
  • @Potatoswatter wait, I don't understand. If they are `thread-safe`, how can the result be a data race? – VP. Aug 10 '15 at 08:06
  • @VictorPolevoy Sorry, copy-paste error. Extreme laziness. – Potatoswatter Aug 10 '15 at 08:06
  • @Potatoswatter np :) It seems I am an answer-killer in this topic - commented to 2 answers which are deleted.. Why don't they just edit them? – VP. Aug 10 '15 at 08:07
  • @VictorPolevoy Probably for the same reason I wrote my answer by copying and modifying Piotr's: the extra effort just doesn't seem worth it. – Potatoswatter Aug 10 '15 at 08:11
  • @VictorPolevoy I deleted mine because it would be identical to Potatoswatter's post - that will not help future readers to have two identical answers... – PiotrNycz Aug 10 '15 at 08:14
  • @PiotrNycz well, I've thought your answer was first.. So you could just edit it.. But okay, I got you. – VP. Aug 10 '15 at 08:15
1

No they are not, see @Potatoswatter answer.

But if you do need to atomically operate a shared_ptr, you can use these dedicated functions. (Although AFAIK they are only implemented on recent versions of GCC/Clang).

So your example would be:

// Main thread (before creating any other threads)
shared_ptr<A> a(new A(1));

// Thread 1
shared_ptr<A> a_copy = atomic_load(&a);

// Thread 2
atomic_store(&a, make_shared<A>(2) );
sbabbi
  • 11,070
  • 2
  • 29
  • 57