forked from osmocom/wireshark
Qt: stop capture syntax worker thread on exit
Instead of creating endless loop and synchronizing using QWaitCondition, execute the syntax worker check in its thread by emitting signal. The syntax worker thread affinity is set to worker thread so the slots handling takes place within the worker thread context.
This commit is contained in:
parent
dd8c23c83d
commit
e9533a3f5d
|
@ -34,7 +34,7 @@ static QMutex pcap_compile_mtx_;
|
||||||
#if 0
|
#if 0
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#define DEBUG_SYNTAX_CHECK(state1, state2) qDebug() << "CF state" << QThread::currentThreadId() << state1 << "->" << state2 << ":" << filter_text_ << ":" << filter
|
#define DEBUG_SYNTAX_CHECK(state1, state2) qDebug() << "CF state" << QThread::currentThreadId() << state1 << "->" << state2 << ":" << filter
|
||||||
#define DEBUG_SLEEP_TIME 5000 // ms
|
#define DEBUG_SLEEP_TIME 5000 // ms
|
||||||
#else
|
#else
|
||||||
#define DEBUG_SYNTAX_CHECK(state1, state2)
|
#define DEBUG_SYNTAX_CHECK(state1, state2)
|
||||||
|
@ -44,10 +44,9 @@ static QMutex pcap_compile_mtx_;
|
||||||
#define DUMMY_SNAPLENGTH 65535
|
#define DUMMY_SNAPLENGTH 65535
|
||||||
#define DUMMY_NETMASK 0xFF000000
|
#define DUMMY_NETMASK 0xFF000000
|
||||||
|
|
||||||
void CaptureFilterSyntaxWorker::start() {
|
void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
|
||||||
|
{
|
||||||
#ifdef HAVE_LIBPCAP
|
#ifdef HAVE_LIBPCAP
|
||||||
forever {
|
|
||||||
QString filter;
|
|
||||||
QSet<gint> active_dlts;
|
QSet<gint> active_dlts;
|
||||||
QSet<guint> active_extcap;
|
QSet<guint> active_extcap;
|
||||||
struct bpf_program fcode;
|
struct bpf_program fcode;
|
||||||
|
@ -56,20 +55,12 @@ void CaptureFilterSyntaxWorker::start() {
|
||||||
enum SyntaxLineEdit::SyntaxState state = SyntaxLineEdit::Valid;
|
enum SyntaxLineEdit::SyntaxState state = SyntaxLineEdit::Valid;
|
||||||
QString err_str;
|
QString err_str;
|
||||||
|
|
||||||
data_mtx_.lock();
|
DEBUG_SYNTAX_CHECK("received", "?");
|
||||||
while (filter_text_.isEmpty()) {
|
|
||||||
data_cond_.wait(&data_mtx_);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_SYNTAX_CHECK("pending", "unknown");
|
|
||||||
filter = filter_text_;
|
|
||||||
filter_text_ = QString();
|
|
||||||
data_mtx_.unlock();
|
|
||||||
|
|
||||||
if (global_capture_opts.num_selected < 1) {
|
if (global_capture_opts.num_selected < 1) {
|
||||||
emit syntaxResult(filter, SyntaxLineEdit::Invalid, QString("No interfaces selected"));
|
emit syntaxResult(filter, SyntaxLineEdit::Invalid, QString("No interfaces selected"));
|
||||||
DEBUG_SYNTAX_CHECK("unknown", "no interfaces");
|
DEBUG_SYNTAX_CHECK("unknown", "no interfaces");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
|
for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
|
||||||
|
@ -147,18 +138,6 @@ void CaptureFilterSyntaxWorker::start() {
|
||||||
emit syntaxResult(filter, state, err_str);
|
emit syntaxResult(filter, state, err_str);
|
||||||
|
|
||||||
DEBUG_SYNTAX_CHECK("known", "idle");
|
DEBUG_SYNTAX_CHECK("known", "idle");
|
||||||
}
|
|
||||||
#endif // HAVE_LIBPCAP
|
|
||||||
}
|
|
||||||
|
|
||||||
void CaptureFilterSyntaxWorker::checkFilter(const QString &filter)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_LIBPCAP
|
|
||||||
QMutexLocker ml(&data_mtx_);
|
|
||||||
/* Ruthlessly clobber the current state. */
|
|
||||||
filter_text_ = filter;
|
|
||||||
DEBUG_SYNTAX_CHECK("received", "?");
|
|
||||||
data_cond_.wakeOne();
|
|
||||||
#else
|
#else
|
||||||
emit syntaxResult(filter, SyntaxLineEdit::Deprecated, QString("Syntax checking unavailable"));
|
emit syntaxResult(filter, SyntaxLineEdit::Deprecated, QString("Syntax checking unavailable"));
|
||||||
#endif // HAVE_LIBPCAP
|
#endif // HAVE_LIBPCAP
|
||||||
|
|
|
@ -20,15 +20,9 @@ class CaptureFilterSyntaxWorker : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CaptureFilterSyntaxWorker(QObject *parent = 0) : QObject(parent) {}
|
CaptureFilterSyntaxWorker(QObject *parent = 0) : QObject(parent) {}
|
||||||
void checkFilter(const QString &filter);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void start();
|
void checkFilter(const QString filter);
|
||||||
|
|
||||||
private:
|
|
||||||
QMutex data_mtx_;
|
|
||||||
QWaitCondition data_cond_;
|
|
||||||
QString filter_text_;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void syntaxResult(QString filter, int state, QString err_msg);
|
void syntaxResult(QString filter, int state, QString err_msg);
|
||||||
|
|
|
@ -218,21 +218,28 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QThread *syntax_thread = new QThread;
|
syntax_thread_ = new QThread;
|
||||||
syntax_worker_ = new CaptureFilterSyntaxWorker;
|
syntax_worker_ = new CaptureFilterSyntaxWorker;
|
||||||
syntax_worker_->moveToThread(syntax_thread);
|
syntax_worker_->moveToThread(syntax_thread_);
|
||||||
connect(wsApp, &WiresharkApplication::appInitialized, this, &CaptureFilterEdit::updateBookmarkMenu);
|
connect(wsApp, &WiresharkApplication::appInitialized, this, &CaptureFilterEdit::updateBookmarkMenu);
|
||||||
connect(wsApp, &WiresharkApplication::captureFilterListChanged, this, &CaptureFilterEdit::updateBookmarkMenu);
|
connect(wsApp, &WiresharkApplication::captureFilterListChanged, this, &CaptureFilterEdit::updateBookmarkMenu);
|
||||||
connect(syntax_thread, &QThread::started, syntax_worker_, &CaptureFilterSyntaxWorker::start);
|
connect(syntax_thread_, &QThread::started, this,
|
||||||
connect(syntax_thread, &QThread::started, this,
|
|
||||||
static_cast<void (CaptureFilterEdit::*)()>(&CaptureFilterEdit::checkFilter));
|
static_cast<void (CaptureFilterEdit::*)()>(&CaptureFilterEdit::checkFilter));
|
||||||
connect(syntax_worker_, &CaptureFilterSyntaxWorker::syntaxResult,
|
connect(syntax_worker_, &CaptureFilterSyntaxWorker::syntaxResult,
|
||||||
this, &CaptureFilterEdit::setFilterSyntaxState);
|
this, &CaptureFilterEdit::setFilterSyntaxState);
|
||||||
connect(syntax_thread, &QThread::finished, syntax_worker_, &CaptureFilterSyntaxWorker::deleteLater);
|
connect(this, &CaptureFilterEdit::captureFilterChanged, syntax_worker_, &CaptureFilterSyntaxWorker::checkFilter);
|
||||||
syntax_thread->start();
|
syntax_thread_->start();
|
||||||
updateBookmarkMenu();
|
updateBookmarkMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CaptureFilterEdit::~CaptureFilterEdit()
|
||||||
|
{
|
||||||
|
syntax_thread_->quit();
|
||||||
|
syntax_thread_->wait();
|
||||||
|
delete syntax_thread_;
|
||||||
|
delete syntax_worker_;
|
||||||
|
}
|
||||||
|
|
||||||
void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
|
void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
|
||||||
SyntaxLineEdit::paintEvent(evt);
|
SyntaxLineEdit::paintEvent(evt);
|
||||||
|
|
||||||
|
@ -366,7 +373,7 @@ void CaptureFilterEdit::checkFilter(const QString& filter)
|
||||||
if (empty) {
|
if (empty) {
|
||||||
setFilterSyntaxState(filter, Empty, QString());
|
setFilterSyntaxState(filter, Empty, QString());
|
||||||
} else {
|
} else {
|
||||||
syntax_worker_->checkFilter(filter);
|
emit captureFilterChanged(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class CaptureFilterEdit : public SyntaxLineEdit
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CaptureFilterEdit(QWidget *parent = 0, bool plain = false);
|
explicit CaptureFilterEdit(QWidget *parent = 0, bool plain = false);
|
||||||
|
~CaptureFilterEdit();
|
||||||
void setConflict(bool conflict = false);
|
void setConflict(bool conflict = false);
|
||||||
// No selections: (QString(), false)
|
// No selections: (QString(), false)
|
||||||
// Selections, same filter: (filter, false)
|
// Selections, same filter: (filter, false)
|
||||||
|
@ -63,11 +64,13 @@ private:
|
||||||
StockIconToolButton *clear_button_;
|
StockIconToolButton *clear_button_;
|
||||||
StockIconToolButton *apply_button_;
|
StockIconToolButton *apply_button_;
|
||||||
CaptureFilterSyntaxWorker *syntax_worker_;
|
CaptureFilterSyntaxWorker *syntax_worker_;
|
||||||
|
QThread *syntax_thread_;
|
||||||
|
|
||||||
void buildCompletionList(const QString& primitive_word);
|
void buildCompletionList(const QString& primitive_word);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void captureFilterSyntaxChanged(bool valid);
|
void captureFilterSyntaxChanged(bool valid);
|
||||||
|
void captureFilterChanged(const QString filter);
|
||||||
void startCapture();
|
void startCapture();
|
||||||
void addBookmark(const QString filter);
|
void addBookmark(const QString filter);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue