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\$