mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 03:46:11 +00:00
Use AsyncTask for initial analysis
This commit is contained in:
parent
790dd4868e
commit
7117846b3e
@ -1,48 +1,43 @@
|
||||
#include "Cutter.h"
|
||||
#include "AnalThread.h"
|
||||
#include "AnalTask.h"
|
||||
#include "MainWindow.h"
|
||||
#include "dialogs/OptionsDialog.h"
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include <QCheckBox>
|
||||
|
||||
AnalThread::AnalThread(OptionsDialog *parent) :
|
||||
QThread(parent),
|
||||
AnalTask::AnalTask(OptionsDialog *parent) :
|
||||
AsyncTask(parent),
|
||||
level(2),
|
||||
main(nullptr),
|
||||
interrupted(false)
|
||||
main(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
AnalThread::~AnalThread()
|
||||
AnalTask::~AnalTask()
|
||||
{
|
||||
if (isRunning()) {
|
||||
quit();
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
void AnalThread::start(MainWindow *main, int level, QList<QString> advanced)
|
||||
void AnalTask::setSettings(MainWindow *main, int level, QList<QString> advanced)
|
||||
{
|
||||
this->main = main;
|
||||
this->level = level;
|
||||
this->advanced = advanced;
|
||||
this->main = main;
|
||||
|
||||
QThread::start();
|
||||
}
|
||||
|
||||
void AnalThread::interruptAndWait()
|
||||
void AnalTask::interrupt()
|
||||
{
|
||||
interrupted = true;
|
||||
|
||||
while (isRunning()) {
|
||||
r_cons_singleton()->breaked = true;
|
||||
r_sys_usleep(10000);
|
||||
}
|
||||
AsyncTask::interrupt();
|
||||
r_cons_singleton()->breaked = true;
|
||||
}
|
||||
|
||||
// run() will be called when a thread starts
|
||||
void AnalThread::run()
|
||||
void AnalTask::interruptAndWait()
|
||||
{
|
||||
do {
|
||||
interrupt();
|
||||
} while(!wait(10));
|
||||
}
|
||||
|
||||
void AnalTask::runTask()
|
||||
{
|
||||
const auto optionsDialog = dynamic_cast<OptionsDialog *>(parent());
|
||||
const auto &ui = optionsDialog->ui;
|
||||
@ -51,7 +46,7 @@ void AnalThread::run()
|
||||
if (ui->entry_loadOffset->text().length() > 0)
|
||||
binLoadAddr = Core()->math(ui->entry_loadOffset->text());
|
||||
ut64 mapAddr = Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m)
|
||||
interrupted = false;
|
||||
|
||||
emit updateProgress(tr("Loading binary..."));
|
||||
|
||||
// Set the CPU details (handle auto)
|
||||
@ -83,7 +78,7 @@ void AnalThread::run()
|
||||
if (!fileLoaded) {
|
||||
// Something wrong happened, fallback to open dialog
|
||||
emit openFileFailed();
|
||||
interrupted = true;
|
||||
AsyncTask::interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,31 +1,26 @@
|
||||
#ifndef ANALTHREAD_H
|
||||
#define ANALTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include "utils/AsyncTask.h"
|
||||
|
||||
class CutterCore;
|
||||
class MainWindow;
|
||||
class OptionsDialog;
|
||||
|
||||
class AnalThread : public QThread
|
||||
class AnalTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnalThread(OptionsDialog *parent = nullptr);
|
||||
~AnalThread();
|
||||
|
||||
void start(MainWindow *main, int level, QList<QString> advanced);
|
||||
public:
|
||||
explicit AnalTask(OptionsDialog *parent = nullptr);
|
||||
~AnalTask();
|
||||
|
||||
void setSettings(MainWindow *main, int level, QList<QString> advanced);
|
||||
void interrupt() override;
|
||||
void interruptAndWait();
|
||||
|
||||
bool isInterrupted()
|
||||
{
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
using QThread::start;
|
||||
void runTask();
|
||||
|
||||
signals:
|
||||
void updateProgress(QString str);
|
||||
@ -35,8 +30,6 @@ private:
|
||||
int level;
|
||||
QList<QString> advanced;
|
||||
MainWindow *main;
|
||||
|
||||
bool interrupted;
|
||||
};
|
||||
|
||||
#endif // ANALTHREAD_H
|
@ -312,11 +312,9 @@ public:
|
||||
~CutterCore();
|
||||
static CutterCore *getInstance();
|
||||
|
||||
/* Getters */
|
||||
RVA getOffset() const
|
||||
{
|
||||
return core_->offset;
|
||||
}
|
||||
AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; }
|
||||
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
|
||||
static QString sanitizeStringForCommand(QString s);
|
||||
QString cmd(const QString &str);
|
||||
|
@ -107,7 +107,7 @@ SOURCES += \
|
||||
utils/MdHighlighter.cpp \
|
||||
dialogs/preferences/AsmOptionsWidget.cpp \
|
||||
dialogs/NewFileDialog.cpp \
|
||||
AnalThread.cpp \
|
||||
AnalTask.cpp \
|
||||
widgets/CommentsWidget.cpp \
|
||||
widgets/ConsoleWidget.cpp \
|
||||
widgets/Dashboard.cpp \
|
||||
@ -183,7 +183,7 @@ HEADERS += \
|
||||
utils/MdHighlighter.h \
|
||||
dialogs/OptionsDialog.h \
|
||||
dialogs/NewFileDialog.h \
|
||||
AnalThread.h \
|
||||
AnalTask.h \
|
||||
widgets/CommentsWidget.h \
|
||||
widgets/ConsoleWidget.h \
|
||||
widgets/Dashboard.h \
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
OptionsDialog::OptionsDialog(MainWindow *main):
|
||||
QDialog(0), // parent may not be main
|
||||
analThread(this),
|
||||
analTask(this),
|
||||
main(main),
|
||||
core(Core()),
|
||||
defaultAnalLevel(1),
|
||||
@ -61,7 +61,7 @@ OptionsDialog::OptionsDialog(MainWindow *main):
|
||||
// Add this so the dialog resizes when widgets are shown/hidden
|
||||
//this->layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
connect(&analThread, SIGNAL(finished()), this, SLOT(analysisFinished()));
|
||||
connect(&analTask, SIGNAL(finished()), this, SLOT(analysisFinished()));
|
||||
connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
|
||||
ui->programLineEdit->setText(main->getFilename());
|
||||
@ -170,9 +170,10 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList<QString> advanced)
|
||||
connect(&analTimer, SIGNAL(timeout()), this, SLOT(updateProgressTimer()));
|
||||
|
||||
// Threads stuff, connect signal/slot
|
||||
connect(&analThread, &AnalThread::updateProgress, this, &OptionsDialog::updateProgress);
|
||||
connect(&analThread, &AnalThread::openFileFailed, main, &MainWindow::openNewFileFailed);
|
||||
analThread.start(main, level, advanced);
|
||||
connect(&analTask, &AnalTask::updateProgress, this, &OptionsDialog::updateProgress);
|
||||
connect(&analTask, &AnalTask::openFileFailed, main, &MainWindow::openNewFileFailed);
|
||||
analTask.setSettings(main, level, advanced);
|
||||
Core()->getAsyncTaskManager()->start(&analTask);
|
||||
}
|
||||
|
||||
void OptionsDialog::updateProgressTimer()
|
||||
@ -249,7 +250,7 @@ void OptionsDialog::on_okButton_clicked()
|
||||
|
||||
void OptionsDialog::analysisFinished()
|
||||
{
|
||||
if (analThread.isInterrupted()) {
|
||||
if (analTask.isInterrupted()) {
|
||||
updateProgress(tr("Analysis aborted."));
|
||||
done(1);
|
||||
return;
|
||||
@ -264,8 +265,8 @@ void OptionsDialog::analysisFinished()
|
||||
|
||||
void OptionsDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (analThread.isRunning()) {
|
||||
analThread.interruptAndWait();
|
||||
if (analTask.isRunning()) {
|
||||
analTask.interruptAndWait();
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <QElapsedTimer>
|
||||
#include <memory>
|
||||
#include "Cutter.h"
|
||||
#include "AnalThread.h"
|
||||
#include "AnalTask.h"
|
||||
#include "ui_OptionsDialog.h"
|
||||
|
||||
class MainWindow;
|
||||
@ -46,7 +46,7 @@ protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
AnalThread analThread;
|
||||
AnalTask analTask;
|
||||
MainWindow *main;
|
||||
CutterCore *core;
|
||||
int defaultAnalLevel;
|
||||
|
@ -1,10 +1,53 @@
|
||||
|
||||
#include "AsyncTask.h"
|
||||
|
||||
AsyncTask::AsyncTask(QObject *parent)
|
||||
: QObject(parent),
|
||||
QRunnable()
|
||||
{
|
||||
setAutoDelete(false);
|
||||
running = false;
|
||||
}
|
||||
|
||||
AsyncTask::~AsyncTask()
|
||||
{
|
||||
wait();
|
||||
}
|
||||
|
||||
void AsyncTask::wait()
|
||||
{
|
||||
runningMutex.lock();
|
||||
runningMutex.unlock();
|
||||
}
|
||||
|
||||
bool AsyncTask::wait(int timeout)
|
||||
{
|
||||
bool r = runningMutex.tryLock(timeout);
|
||||
if (r) {
|
||||
runningMutex.unlock();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void AsyncTask::interrupt()
|
||||
{
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
void AsyncTask::prepareRun()
|
||||
{
|
||||
interrupted = false;
|
||||
wait();
|
||||
}
|
||||
|
||||
void AsyncTask::run()
|
||||
{
|
||||
runningMutex.lock();
|
||||
running = true;
|
||||
runTask();
|
||||
emit finished();
|
||||
running = false;
|
||||
runningMutex.unlock();
|
||||
}
|
||||
|
||||
AsyncTaskManager::AsyncTaskManager(QObject *parent)
|
||||
@ -19,5 +62,6 @@ AsyncTaskManager::~AsyncTaskManager()
|
||||
|
||||
void AsyncTaskManager::start(AsyncTask *task)
|
||||
{
|
||||
task->prepareRun();
|
||||
threadPool->start(task);
|
||||
}
|
||||
|
@ -4,18 +4,40 @@
|
||||
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <QMutex>
|
||||
|
||||
class AsyncTaskManager;
|
||||
|
||||
class AsyncTask : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class AsyncTaskManager;
|
||||
|
||||
public:
|
||||
AsyncTask(QObject *parent = nullptr);
|
||||
~AsyncTask();
|
||||
|
||||
void run() override final;
|
||||
|
||||
void wait();
|
||||
bool wait(int timeout);
|
||||
virtual void interrupt();
|
||||
bool isInterrupted() { return interrupted; }
|
||||
bool isRunning() { return running; }
|
||||
|
||||
protected:
|
||||
virtual void runTask() =0;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
bool running;
|
||||
bool interrupted;
|
||||
QMutex runningMutex;
|
||||
|
||||
void prepareRun();
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user