From c145d60df437447f16d06be9b85fa90df0e58185 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 12 Mar 2020 11:30:51 +0100 Subject: [PATCH] Improvement in the RemovableDriveManager update function: Don't call the update() if it is already running. Wait for the other instance to finish instead. --- src/slic3r/GUI/RemovableDriveManager.cpp | 28 +++++++++++++++--------- src/slic3r/GUI/RemovableDriveManager.hpp | 2 ++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index f76625049..3ec27ce5b 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -487,17 +487,25 @@ RemovableDriveManager::RemovableDrivesStatus RemovableDriveManager::status() // Update is called from thread_proc() and from most of the public methods on demand. void RemovableDriveManager::update() { - std::vector current_drives = this->search_for_removable_drives(); - - // Post update events. - tbb::mutex::scoped_lock lock(m_drives_mutex); - std::sort(current_drives.begin(), current_drives.end()); - if (current_drives != m_current_drives) { - assert(m_callback_evt_handler); - if (m_callback_evt_handler) - wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED)); + tbb::mutex::scoped_lock inside_update_lock; + if (inside_update_lock.try_acquire(m_inside_update_mutex)) { + // Got the lock without waiting. That means, the update was not running. + // Run the update. + std::vector current_drives = this->search_for_removable_drives(); + // Post update events. + tbb::mutex::scoped_lock lock(m_drives_mutex); + std::sort(current_drives.begin(), current_drives.end()); + if (current_drives != m_current_drives) { + assert(m_callback_evt_handler); + if (m_callback_evt_handler) + wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED)); + } + m_current_drives = std::move(current_drives); + } else { + // Acquiring the m_iniside_update lock failed, therefore another update is running. + // Just block until the other instance of update() finishes. + inside_update_lock.acquire(m_inside_update_mutex); } - m_current_drives = std::move(current_drives); } #ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS diff --git a/src/slic3r/GUI/RemovableDriveManager.hpp b/src/slic3r/GUI/RemovableDriveManager.hpp index 8b661d19c..c12f2dd0a 100644 --- a/src/slic3r/GUI/RemovableDriveManager.hpp +++ b/src/slic3r/GUI/RemovableDriveManager.hpp @@ -102,6 +102,8 @@ private: // sorted ascending by path std::vector m_current_drives; mutable tbb::mutex m_drives_mutex; + // Locking the update() function to avoid that the function is executed multiple times. + mutable tbb::mutex m_inside_update_mutex; // Returns drive path (same as path in DriveData) if exists otherwise empty string. std::string get_removable_drive_from_path(const std::string& path);