-1

example:

std::shared_ptr<config const> ClassA::getConfig() {
  folly::SharedMutex::ReadHolder rh(rwConfigLock_);
  return config_;
}

The return is in the lock. However, does the shared pointer get copied over before the lock is released? I am afraid of a situation where the shared_pointers counter would get written to by different threads at the same time.

Max Gómez
  • 11
  • 2

1 Answers1

0

shared_ptr itself is thread safe by design. So the code is safe with respect to returning the shared_ptr instance.


More precisely: it is required to copy config_ to be thread safe. And even the lock is not dispensable.

Assuming that your lock prevents config_ from being modified while the function executes, the copy of config_ is done while the lock is held. This is essential because shared_ptr does not provide strong thread safety. The latter is required to safely read a shared pointer instance that could be modified asynchronously.

The problem behind the scenes is that after shared_ptr read the pointer of config_ and before it incremented the reference counter config_ might just being assigned with a new object. In this case the assignment operator decrements the reference counter, and if it returns to 0 (because no reference except for config_ points to the old object) it discards the old object. Unfortunately your thread has read the old object pointer and tries to increment the counter of the object that is currently destroyed. This is UB.

The lock together with the copy prevents from this scenario, because at the time the lock is released the reference counter of the object behind config_ is at least 2. One for your copy and one for config_ itself. So the object cannot be destroyed by an assignment to config_.

Marcel
  • 1,365
  • 9
  • 21