fix: the thread crashed when searching edge from bit data

This commit is contained in:
dreamsource-tai 2024-07-26 18:43:32 +08:00
parent a137c03ff0
commit fcc3c01926
4 changed files with 102 additions and 20 deletions

View File

@ -59,6 +59,7 @@ LogicSnapshot::LogicSnapshot() :
_is_loop = false;
_loop_offset = 0;
_able_free = true;
_is_search_stop = false;
}
LogicSnapshot::~LogicSnapshot()
@ -1258,6 +1259,7 @@ bool LogicSnapshot::pattern_search(int64_t start, int64_t end, int64_t& index,
{
std::lock_guard<std::mutex> lock(_mutex);
_is_search_stop = false;
start += _loop_offset;
end += _loop_offset;
index += _loop_offset;
@ -1324,12 +1326,16 @@ bool LogicSnapshot::pattern_search_self(int64_t start, int64_t end, int64_t &ind
index = end;
}
while (index != to)
while (index != to && !_is_search_stop)
{
macthed = 0;
for (int i = 0; i < count; i++)
{
if (_is_search_stop){
break;
}
val = (char)get_sample_self(index, chanIndexs[i]);
if (flagList[i] == '0')

View File

@ -150,6 +150,10 @@ public:
return _loop_offset;
}
inline void cancel_search(){
_is_search_stop = true;
}
int get_block_index_with_sample(uint64_t sample_index, uint64_t *out_offset);
private:
@ -257,6 +261,7 @@ private:
std::vector<void*> _free_block_list;
struct BlockIndex _cur_ref_block_indexs[CHANNEL_MAX_COUNT];
int _lst_free_block_index;
bool _is_search_stop;
friend class LogicSnapshotTest::Pow2;
friend class LogicSnapshotTest::Basic;

View File

@ -38,11 +38,40 @@
#include <QProgressDialog>
#include <QtConcurrent/QtConcurrent>
#include <stdint.h>
#include <QWidget>
#include "../config/appconfig.h"
#include "../ui/langresource.h"
#include "../ui/msgbox.h"
#include "../appcontrol.h"
#include "../ui/fn.h"
#include "../log.h"
class EdgeSearchProgressDialog : public QProgressDialog
{
public:
EdgeSearchProgressDialog(QWidget *parent, QString &title, QString &cancelText)
:QProgressDialog(title, cancelText, 0, 0, parent, Qt::CustomizeWindowHint)
{
}
~EdgeSearchProgressDialog(){
}
protected:
void keyPressEvent(QKeyEvent *event) override
{
if (event->key() == Qt::Key_Escape) {
canceled();
close();
}
else {
QWidget::keyPressEvent(event);
}
}
};
namespace pv {
namespace dock {
@ -55,6 +84,9 @@ SearchDock::SearchDock(QWidget *parent, View &view, SigSession *session) :
_session(session),
_view(view)
{
_is_busy = false;
_is_cancel = false;
_search_button = new QPushButton(this);
_search_button->setFixedWidth(_search_button->height());
_search_button->setDisabled(true);
@ -109,14 +141,16 @@ void SearchDock::reStyle()
void SearchDock::paintEvent(QPaintEvent *)
{
// QStyleOption opt;
// opt.init(this);
// QPainter p(this);
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
void SearchDock::on_previous()
{
if (_is_busy){
dsv_info("The searching task is busy,please wait.");
return;
}
_is_cancel = false;
bool ret;
int64_t last_pos;
bool last_hit;
@ -140,28 +174,35 @@ void SearchDock::on_previous()
}
else {
QFuture<void> future;
future = QtConcurrent::run([&]{
last_pos -= last_hit;
_is_busy = true;
ret = logic_snapshot->pattern_search(0, end, last_pos, _pattern, false);
_is_busy = false;
});
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
QProgressDialog dlg(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_PREVIOUS), "Search Previous..."),
L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"),0,0,this,flags);
QString title = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_PREVIOUS), "Search Previous...");
QString cancelText = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel");
EdgeSearchProgressDialog dlg(this, title, cancelText);
dlg.setWindowModality(Qt::WindowModal);
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
dlg.setCancelButton(NULL);
QFutureWatcher<void> watcher;
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
connect(&watcher, SIGNAL(finished()), &dlg, SLOT(cancel()));
connect(&dlg, SIGNAL(canceled()), SLOT(on_progress_cancel()));
watcher.setFuture(future);
dlg.exec();
if (!ret) {
QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_PATTERN_NOT_FOUND), "Pattern not found!"));
MsgBox::Show(strMsg);
return;
} else {
if (!_is_cancel){
MsgBox::Show(strMsg);
}
}
else {
_view.set_search_pos(last_pos, true);
}
}
@ -169,6 +210,13 @@ void SearchDock::on_previous()
void SearchDock::on_next()
{
if (_is_busy){
dsv_info("The searching task is busy,please wait.");
return;
}
_is_cancel = false;
bool ret;
int64_t last_pos;
const auto snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC);
@ -187,34 +235,54 @@ void SearchDock::on_next()
QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_SEARCH_AT_END), "Search cursor at the end position!"));
MsgBox::Show(strMsg);
return;
} else {
}
else {
QFuture<void> future;
future = QtConcurrent::run([&]{
_is_busy = true;
ret = logic_snapshot->pattern_search(0, end, last_pos, _pattern, true);
_is_busy = false;
});
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
QProgressDialog dlg(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_NEXT), "Search Next..."),
L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"),0,0,this,flags);
QString title = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_NEXT), "Search Next...");
QString cancelText = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel");
EdgeSearchProgressDialog dlg(this, title, cancelText);
dlg.setWindowModality(Qt::WindowModal);
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
dlg.setCancelButton(NULL);
QFutureWatcher<void> watcher;
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
connect(&watcher, SIGNAL(finished()), &dlg, SLOT(cancel()));
connect(&dlg, SIGNAL(canceled()), SLOT(on_progress_cancel()));
watcher.setFuture(future);
dlg.exec();
if (!ret) {
QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_PATTERN_NOT_FOUND), "Pattern not found!"));
MsgBox::Show(strMsg);
return;
} else {
if (!_is_cancel){
MsgBox::Show(strMsg);
}
}
else {
_view.set_search_pos(last_pos, true);
}
}
}
void SearchDock::on_progress_cancel()
{
const auto snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC);
const auto logic_snapshot = dynamic_cast<data::LogicSnapshot*>(snapshot);
_is_cancel = true;
if (logic_snapshot != NULL){
logic_snapshot->cancel_search();
}
}
void SearchDock::on_set()
{
dialogs::Search dlg(this, _session, _pattern);

View File

@ -81,6 +81,7 @@ public slots:
void on_previous();
void on_next();
void on_set();
void on_progress_cancel();
private:
SigSession *_session;
@ -91,6 +92,8 @@ private:
QPushButton _nxt_button;
widgets::FakeLineEdit* _search_value;
QPushButton *_search_button;
bool _is_busy;
bool _is_cancel;
};
} // namespace dock