From db80fa03715d006f76821ae66b941c53aea301af Mon Sep 17 00:00:00 2001 From: ev-mp Date: Tue, 19 May 2020 19:11:39 +0300 Subject: [PATCH] resolve dead-lock on multi-threaded notifications calls --- common/notifications.cpp | 23 ++++++++++++++++------- common/notifications.h | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/common/notifications.cpp b/common/notifications.cpp index 485a57e847..585ac29c7e 100644 --- a/common/notifications.cpp +++ b/common/notifications.cpp @@ -683,11 +683,22 @@ namespace rs2 void notifications_model::foreach_log(std::function action) { std::lock_guard lock(m); - for (auto&& l : log) + + // Process only the messages that are available upon invocation + std::string log_entry; + for (size_t len = 0; len < incoming_log_queue.size(); len++) { - action(l); + if (incoming_log_queue.try_dequeue(&log_entry)) + notification_logs.push_back(log_entry); } + // Limit the notification window + while (notification_logs.size() > 200) + notification_logs.pop_front(); + + for (auto&& l : notification_logs) + action(l); + auto rc = ImGui::GetCursorPos(); ImGui::SetCursorPos({ rc.x, rc.y + 5 }); @@ -698,15 +709,13 @@ namespace rs2 } } + // Callback function must not include mutex void notifications_model::add_log(std::string line) { - std::lock_guard lock(m); if (!line.size()) return; - // Limit the notification window - while (log.size() > 200) - log.pop_front(); + if (line[line.size() - 1] != '\n') line += "\n"; - log.push_back(line); + incoming_log_queue.enqueue(std::move(line)); new_log = true; } diff --git a/common/notifications.h b/common/notifications.h index 5a3e985672..ec4d09e301 100644 --- a/common/notifications.h +++ b/common/notifications.h @@ -195,7 +195,8 @@ namespace rs2 std::recursive_mutex m; bool new_log = false; - std::deque log; + single_consumer_queue incoming_log_queue; + std::deque notification_logs; std::shared_ptr selected; std::chrono::system_clock::time_point last_snoozed; };