From 54f3b551ef9e16a99391a30555d3f67a0a23c52d Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Tue, 16 Oct 2018 15:20:48 +0200 Subject: [PATCH] src: Fixed shared memory garbage collector mutex stuck * Try unlocking mutex 5 times * Then force ownership * If everything fails run without garbage collector --- src/lib/Application.cpp | 2 +- src/lib/utility/interprocess/SharedMemory.cpp | 31 +++++++++++++++++-- src/lib/utility/interprocess/SharedMemory.h | 2 +- .../SharedMemoryGarbageCollector.cpp | 10 ++++-- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 29979deb..71dc0617 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -134,7 +134,7 @@ Application::~Application() m_mainView->saveLayout(); } - SharedMemoryGarbageCollector* collector = SharedMemoryGarbageCollector::createInstance(); + SharedMemoryGarbageCollector* collector = SharedMemoryGarbageCollector::getInstance(); if (collector) { collector->stop(); diff --git a/src/lib/utility/interprocess/SharedMemory.cpp b/src/lib/utility/interprocess/SharedMemory.cpp index b9974e12..cdfeaeba 100644 --- a/src/lib/utility/interprocess/SharedMemory.cpp +++ b/src/lib/utility/interprocess/SharedMemory.cpp @@ -168,9 +168,36 @@ SharedMemory::~SharedMemory() } } -void SharedMemory::unlockSharedMutex() +bool SharedMemory::checkSharedMutex() { - getMutex().unlock(); + try + { + boost::interprocess::named_mutex& mutex = getMutex(); + + for (size_t i = 0; i < 5; i++) + { + { + // try to get ownership of the mutex a couple times + boost::interprocess::scoped_lock lock(mutex, boost::interprocess::try_to_lock); + if (lock.owns()) // mutex successfully locked + { + return true; + } + } + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + // locking kept failing, try to get ownership + boost::interprocess::scoped_lock lock(mutex, boost::interprocess::accept_ownership); + return true; + } + catch (boost::interprocess::interprocess_exception& e) + { + LOG_ERROR_STREAM(<< "boost exception thrown at shared mutex check: " << e.what()); + } + + return false; } std::string SharedMemory::getMemoryName() const diff --git a/src/lib/utility/interprocess/SharedMemory.h b/src/lib/utility/interprocess/SharedMemory.h index 863a9222..68ad08ef 100644 --- a/src/lib/utility/interprocess/SharedMemory.h +++ b/src/lib/utility/interprocess/SharedMemory.h @@ -100,7 +100,7 @@ public: std::string m_memoryName; }; - void unlockSharedMutex(); + bool checkSharedMutex(); private: static const char* s_memoryNamePrefix; diff --git a/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp b/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp index e6593bda..2281c2c0 100644 --- a/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp +++ b/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp @@ -22,10 +22,17 @@ SharedMemoryGarbageCollector* SharedMemoryGarbageCollector::createInstance() if (!s_instance) { s_instance = std::shared_ptr(new SharedMemoryGarbageCollector()); + + if (!s_instance->m_memory.checkSharedMutex()) + { + LOG_ERROR_STREAM(<< "Shared memory mutex check failed. Shared memory garbage collection disabled."); + s_instance.reset(); + } } } - catch (boost::interprocess::interprocess_exception) + catch (boost::interprocess::interprocess_exception& e) { + LOG_ERROR_STREAM(<< "boost exception thrown at shared memory garbage collector: " << e.what()); } return s_instance.get(); @@ -40,7 +47,6 @@ SharedMemoryGarbageCollector::SharedMemoryGarbageCollector() : m_memory(getMemoryName(), 65536 /* 64 kB */, SharedMemory::OPEN_OR_CREATE) , m_loopIsRunning(false) { - m_memory.unlockSharedMutex(); } SharedMemoryGarbageCollector::~SharedMemoryGarbageCollector()