From 1cae0b8aa90e04473c5c917b5770bbcb872c693b Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Wed, 20 Apr 2016 21:59:22 +0000 Subject: [PATCH] Move temporary directory creation and deletion outside of MainWindow Changing configuration causes WSJT-X and JTAlert to get into a fight for the temporary directory. By moving the creation and clearup of the temporary directory outside of the configurations loop this issue is minimized to no worse than before multiple configurations were added. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6630 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- Configuration.cpp | 46 ++++++++-------------------------------------- Configuration.hpp | 3 ++- main.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------- mainwindow.cpp | 6 +++--- mainwindow.h | 8 ++++---- 5 files changed, 57 insertions(+), 53 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 7dd86ed83..616db6725 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -344,7 +344,8 @@ public: using FrequencyDelta = Radio::FrequencyDelta; using port_type = Configuration::port_type; - explicit impl (Configuration * self, QSettings * settings, QWidget * parent); + explicit impl (Configuration * self, QDir const& temp_directory, + QSettings * settings, QWidget * parent); ~impl (); bool have_rig (); @@ -564,8 +565,9 @@ private: // delegate to implementation class -Configuration::Configuration (QSettings * settings, QWidget * parent) - : m_ {this, settings, parent} +Configuration::Configuration (QDir const& temp_directory, + QSettings * settings, QWidget * parent) + : m_ {this, temp_directory, settings, parent} { } @@ -734,13 +736,15 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s } } -Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget * parent) +Configuration::impl::impl (Configuration * self, QDir const& temp_directory, + QSettings * settings, QWidget * parent) : QDialog {parent} , self_ {self} , ui_ {new Ui::configuration_dialog} , settings_ {settings} , doc_dir_ {QApplication::applicationDirPath ()} , data_dir_ {QApplication::applicationDirPath ()} + , temp_dir_ {temp_directory} , frequencies_ {&bands_} , next_frequencies_ {&bands_} , stations_ {&bands_} @@ -805,39 +809,6 @@ Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget * data_dir_.cd (WSJT_DATA_DESTINATION); #endif - { - // Create a temporary directory in a suitable location - QString temp_location {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}; - if (!temp_location.isEmpty ()) - { - temp_dir_.setPath (temp_location); - } - - bool ok {false}; - QString unique_directory {QApplication::applicationName ()}; - do - { - if (!temp_dir_.mkpath (unique_directory) - || !temp_dir_.cd (unique_directory)) - { - QMessageBox::critical (this, "WSJT-X", tr ("Create temporary directory error: ") + temp_dir_.absolutePath ()); - throw std::runtime_error {"Failed to create a temporary directory"}; - } - if (!temp_dir_.isReadable () || !(ok = QTemporaryFile {temp_dir_.absoluteFilePath ("test")}.open ())) - { - if (QMessageBox::Cancel == QMessageBox::critical (this, "WSJT-X", - tr ("Create temporary directory error:\n%1\n" - "Another application may be locking the directory").arg (temp_dir_.absolutePath ()), - QMessageBox::Retry | QMessageBox::Cancel)) - { - throw std::runtime_error {"Failed to create a usable temporary directory"}; - } - temp_dir_.cdUp (); // revert to parent as this one is no good - } - } - while (!ok); - } - { // Find a suitable data file location QDir data_dir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}; @@ -1034,7 +1005,6 @@ Configuration::impl::~impl () transceiver_thread_->quit (); transceiver_thread_->wait (); write_settings (); - temp_dir_.removeRecursively (); // clean up temp files } void Configuration::impl::initialize_models () diff --git a/Configuration.hpp b/Configuration.hpp index 25efa8f29..4c0f99c44 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -68,7 +68,8 @@ public: enum Type2MsgGen {type_2_msg_1_full, type_2_msg_3_full, type_2_msg_5_only}; Q_ENUM (Type2MsgGen) - explicit Configuration (QSettings * settings, QWidget * parent = nullptr); + explicit Configuration (QDir const& temp_directory, QSettings * settings, + QWidget * parent = nullptr); ~Configuration (); int exec (); diff --git a/main.cpp b/main.cpp index d010036c3..9eb610389 100644 --- a/main.cpp +++ b/main.cpp @@ -158,11 +158,15 @@ int main(int argc, char *argv[]) multiple = true; } + // find the temporary files path + QDir temp_dir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}; + Q_ASSERT (temp_dir.exists ()); // sanity check + // disallow multiple instances with same instance key - QLockFile instance_lock {QDir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}.absoluteFilePath (a.applicationName () + ".lock")}; + QLockFile instance_lock {temp_dir.absoluteFilePath (a.applicationName () + ".lock")}; instance_lock.setStaleLockTime (0); - auto ok = false; - while (!(ok = instance_lock.tryLock ())) + bool lock_ok {false}; + while (!(lock_ok = instance_lock.tryLock ())) { if (QLockFile::LockFailedError == instance_lock.error ()) { @@ -187,14 +191,42 @@ int main(int argc, char *argv[]) } #endif - MultiSettings multi_settings; - #if WSJT_QDEBUG_TO_FILE // Open a trace file - TraceFile trace_file {QDir {QStandardPaths::writableLocation (QStandardPaths::TempLocation)}.absoluteFilePath (a.applicationName () + "_trace.log")}; + TraceFile trace_file {temp_dir.absoluteFilePath (a.applicationName () + "_trace.log")}; qDebug () << program_title (revision ()) + " - Program startup"; #endif + // Create a unique writeable temporary directory in a suitable location + bool temp_ok {false}; + QString unique_directory {QApplication::applicationName ()}; + do + { + if (!temp_dir.mkpath (unique_directory) + || !temp_dir.cd (unique_directory)) + { + QMessageBox::critical (nullptr, + "WSJT-X", + QObject::tr ("Create temporary directory error: ") + temp_dir.absolutePath ()); + throw std::runtime_error {"Failed to create a temporary directory"}; + } + if (!temp_dir.isReadable () || !(temp_ok = QTemporaryFile {temp_dir.absoluteFilePath ("test")}.open ())) + { + if (QMessageBox::Cancel == QMessageBox::critical (nullptr, + "WSJT-X", + QObject::tr ("Create temporary directory error:\n%1\n" + "Another application may be locking the directory").arg (temp_dir.absolutePath ()), + QMessageBox::Retry | QMessageBox::Cancel)) + { + throw std::runtime_error {"Failed to create a usable temporary directory"}; + } + temp_dir.cdUp (); // revert to parent as this one is no good + } + } + while (!temp_ok); + + MultiSettings multi_settings; + int result; do { @@ -251,12 +283,13 @@ int main(int argc, char *argv[]) } // run the application UI - MainWindow w(multiple, &multi_settings, &mem_jt9, downSampleFactor, new QNetworkAccessManager {&a}); + MainWindow w(temp_dir, multiple, &multi_settings, &mem_jt9, downSampleFactor, new QNetworkAccessManager {&a}); w.show(); QObject::connect (&a, SIGNAL (lastWindowClosed()), &a, SLOT (quit())); result = a.exec(); } while (!result && !multi_settings.exit ()); + temp_dir.removeRecursively (); // clean up temp files return result; } catch (std::exception const& e) diff --git a/mainwindow.cpp b/mainwindow.cpp index b60acdec7..4b9b88aec 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -138,8 +138,8 @@ namespace } //--------------------------------------------------- MainWindow constructor -MainWindow::MainWindow(bool multiple, MultiSettings * multi_settings, - QSharedMemory *shdmem, +MainWindow::MainWindow(QDir const& temp_directory, bool multiple, + MultiSettings * multi_settings, QSharedMemory *shdmem, unsigned downSampleFactor, QNetworkAccessManager * network_manager, QWidget *parent) : QMainWindow(parent), @@ -149,7 +149,7 @@ MainWindow::MainWindow(bool multiple, MultiSettings * multi_settings, m_multi_settings {multi_settings}, m_settings {multi_settings->settings ()}, ui(new Ui::MainWindow), - m_config {m_settings, this}, + m_config {temp_directory, m_settings, this}, m_WSPR_band_hopping {m_settings, &m_config, this}, m_WSPR_tx_next {false}, m_wideGraph (new WideGraph(m_settings)), diff --git a/mainwindow.h b/mainwindow.h index 82714c0fc..ffb425fc7 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -82,10 +82,10 @@ public: using FrequencyDelta = Radio::FrequencyDelta; using Mode = Modes::Mode; - // Multiple instances: call MainWindow() with *thekey - explicit MainWindow(bool multiple, MultiSettings *, QSharedMemory *shdmem, - unsigned downSampleFactor, QNetworkAccessManager * network_manager, - QWidget *parent = 0); + explicit MainWindow(QDir const& temp_directory, bool multiple, MultiSettings *, + QSharedMemory *shdmem, unsigned downSampleFactor, + QNetworkAccessManager * network_manager, + QWidget *parent = nullptr); ~MainWindow(); public slots: