Skip to content

Commit 73f65ab

Browse files
committed
more work
1 parent a56b59b commit 73f65ab

8 files changed

Lines changed: 154 additions & 8 deletions

File tree

doc/BGPLAN.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
⏺ Background Task System Implementation Plan
2+
3+
1. Task Priority System
4+
5+
- Create an enum class TaskPriority with levels: Critical, High, Normal, Low
6+
- Add priority to AsyncTask to allow scheduling based on importance
7+
- Make analysis tasks lower priority than UI-responsive commands
8+
9+
2. Enhanced Task Manager
10+
11+
- Develop a centralized TaskManager to replace the current AsyncTaskManager
12+
- Implement concurrent command queues with priority scheduling
13+
- Use mutex for radare2 API access for thread safety
14+
- Add task dependencies to prevent race conditions
15+
16+
3. Command Queue System
17+
18+
- Create a serialized command queue for radare2 commands
19+
- Implement mutex-protected access to radare2 API
20+
- Allow UI thread to post quick commands with higher priority
21+
22+
4. Specific Implementation for Key Features
23+
24+
Analysis Tasks:
25+
- Move initial analysis (aa/aaa/aaaa) to background thread
26+
- Add progress reporting via signals
27+
- Allow task interruption with proper cleanup
28+
29+
Debugger Operations:
30+
- Queue stepping/continuation commands
31+
- Allow UI interaction during long-running debug operations
32+
- Implement cancellation for breakpoint resolution
33+
34+
Decompilation:
35+
- Run decompilers in separate threads
36+
- Add caching for faster repeat access
37+
- Enable result streaming for large functions
38+
39+
R2AI Requests:
40+
- Execute network requests asynchronously
41+
- Add timeout and retry handling
42+
- Provide real-time progress indicators
43+
44+
5. UI Integration
45+
46+
- Add persistent task status indicator to main UI
47+
- Create task queue inspector widget
48+
- Implement per-task progress reporting
49+
- Add notification system for task completion
50+
51+
This approach maintains radare2's thread safety while allowing heavy operations to run in background without freezing
52+
the UI.
53+

src/Iaito.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ SOURCES += \
400400
widgets/ZignaturesWidget.cpp \
401401
common/AsyncTask.cpp \
402402
dialogs/AsyncTaskDialog.cpp \
403+
common/UiInitTask.cpp \
403404
widgets/StackWidget.cpp \
404405
widgets/RegistersWidget.cpp \
405406
widgets/ThreadsWidget.cpp \
@@ -576,6 +577,7 @@ HEADERS += \
576577
widgets/ZignaturesWidget.h \
577578
common/AsyncTask.h \
578579
dialogs/AsyncTaskDialog.h \
580+
common/UiInitTask.h \
579581
widgets/StackWidget.h \
580582
widgets/RegistersWidget.h \
581583
widgets/ThreadsWidget.h \

src/common/UiInitTask.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "UiInitTask.h"
2+
#include "core/Iaito.h"
3+
#include "core/MainWindow.h"
4+
#include <QMetaObject>
5+
6+
UiInitTask::UiInitTask(MainWindow *main)
7+
: Task(QObject::tr("UI Initialization"), TaskPriority::Low)
8+
, m_main(main)
9+
{
10+
setCancellable(false);
11+
}
12+
13+
void UiInitTask::run() {
14+
// Load opcodes and update seek position
15+
Core()->getOpcodes();
16+
Core()->updateSeek();
17+
// Trigger all panel refreshes
18+
QMetaObject::invokeMethod(m_main, "refreshAll", Qt::QueuedConnection);
19+
// Show fortune message
20+
QString fortune = Core()->cmdRaw("fo");
21+
if (!fortune.isEmpty()) {
22+
Core()->message("\n" + fortune);
23+
}
24+
}

src/common/UiInitTask.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef UIINITTASK_H
2+
#define UIINITTASK_H
3+
4+
#include "common/TaskManager.h"
5+
#include <QObject>
6+
7+
class MainWindow;
8+
9+
/**
10+
* Background task to initialize UI data (opcodes, seek, panels) after main window shows.
11+
*/
12+
class UiInitTask : public Task {
13+
Q_OBJECT
14+
MainWindow *m_main;
15+
public:
16+
explicit UiInitTask(MainWindow *main);
17+
void run() override;
18+
};
19+
20+
#endif // UIINITTASK_H

src/core/Iaito.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,22 @@ static QString fromOwnedCharPtr(char *str)
151151
return result;
152152
}
153153

