Graceful shutdown of MAP65

May wait for current decoding cycle to complete.
This commit is contained in:
Bill Somerville 2021-05-17 22:18:52 +01:00
parent d93b5fc908
commit cc24068106
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
4 changed files with 48 additions and 58 deletions

View File

@ -54,11 +54,8 @@ subroutine m65a
endif
p_m65=>address_m65()
call m65b(p_m65,nbytes)
100 inquire(file=trim(cwd)//'/.lock',exist=fileExists)
if(fileExists) go to 10
call sleep_msec(100)
go to 100
call sleep_msec(500) ! wait for .lock to be recreated
go to 10
999 return
end subroutine m65a

View File

@ -14,26 +14,15 @@ extern "C" {
void four2a_ (_Complex float *, int * nfft, int * ndim, int * isign, int * iform, int len);
}
static QtMessageHandler default_message_handler;
void my_message_handler (QtMsgType type, QMessageLogContext const& context, QString const& msg)
{
// Handle the messages!
// Call the default handler.
(*default_message_handler) (type, context, msg);
}
int main(int argc, char *argv[])
{
default_message_handler = qInstallMessageHandler (my_message_handler);
QApplication a {argc, argv};
// Override programs executable basename as application name.
a.setApplicationName ("MAP65");
a.setApplicationVersion ("3.0.0-devel");
MainWindow w;
w.show ();
QObject::connect (&a, &QApplication::lastWindowClosed, &a, &QApplication::quit);
auto result = a.exec ();
// clean up lazily initialized FFTW3 resources

View File

@ -3,6 +3,7 @@
#include <fftw3.h>
#include <QDir>
#include <QSettings>
#include <QTimer>
#include "revision_utils.hpp"
#include "SettingsGroup.hpp"
#include "widgets/MessageBox.hpp"
@ -46,7 +47,8 @@ MainWindow::MainWindow(QWidget *parent) :
m_astro_window {new Astro {m_settings_filename}},
m_band_map_window {new BandMap {m_settings_filename}},
m_messages_window {new Messages {m_settings_filename}},
m_wide_graph_window {new WideGraph {m_settings_filename}}
m_wide_graph_window {new WideGraph {m_settings_filename}},
m_gui_timer {new QTimer {this}}
{
ui->setupUi(this);
on_EraseButton_clicked();
@ -120,8 +122,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(&proc_editor, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(editor_error()));
QTimer *guiTimer = new QTimer(this);
connect(guiTimer, SIGNAL(timeout()), this, SLOT(guiUpdate()));
connect(m_gui_timer, &QTimer::timeout, this, &MainWindow::guiUpdate);
m_auto=false;
m_waterfallAvg = 1;
@ -131,7 +132,6 @@ MainWindow::MainWindow(QWidget *parent) :
btxok=false;
m_restart=false;
m_transmitting=false;
m_killAll=false;
m_widebandDecode=false;
m_ntx=1;
m_myCall="K1JT";
@ -299,13 +299,13 @@ MainWindow::MainWindow(QWidget *parent) :
if(ui->actionAFMHot->isChecked()) on_actionAFMHot_triggered();
if(ui->actionBlue->isChecked()) on_actionBlue_triggered();
connect (m_messages_window, &Messages::click2OnCallsign, this, &MainWindow::doubleClickOnMessages);
connect (m_wide_graph_window, &WideGraph::freezeDecode2, this, &MainWindow::freezeDecode);
connect (m_wide_graph_window, &WideGraph::f11f12, this, &MainWindow::bumpDF);
connect (m_messages_window.get (), &Messages::click2OnCallsign, this, &MainWindow::doubleClickOnMessages);
connect (m_wide_graph_window.get (), &WideGraph::freezeDecode2, this, &MainWindow::freezeDecode);
connect (m_wide_graph_window.get (), &WideGraph::f11f12, this, &MainWindow::bumpDF);
// only start the guiUpdate timer after this constructor has finished
QTimer::singleShot (0, [=] {
guiTimer->start(100); //Don't change the 100 ms!
m_gui_timer->start(100); //Don't change the 100 ms!
});
}
@ -926,29 +926,37 @@ void MainWindow::on_tolSpinBox_valueChanged(int i) //tolSpinBox
void MainWindow::on_actionExit_triggered() //Exit()
{
OnExit();
close ();
}
void MainWindow::closeEvent(QCloseEvent*)
{
OnExit();
}
void MainWindow::OnExit()
void MainWindow::closeEvent (QCloseEvent * e)
{
if (m_gui_timer) m_gui_timer->stop ();
m_wide_graph_window->saveSettings();
m_killAll=true;
mem_m65.detach();
proc_m65.closeReadChannel (QProcess::StandardOutput);
proc_m65.closeReadChannel (QProcess::StandardError);
QFile quitFile(m_appDir + "/.quit");
quitFile.open(QIODevice::ReadWrite);
QFile lockFile(m_appDir + "/.lock");
lockFile.remove(); // Allow m65 to terminate
bool b=proc_m65.waitForFinished(1000);
if(!b) proc_m65.kill();
// close pipes
proc_m65.closeReadChannel (QProcess::StandardOutput);
proc_m65.closeReadChannel (QProcess::StandardError);
// flush all input
proc_m65.setReadChannel (QProcess::StandardOutput);
proc_m65.readAll ();
proc_m65.setReadChannel (QProcess::StandardError);
proc_m65.readAll ();
// allow time for any decode cycle to finish
if (!proc_m65.waitForFinished ()) proc_m65.kill();
quitFile.remove();
qApp->exit(0); // Exit the event loop
mem_m65.detach();
if (m_astro_window) m_astro_window->close ();
if (m_band_map_window) m_band_map_window->close ();
if (m_messages_window) m_messages_window->close ();
if (m_wide_graph_window) m_wide_graph_window->close ();
QMainWindow::closeEvent (e);
}
void MainWindow::on_stopButton_clicked() //stopButton
@ -1321,18 +1329,14 @@ bool MainWindow::subProcessFailed (QProcess * process, int exit_code, QProcess::
void MainWindow::m65_error (QProcess::ProcessError)
{
if(!m_killAll) {
msgBox("Error starting or running\n" + m_appDir + "/m65 -s\n\n"
+ proc_m65.errorString ());
QTimer::singleShot (0, this, SLOT (close ()));
}
msgBox("Error starting or running\n" + m_appDir + "/m65 -s\n\n"
+ proc_m65.errorString ());
QTimer::singleShot (0, this, SLOT (close ()));
}
void MainWindow::editor_error() //editor_error
{
if(!m_killAll) {
msgBox("Error starting or running\n" + m_appDir + "/" + m_editorCommand);
}
msgBox("Error starting or running\n" + m_appDir + "/" + m_editorCommand);
}
void MainWindow::readFromStdout() //readFromStdout

View File

@ -3,8 +3,8 @@
#include <QtGui>
#include <QtWidgets>
#include <QPointer>
#include <QScopedPointer>
#include <QLabel>
#include <QTimer>
#include <QDateTime>
#include <QHash>
#include <QProcess>
@ -24,6 +24,7 @@ namespace Ui {
class MainWindow;
}
class QTimer;
class Astro;
class BandMap;
class Messages;
@ -52,10 +53,10 @@ public slots:
void doubleClickOnCall(QString hiscall, bool ctrl);
void doubleClickOnMessages(QString hiscall, QString t2);
protected:
virtual void keyPressEvent( QKeyEvent *e );
void closeEvent(QCloseEvent*);
virtual bool eventFilter(QObject *object, QEvent *event);
private:
virtual void keyPressEvent (QKeyEvent *) override;
virtual bool eventFilter (QObject *, QEvent *) override;
virtual void closeEvent (QCloseEvent *) override;
private slots:
void on_tx1_editingFinished();
@ -68,7 +69,6 @@ private slots:
void on_monitorButton_clicked();
void on_actionExit_triggered();
void on_actionAbout_triggered();
void OnExit();
void on_actionLinrad_triggered();
void on_actionCuteSDR_triggered();
void on_autoButton_clicked();
@ -148,10 +148,11 @@ private:
Ui::MainWindow *ui;
QString m_appDir;
QString m_settings_filename;
QPointer<Astro> m_astro_window;
QPointer<BandMap> m_band_map_window;
QPointer<Messages> m_messages_window;
QPointer<WideGraph> m_wide_graph_window;
QScopedPointer<Astro> m_astro_window;
QScopedPointer<BandMap> m_band_map_window;
QScopedPointer<Messages> m_messages_window;
QScopedPointer<WideGraph> m_wide_graph_window;
QPointer<QTimer> m_gui_timer;
qint64 m_msErase;
qint32 m_nDevIn;
qint32 m_nDevOut;
@ -204,7 +205,6 @@ private:
bool m_auto;
bool m_txMute;
bool m_restart;
bool m_killAll;
bool m_xpol;
bool m_xpolx;
bool m_call3Modified;