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
This commit is contained in:
Bill Somerville 2016-04-20 21:59:22 +00:00
parent e6c59a42b5
commit 1cae0b8aa9
5 changed files with 57 additions and 53 deletions

View File

@ -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 ()

View File

@ -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 ();

View File

@ -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)

View File

@ -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)),

View File

@ -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: