I have an unordered_map<int, std::shared_ptr<foo>>
into which I want to lazily create the instances of foo
based on callbacks. These callbacks would come from potentially a pool of threads, so to handle this, at the start I create the map and insert empty shared_ptr<>
s into the map for all possible indexes. Now I have the code below which is designed to create the foo
instance based on demand.
Is my implementation of double checked locking with shared_ptr<>
correct?
void Publish(const bar& data) {
auto id = data.get_id();
auto it = foos_.find(id);
if (it == foos_.end()) {
// throw
}
// Check if this is present
auto sp = std::atomic_load_explicit(&(it->second), std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
if (!sp) {
// Create the instance of the foo for this id
std::lock_guard<std::mutex> lock(mutex_);
(void) lock;
// Check again
sp = std::atomic_load_explicit(&(it->second), std::memory_order_relaxed);
if (!sp) {
// Create new foo
sp = std::make_shared<foo>(...);
std::atomic_thread_fence(std::memory_order_release);
std::atomic_store_explicit(&(it->second), sp, std::memory_order_relaxed);
} // Someone else created it...
}
// Push the data in
sp->Publish(data);
}
(void) lock;
? \$\endgroup\$ – πάντα ῥεῖ Jan 17 '17 at 10:33