Fix webserver deadlock

Removes the ability to stop the webserver, because 1. it's needed for
the graph views to work 2. multiple start/stop calls could lead to a
deadlock, because =h- was waiting for input (^C)

Since =h& is used the server manager class doesn't need to be a QThread
This commit is contained in:
ballessay 2017-05-13 18:39:37 +02:00 committed by C. Balles
parent 6ffb18e6e4
commit a562d5b0b6
4 changed files with 30 additions and 96 deletions

View File

@ -107,7 +107,7 @@ MainWindow::MainWindow(QWidget *parent, QRCore *kore) :
sidebar_action(nullptr), sidebar_action(nullptr),
sectionsDock(nullptr), sectionsDock(nullptr),
consoleWidget(nullptr), consoleWidget(nullptr),
webserverThread(core, this) webserver(core)
{ {
this->start_web_server(); this->start_web_server();
ui->setupUi(this); ui->setupUi(this);
@ -264,8 +264,6 @@ MainWindow::MainWindow(QWidget *parent, QRCore *kore) :
QShortcut *commands_shortcut = new QShortcut(QKeySequence(Qt::Key_Colon), this); QShortcut *commands_shortcut = new QShortcut(QKeySequence(Qt::Key_Colon), this);
connect(commands_shortcut, SIGNAL(activated()), this->omnibar, SLOT(showCommands())); connect(commands_shortcut, SIGNAL(activated()), this->omnibar, SLOT(showCommands()));
connect(&webserverThread, SIGNAL(finished()), this, SLOT(webserverThreadFinished()));
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this); QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshVisibleDockWidgets())); connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshVisibleDockWidgets()));
} }
@ -279,24 +277,15 @@ MainWindow::~MainWindow()
void MainWindow::start_web_server() void MainWindow::start_web_server()
{ {
// Start web server // Start web server
webserverThread.startServer(); webserver.start();
} }
void MainWindow::webserverThreadFinished()
{
core->core()->http_up = webserverThread.isStarted() ? R_TRUE : R_FALSE;
// this is not true anymore, cause the webserver might have been stopped
//if (core->core->http_up == R_FALSE) {
// eprintf("FAILED TO LAUNCH\n");
//}
}
void MainWindow::setWebServerState(bool start) void MainWindow::setWebServerState(bool start)
{ {
if (start) if (start)
{ {
webserverThread.startServer(); webserver.start();
// Open web interface on default browser // Open web interface on default browser
// ballessay: well isn't this possible with =H& // ballessay: well isn't this possible with =H&
@ -305,7 +294,7 @@ void MainWindow::setWebServerState(bool start)
} }
else else
{ {
webserverThread.stopServer(); webserver.stop();
} }
} }

View File

@ -164,8 +164,6 @@ private slots:
void on_actionReset_settings_triggered(); void on_actionReset_settings_triggered();
void webserverThreadFinished();
void on_actionQuit_triggered(); void on_actionQuit_triggered();
void refreshVisibleDockWidgets(); void refreshVisibleDockWidgets();
@ -200,7 +198,7 @@ private:
QAction *sidebar_action; QAction *sidebar_action;
SectionsDock *sectionsDock; SectionsDock *sectionsDock;
ConsoleWidget *consoleWidget; ConsoleWidget *consoleWidget;
WebServerThread webserverThread; RadareWebServer webserver;
RVA cursor_address; RVA cursor_address;

View File

@ -2,83 +2,37 @@
#include "qrcore.h" #include "qrcore.h"
#include <cassert> #include <cassert>
WebServerThread::WebServerThread(QRCore *core, QObject *parent) :
QThread(parent), RadareWebServer::RadareWebServer(QRCore *core) :
core(core), core(core),
started(false) started(false)
{ {
// MEOW // MEOW
} }
WebServerThread::~WebServerThread() RadareWebServer::~RadareWebServer()
{ {
if (isRunning()) }
void RadareWebServer::start()
{
assert(core != nullptr);
if (!started && core != nullptr)
{ {
quit(); // command: see libr/core/rtr.c
wait(); core->cmd("=h&");
core->core()->http_up = R_TRUE;
started = true;
} }
} }
void WebServerThread::startServer() void RadareWebServer::stop()
{ {
assert(nullptr != core); // TODO: =h- waits for ^C
if (!isRunning() && !started)
{
QThread::start();
}
} }
void WebServerThread::stopServer() bool RadareWebServer::isStarted() const
{ {
assert(nullptr != core);
if (!isRunning() && started)
{
QThread::start();
}
}
bool WebServerThread::isStarted() const
{
QMutexLocker locker(&mutex);
return started; return started;
} }
void WebServerThread::run()
{
QMutexLocker locker(&mutex);
if (core == nullptr)
return;
//eprintf ("Starting webserver!");
toggleWebServer();
}
void WebServerThread::toggleWebServer()
{
// access already locked
// see libr/core/rtr.c
// "=h", " port", "listen for http connections (r2 -qc=H /bin/ls)",
// "=h-", "", "stop background webserver",
// "=h*", "", "restart current webserver",
// "=h&", " port", "start http server in background)",
if (started)
{
// after this the only reaction to this commands is:
// sandbox: connect disabled
// and the webserver is still running
// TODO: find out why
core->cmd("=h-");
}
else
{
core->cmd("=h&");
}
// cmd has no usefull return value for this commands, so just toogle the state
started = !started;
}

View File

@ -1,33 +1,26 @@
#ifndef WEBSERVERTHREAD_H #ifndef RADARE_WEBSERVER_H
#define WEBSERVERTHREAD_H #define RADARE_WEBSERVER_H
#include <QThread> #include <QThread>
#include <QMutex> #include <QMutex>
class QRCore; class QRCore;
class WebServerThread : public QThread class RadareWebServer
{ {
Q_OBJECT
public: public:
explicit WebServerThread(QRCore *core, QObject *parent = 0); explicit RadareWebServer(QRCore *core);
~WebServerThread(); ~RadareWebServer();
void startServer(); void start();
void stopServer(); void stop();
bool isStarted() const; bool isStarted() const;
private: private:
void run();
using QThread::start;
void toggleWebServer();
mutable QMutex mutex;
QRCore *core; QRCore *core;
bool started; bool started;
}; };
#endif // WEBSERVERTHREAD_H #endif // RADARE_WEBSERVER_H