diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 99843616..d2bad53f 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -38,7 +38,11 @@ void Application::createInstance( Version::setApplicationVersion(version); loadSettings(); - SharedMemoryGarbageCollector::createInstance()->run(Application::getUUID()); + SharedMemoryGarbageCollector* collector = SharedMemoryGarbageCollector::createInstance(); + if (collector) + { + collector->run(Application::getUUID()); + } TaskScheduler::getInstance(); MessageQueue::getInstance(); @@ -128,7 +132,11 @@ Application::~Application() m_mainView->saveLayout(); } - SharedMemoryGarbageCollector::getInstance()->stop(); + SharedMemoryGarbageCollector* collector = SharedMemoryGarbageCollector::createInstance(); + if (collector) + { + collector->stop(); + } } const std::shared_ptr Application::getCurrentProject() @@ -214,7 +222,7 @@ void Application::createAndLoadProject(const FilePath& projectSettingsFilePath) void Application::refreshProject(bool force) { - if (m_project) + if (m_project && checkSharedMemory()) { bool indexing = m_project->refresh(force); if (indexing) @@ -443,3 +451,19 @@ void Application::updateTitle() m_mainView->setTitle(title); } } + +bool Application::checkSharedMemory() +{ + std::string error = SharedMemory::checkSharedMemory(getUUID()); + if (error.size()) + { + MessageStatus("Error on accessing shared memory. Indexing not possible. Please restart computer or run as admin: " + error, true).dispatch(); + handleDialog( + "There was an error accessing shared memory on your computer: " + error + "\n\n" + "Project indexing is not possible. Please restart your computer or try running Sourcetrail as admin. If the " + "issue persists contact mail@sourcetrail.com"); + return false; + } + + return true; +} diff --git a/src/lib/Application.h b/src/lib/Application.h index 63ec2664..4a6f4d89 100644 --- a/src/lib/Application.h +++ b/src/lib/Application.h @@ -80,6 +80,8 @@ private: void updateTitle(); + bool checkSharedMemory(); + const bool m_hasGUI; std::shared_ptr m_project; std::shared_ptr m_storageCache; diff --git a/src/lib/utility/interprocess/SharedMemory.cpp b/src/lib/utility/interprocess/SharedMemory.cpp index ece0effc..f032b036 100644 --- a/src/lib/utility/interprocess/SharedMemory.cpp +++ b/src/lib/utility/interprocess/SharedMemory.cpp @@ -57,6 +57,23 @@ std::string SharedMemory::checkName(const std::string& name) return name.size() > 18 ? name.substr(0, 18) : name; } +std::string SharedMemory::checkSharedMemory(const std::string& name) +{ + std::string error; + + try + { + SharedMemory memory("test_" + name, 65536 /* 64 kB */, CREATE_AND_DELETE); + } + catch (boost::interprocess::interprocess_exception& e) + { + LOG_ERROR_STREAM(<< "boost exception thrown at shared memory check: " << e.what()); + error = e.what(); + } + + return error; +} + void SharedMemory::deleteSharedMemory(const std::string& name) { boost::interprocess::shared_memory_object::remove((s_memoryNamePrefix + name).c_str()); @@ -116,11 +133,10 @@ SharedMemory::SharedMemory(const std::string& name, size_t initialMemorySize, Ac boost::interprocess::named_mutex mutex(boost::interprocess::open_only, getMutexName().c_str()); boost::interprocess::scoped_lock lock(mutex, boost::interprocess::try_to_lock); } - } catch (boost::interprocess::interprocess_exception& e) { - LOG_ERROR_STREAM(<< "boost exception thrown at shared momory creation - " << getMemoryName() << ": " << e.what()); + LOG_ERROR_STREAM(<< "boost exception thrown at shared memory creation - " << getMemoryName() << ": " << e.what()); throw e; } } @@ -142,7 +158,7 @@ SharedMemory::~SharedMemory() } catch (boost::interprocess::interprocess_exception& e) { - LOG_ERROR_STREAM(<< "boost exception thrown at shared momory destruction - " << getMemoryName() << ": " << e.what()); + LOG_ERROR_STREAM(<< "boost exception thrown at shared memory destruction - " << getMemoryName() << ": " << e.what()); throw e; } } diff --git a/src/lib/utility/interprocess/SharedMemory.h b/src/lib/utility/interprocess/SharedMemory.h index c444730c..a1fa3919 100644 --- a/src/lib/utility/interprocess/SharedMemory.h +++ b/src/lib/utility/interprocess/SharedMemory.h @@ -42,6 +42,7 @@ public: // Names addressing shared memory objects longer than 29 characters can throw and exception static std::string checkName(const std::string& name); + static std::string checkSharedMemory(const std::string& name); static void deleteSharedMemory(const std::string& name); SharedMemory(const std::string& name, size_t initialMemorySize, AccessMode mode); diff --git a/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp b/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp index f782d3cb..1732880a 100644 --- a/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp +++ b/src/lib/utility/interprocess/SharedMemoryGarbageCollector.cpp @@ -17,9 +17,15 @@ std::shared_ptr SharedMemoryGarbageCollector::s_in SharedMemoryGarbageCollector* SharedMemoryGarbageCollector::createInstance() { - if (!s_instance) + try + { + if (!s_instance) + { + s_instance = std::shared_ptr(new SharedMemoryGarbageCollector()); + } + } + catch (boost::interprocess::interprocess_exception& e) { - s_instance = std::shared_ptr(new SharedMemoryGarbageCollector()); } return s_instance.get();