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
pull/22431/head
Dean Lee 4 years ago committed by GitHub
parent 29b9c8f13b
commit 2253cba98b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      selfdrive/ui/replay/main.cc
  2. 22
      selfdrive/ui/replay/replay.cc
  3. 6
      selfdrive/ui/replay/replay.h

@ -1,5 +1,6 @@
#include "selfdrive/ui/replay/replay.h" #include "selfdrive/ui/replay/replay.h"
#include <csignal>
#include <iostream> #include <iostream>
#include <termios.h> #include <termios.h>
@ -10,9 +11,16 @@
const QString DEMO_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36"; 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 getch() {
int ch; int ch;
struct termios oldt;
struct termios newt; struct termios newt;
tcgetattr(STDIN_FILENO, &oldt); tcgetattr(STDIN_FILENO, &oldt);
@ -63,7 +71,9 @@ void keyboardThread(Replay *replay) {
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
QApplication a(argc, argv); QApplication app(argc, argv);
std::signal(SIGINT, sigHandler);
std::signal(SIGTERM, sigHandler);
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("Mock openpilot components by publishing logged messages."); 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({"dcam", "load driver camera"});
parser.addOption({"ecam", "load wide road camera"}); parser.addOption({"ecam", "load wide road camera"});
parser.process(a); parser.process(app);
const QStringList args = parser.positionalArguments(); const QStringList args = parser.positionalArguments();
if (args.empty() && !parser.isSet("demo")) { if (args.empty() && !parser.isSet("demo")) {
parser.showHelp(); parser.showHelp();
@ -86,7 +96,7 @@ int main(int argc, char *argv[]){
QStringList allow = parser.value("allow").isEmpty() ? QStringList{} : parser.value("allow").split(","); QStringList allow = parser.value("allow").isEmpty() ? QStringList{} : parser.value("allow").split(",");
QStringList block = parser.value("block").isEmpty() ? QStringList{} : parser.value("block").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()) { if (replay->load()) {
replay->start(parser.value("start").toInt()); replay->start(parser.value("start").toInt());
} }
@ -96,5 +106,5 @@ int main(int argc, char *argv[]){
QObject::connect(t, &QThread::finished, t, &QThread::deleteLater); QObject::connect(t, &QThread::finished, t, &QThread::deleteLater);
t->start(); t->start();
return a.exec(); return app.exec();
} }

@ -35,7 +35,21 @@ Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *s
} }
Replay::~Replay() { 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() { bool Replay::load() {
@ -54,9 +68,9 @@ void Replay::start(int seconds) {
camera_server_ = std::make_unique<CameraServer>(); camera_server_ = std::make_unique<CameraServer>();
// start stream thread // start stream thread
thread = new QThread; stream_thread_ = new QThread(this);
QObject::connect(thread, &QThread::started, [=]() { stream(); }); QObject::connect(stream_thread_, &QThread::started, [=]() { stream(); });
thread->start(); stream_thread_->start();
} }
void Replay::updateEvents(const std::function<bool()> &lambda) { void Replay::updateEvents(const std::function<bool()> &lambda) {

@ -36,7 +36,7 @@ protected:
void updateEvents(const std::function<bool()>& lambda); void updateEvents(const std::function<bool()>& lambda);
void publishFrame(const Event *e); void publishFrame(const Event *e);
QThread *thread; QThread *stream_thread_ = nullptr;
// logs // logs
std::mutex stream_lock_; std::mutex stream_lock_;
@ -54,8 +54,8 @@ protected:
std::vector<int> segments_merged_; std::vector<int> segments_merged_;
// messaging // messaging
SubMaster *sm; SubMaster *sm = nullptr;
PubMaster *pm; PubMaster *pm = nullptr;
std::vector<const char*> sockets_; std::vector<const char*> sockets_;
std::unique_ptr<Route> route_; std::unique_ptr<Route> route_;
bool load_dcam = false, load_ecam = false; bool load_dcam = false, load_ecam = false;

Loading…
Cancel
Save