154+
// Static control for core mutex locking (enabled by default)
155+
bool RCoreLocked::s_enabled = true;
156+
/** Enable or disable the global core mutex lock */
157+
void RCoreLocked::setEnabled(bool enabled) { s_enabled = enabled; }
158+
/** Check if the global core mutex lock is enabled */
159+
bool RCoreLocked::isEnabled() { return s_enabled; }
160+
154161
RCoreLocked::RCoreLocked(IaitoCore *core)
155162
: core(core)
156163
{
164+
#if 0
165+
// locking is controlled by s_enabled
166+
#endif
167+
if (!RCoreLocked::s_enabled) {
168+
return;
169+
}
157170
core->coreMutex.lock();
158171
#if R2_VERSION_NUMBER < 50609
159172
assert(core->coreLockDepth >= 0);
@@ -169,6 +182,9 @@ RCoreLocked::RCoreLocked(IaitoCore *core)
169182

170183
RCoreLocked::~RCoreLocked()
171184
{
185+
if (!RCoreLocked::s_enabled) {
186+
return;
187+
}
172188
core->coreLockDepth--;
173189
#if R2_VERSION_NUMBER < 50609
174190
assert(core->coreLockDepth >= 0);
@@ -208,6 +224,13 @@ IaitoCore *IaitoCore::instance()
208224
{
209225
return uniqueInstance;
210226
}
227+
// -- Core lock control APIs -----------------------------------------------
228+
void IaitoCore::setCoreLockEnabled(bool enabled) {
229+
RCoreLocked::setEnabled(enabled);
230+
}
231+
bool IaitoCore::isCoreLockEnabled() {
232+
return RCoreLocked::isEnabled();
233+
}
211234

212235
void IaitoCore::initialize(bool loadPlugins)
213236
{

src/core/Iaito.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ class IAITO_EXPORT IaitoCore : public QObject
6262
explicit IaitoCore(QObject *parent = nullptr);
6363
~IaitoCore();
6464
static IaitoCore *instance();
65+
/**
66+
* @brief Enable or disable the global core mutex lock
67+
* @param enabled true to enable locking, false to disable
68+
*/
69+
static void setCoreLockEnabled(bool enabled);
70+
/**
71+
* @brief Check if the global core mutex lock is enabled
72+
* @return true if locking is enabled, false otherwise
73+
*/
74+
static bool isCoreLockEnabled();
6575

6676
void initialize(bool loadPlugins = true);
6777
void loadIaitoRC(int n);
@@ -817,13 +827,26 @@ class IAITO_EXPORT RCoreLocked
817827
IaitoCore *const core;
818828

819829
public:
830+
/**
831+
* Enable or disable the global core mutex lock usage.
832+
* When disabled, CORE_LOCK() calls become no-ops.
833+
*/
834+
static void setEnabled(bool enabled);
835+
/**
836+
* Check whether the global core mutex lock is enabled.
837+
*/
838+
static bool isEnabled();
839+
820840
explicit RCoreLocked(IaitoCore *core);
821841
RCoreLocked(const RCoreLocked &) = delete;
822842
RCoreLocked &operator=(const RCoreLocked &) = delete;
823843
RCoreLocked(RCoreLocked &&);
824844
~RCoreLocked();
825845
operator RCore *() const;
826846
RCore *operator->() const;
847+
private:
848+
/** Internal flag to control locking behavior */
849+
static bool s_enabled;
827850
};
828851

829852
#if R2_VERSION_NUMBER >= 50909

src/core/MainWindow.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
#include "widgets/VTablesWidget.h"
7575
#include "widgets/VisualNavbar.h"
7676
#include "widgets/ZignaturesWidget.h"
77+
#include "common/UiInitTask.h"
78+
#include "common/TaskManager.h"
7779

7880
// Qt Headers
7981
#include <QActionGroup>
@@ -725,12 +727,10 @@ void MainWindow::openProject(const QString &project_name)
725727

726728
void MainWindow::finalizeOpen()
727729
{
728-
// These operations are quick and should be done immediately
729-
core->getOpcodes();
730-
core->updateSeek();
731-
refreshAll();
732-
// Add fortune message
733-
core->message("\n" + core->cmdRaw("fo"));
730+
// Schedule background UI initialization (opcodes, panels refresh, fortune)
731+
// Background initialize opcodes, refresh panels, and show fortune
732+
TaskManager::getInstance()->startTask(
733+
Task::Ptr(new UiInitTask(this)));
734734

735735
// hide all docks before showing window to avoid false positive for
736736
// refreshDeferrer

src/dialogs/InitialOptionsDialog.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <QFileDialog>
1414
#include <QFileInfo>
1515
#include <QSettings>
16+
#include <QTimer> // For scheduling main window initialization after dialog closes
1617

1718
#include "common/AnalTask.h"
1819
#include "core/Iaito.h"
@@ -369,8 +370,8 @@ void InitialOptionsDialog::setupAndStartAnalysis()
369370
// Close the dialog now that the task is started
370371
done(0);
371372

372-
// Call finalizeOpen to set up UI before analysis is complete
373-
mainWindow->finalizeOpen();
373+
// Schedule main window initialization after dialog is closed
374+
QTimer::singleShot(0, mainWindow, &MainWindow::finalizeOpen);
374375
}
375376

376377
void InitialOptionsDialog::on_okButton_clicked()

0 commit comments

Comments
 (0)