From 7b3200362b686fab4cf8b54ed694ed9266a39b51 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 5 Oct 2021 00:00:49 +0800 Subject: [PATCH] c++ replay: graceful shutdown (#22280) * graceful shutdown * reset termios * continue * call clear in dctor * unpause * delete vipc_server * relase context * notify_one * merge master * merge master * print vipc stop listen before shutdown down old-commit-hash: 2253cba98bcc1cf5799567fc9050f10871ddce1d --- selfdrive/ui/replay/main.cc | 20 +++++++++++++++----- selfdrive/ui/replay/replay.cc | 22 ++++++++++++++++++---- selfdrive/ui/replay/replay.h | 6 +++--- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/selfdrive/ui/replay/main.cc b/selfdrive/ui/replay/main.cc index 54853172cd..1bb4344956 100644 --- a/selfdrive/ui/replay/main.cc +++ b/selfdrive/ui/replay/main.cc @@ -1,5 +1,6 @@ #include "selfdrive/ui/replay/replay.h" +#include #include #include @@ -10,9 +11,16 @@ const QString DEMO_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36"; +struct termios oldt = {}; + +void sigHandler(int s) { + std::signal(s, SIG_DFL); + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + qApp->quit(); +} + int getch() { int ch; - struct termios oldt; struct termios newt; tcgetattr(STDIN_FILENO, &oldt); @@ -63,7 +71,9 @@ void keyboardThread(Replay *replay) { } int main(int argc, char *argv[]){ - QApplication a(argc, argv); + QApplication app(argc, argv); + std::signal(SIGINT, sigHandler); + std::signal(SIGTERM, sigHandler); QCommandLineParser parser; parser.setApplicationDescription("Mock openpilot components by publishing logged messages."); @@ -76,7 +86,7 @@ int main(int argc, char *argv[]){ parser.addOption({"dcam", "load driver camera"}); parser.addOption({"ecam", "load wide road camera"}); - parser.process(a); + parser.process(app); const QStringList args = parser.positionalArguments(); if (args.empty() && !parser.isSet("demo")) { parser.showHelp(); @@ -86,7 +96,7 @@ int main(int argc, char *argv[]){ QStringList allow = parser.value("allow").isEmpty() ? QStringList{} : parser.value("allow").split(","); QStringList block = parser.value("block").isEmpty() ? QStringList{} : parser.value("block").split(","); - Replay *replay = new Replay(route, allow, block, nullptr, parser.isSet("dcam"), parser.isSet("ecam")); + Replay *replay = new Replay(route, allow, block, nullptr, parser.isSet("dcam"), parser.isSet("ecam"), &app); if (replay->load()) { replay->start(parser.value("start").toInt()); } @@ -96,5 +106,5 @@ int main(int argc, char *argv[]){ QObject::connect(t, &QThread::finished, t, &QThread::deleteLater); t->start(); - return a.exec(); + return app.exec(); } diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc index 838495df3d..532b3daf80 100644 --- a/selfdrive/ui/replay/replay.cc +++ b/selfdrive/ui/replay/replay.cc @@ -35,7 +35,21 @@ Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *s } Replay::~Replay() { - // TODO: quit stream thread and free resources. + qDebug() << "shutdown: in progress..."; + + exit_ = true; + updating_events_ = true; + if (stream_thread_) { + stream_cv_.notify_one(); + stream_thread_->quit(); + stream_thread_->wait(); + } + + delete pm; + delete events_; + segments_.clear(); + camera_server_.reset(nullptr); + qDebug() << "shutdown: done"; } bool Replay::load() { @@ -54,9 +68,9 @@ void Replay::start(int seconds) { camera_server_ = std::make_unique(); // start stream thread - thread = new QThread; - QObject::connect(thread, &QThread::started, [=]() { stream(); }); - thread->start(); + stream_thread_ = new QThread(this); + QObject::connect(stream_thread_, &QThread::started, [=]() { stream(); }); + stream_thread_->start(); } void Replay::updateEvents(const std::function &lambda) { diff --git a/selfdrive/ui/replay/replay.h b/selfdrive/ui/replay/replay.h index a9151b2d43..65f4cc5cfc 100644 --- a/selfdrive/ui/replay/replay.h +++ b/selfdrive/ui/replay/replay.h @@ -36,7 +36,7 @@ protected: void updateEvents(const std::function& lambda); void publishFrame(const Event *e); - QThread *thread; + QThread *stream_thread_ = nullptr; // logs std::mutex stream_lock_; @@ -54,8 +54,8 @@ protected: std::vector segments_merged_; // messaging - SubMaster *sm; - PubMaster *pm; + SubMaster *sm = nullptr; + PubMaster *pm = nullptr; std::vector sockets_; std::unique_ptr route_; bool load_dcam = false, load_ecam = false;