From 010146715441c8db235fa9ffbce33761ac23b4c0 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Thu, 20 Oct 2022 17:26:21 -0400 Subject: [PATCH] Communication: Atomic sync messages If waitForMessageSync() is called in two threads for the same message the callback for both will be invoked with the first send. --- communication/communication.cpp | 13 +++++++------ include/icsneo/communication/communication.h | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/communication/communication.cpp b/communication/communication.cpp index 95bf441..617f882 100644 --- a/communication/communication.cpp +++ b/communication/communication.cpp @@ -212,14 +212,15 @@ bool Communication::removeMessageCallback(int id) { std::shared_ptr Communication::waitForMessageSync(std::function onceWaitingDo, const std::shared_ptr& f, std::chrono::milliseconds timeout) { - std::mutex m; + std::mutex cvMutex; std::condition_variable cv; std::shared_ptr returnedMessage; - std::unique_lock lk(m); // Don't let the callback fire until we're waiting for it - int cb = addMessageCallback(std::make_shared([&m, &returnedMessage, &cv](std::shared_ptr message) { + std::unique_lock fnLk(syncMessageMutex); // Only allow for one sync message at a time + std::unique_lock cvLk(cvMutex); // Don't let the callback fire until we're waiting for it + int cb = addMessageCallback(std::make_shared([&cvMutex, &returnedMessage, &cv](std::shared_ptr message) { { - std::lock_guard lk(m); + std::lock_guard lk(cvMutex); returnedMessage = message; } cv.notify_all(); @@ -228,8 +229,8 @@ std::shared_ptr Communication::waitForMessageSync(std::function redirectingRead{false}; std::function&&)> redirectionFn; std::mutex redirectingReadMutex; // Don't allow read to be disabled while in the redirectionFn + std::mutex syncMessageMutex; void dispatchMessage(const std::shared_ptr& msg); void handleInput(Packetizer& p, std::vector& readBytes);