Skip to content

Commit

Permalink
Fix race condition
Browse files Browse the repository at this point in the history
Signed-off-by: Addisu Z. Taddese <addisu@openrobotics.org>
  • Loading branch information
azeey committed Mar 20, 2024
1 parent b36e874 commit 60cdec5
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/NodeShared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,33 @@ std::shared_ptr<NodeShared> NodeShared::SharedInstance()
// Create an instance of NodeShared per process so the ZMQ context
// is not shared between different processes.
static std::weak_ptr<NodeShared> nodeSharedWeak;

static std::shared_mutex mutex;

// Check if there's already a NodeShared instance for this process.
// Use a shared_lock so multiple threads can read simultaneously.
// This will only block if there's another thread locking exclusively
// for writing. Since most of the time threads will be reading,
// we make the read operation faster at the expense of making the write
// operation slower
std::shared_ptr<NodeShared> nodeShared = nodeSharedWeak.lock();
if (nodeShared)
return nodeShared;

// Multiple threads from the same process could have arrived here
// simultaneously, so after locking, we need to make sure that there's
// not an already constructed NodeShared instance for this process.
std::lock_guard writeLock(mutex);
nodeShared = nodeSharedWeak.lock();
if (nodeShared)
return nodeShared;

Check warning on line 188 in src/NodeShared.cc

View check run for this annotation

Codecov / codecov/patch

src/NodeShared.cc#L188

Added line #L188 was not covered by tests

// Class used to enable use of std::shared_ptr. This is needed because the
// constructor and destructor of NodeShared are protected.
class MakeSharedEnabler : public NodeShared {};
// No instance, construct a new one.
nodeShared = std::make_shared<MakeSharedEnabler>();
// Assign to weak_ptr so next time SharedInstance is called, we can return the
// instance we just created.
nodeSharedWeak = nodeShared;
return nodeShared;
}
Expand Down

0 comments on commit 60cdec5

Please sign in to comment.