diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 32101ce3b0..574da62bd2 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -2172,46 +2172,51 @@ void setAppNameAndIcon() void tryRunEventLoop(GUISingleApplication& mainApp) { - std::stringstream s; - s << App::Application::getUserCachePath() << App::Application::getExecutableName() << "_" - << QCoreApplication::applicationPid() << ".lock"; + std::stringstream out; + out << App::Application::getUserCachePath() + << App::Application::getExecutableName() + << "_" + << QCoreApplication::applicationPid() + << ".lock"; + // open a lock file with the PID - Base::FileInfo fi(s.str()); + Base::FileInfo fi(out.str()); Base::ofstream lock(fi); // In case the file_lock cannot be created start FreeCAD without IPC support. #if !defined(FC_OS_WIN32) || (BOOST_VERSION < 107600) - std::string filename = s.str(); + std::string filename = out.str(); #else std::wstring filename = fi.toStdWString(); #endif - std::unique_ptr flock; try { - flock = std::make_unique(filename.c_str()); - flock->lock(); + boost::interprocess::file_lock flock(filename.c_str()); + if (flock.try_lock()) { + Base::Console().Log("Init: Executing event loop...\n"); + QApplication::exec(); + + // Qt can't handle exceptions thrown from event handlers, so we need + // to manually rethrow SystemExitExceptions. + if (mainApp.caughtException) { + throw Base::SystemExitException(*mainApp.caughtException.get()); + } + + // close the lock file, in case of a crash we can see the existing lock file + // on the next restart and try to repair the documents, if needed. + flock.unlock(); + lock.close(); + fi.deleteFile(); + } + else { + Base::Console().Warning("Failed to create a file lock for the IPC.\n" + "The application will be terminated\n"); + } } catch (const boost::interprocess::interprocess_exception& e) { QString msg = QString::fromLocal8Bit(e.what()); Base::Console().Warning("Failed to create a file lock for the IPC: %s\n", msg.toUtf8().constData()); } - - Base::Console().Log("Init: Executing event loop...\n"); - QApplication::exec(); - - // Qt can't handle exceptions thrown from event handlers, so we need - // to manually rethrow SystemExitExceptions. - if (mainApp.caughtException) { - throw Base::SystemExitException(*mainApp.caughtException.get()); - } - - // close the lock file, in case of a crash we can see the existing lock file - // on the next restart and try to repair the documents, if needed. - if (flock) { - flock->unlock(); - } - lock.close(); - fi.deleteFile(); } void runEventLoop(GUISingleApplication& mainApp) diff --git a/src/Gui/DocumentRecovery.cpp b/src/Gui/DocumentRecovery.cpp index d74fdf2016..f4dd67c030 100644 --- a/src/Gui/DocumentRecovery.cpp +++ b/src/Gui/DocumentRecovery.cpp @@ -651,12 +651,12 @@ void DocumentRecoveryHandler::checkForPreviousCrashes(const std::function locks = tmp.entryInfoList(); - for (QList::iterator it = locks.begin(); it != locks.end(); ++it) { - QString bn = it->baseName(); + for (const QFileInfo& it : locks) { + QString bn = it.baseName(); // ignore the lock file for this instance QString pid = QString::number(QCoreApplication::applicationPid()); if (bn.startsWith(exeName) && bn.indexOf(pid) < 0) { - QString fn = it->absoluteFilePath(); + QString fn = it.absoluteFilePath(); #if !defined(FC_OS_WIN32) || (BOOST_VERSION < 107600) boost::interprocess::file_lock flock(fn.toUtf8()); @@ -665,7 +665,7 @@ void DocumentRecoveryHandler::checkForPreviousCrashes(const std::function dirs = tmp.entryInfoList(); - callableFunc(tmp, dirs, it->fileName()); + callableFunc(tmp, dirs, it.fileName()); + } + else { + Base::Console().Warning("Failed to lock file %s\n", fn.toUtf8().constData()); } } }