修复偶现的由于队列处理不当导致的搜索应用崩溃问题。

This commit is contained in:
iaom 2023-01-21 11:37:39 +08:00
parent 4fdc102102
commit a6a5b7846a
6 changed files with 63 additions and 56 deletions

View File

@ -23,21 +23,21 @@
using namespace UkuiSearch;
SearchResultManager::SearchResultManager(const QString& plugin_id, QObject *parent) : QObject(parent)
{
m_plugin_id = plugin_id;
m_result_queue = new DataQueue<SearchPluginIface::ResultInfo>;
m_get_result_thread = new ReceiveResultThread(m_result_queue, this);
m_pluginId = plugin_id;
m_resultQueue = new DataQueue<SearchPluginIface::ResultInfo>;
m_getResultThread = new ReceiveResultThread(m_resultQueue, this);
initConnections();
}
void SearchResultManager::startSearch(const QString &keyword)
{
qDebug()<<m_plugin_id<<"started";
if(! m_get_result_thread->isRunning()) {
m_get_result_thread->start();
qDebug()<<m_pluginId<<"started";
if(! m_getResultThread->isRunning()) {
m_getResultThread->start();
}
m_result_queue->clear();
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
plugin->KeywordSearch(keyword, m_result_queue);
m_resultQueue->clear();
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_pluginId);
plugin->KeywordSearch(keyword, m_resultQueue);
}
/**
@ -45,54 +45,49 @@ void SearchResultManager::startSearch(const QString &keyword)
*/
void SearchResultManager::stopSearch()
{
if(m_get_result_thread->isRunning()) {
qDebug()<<m_plugin_id<<"stopped";
m_get_result_thread->stop();
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
if(m_getResultThread->isRunning()) {
m_getResultThread->stop();
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_pluginId);
plugin->stopSearch();
// m_get_result_thread->quit();
qDebug() << m_pluginId << "stopped";
}
}
void SearchResultManager::initConnections()
{
connect(m_get_result_thread, &ReceiveResultThread::gotResultInfo, this, &SearchResultManager::gotResultInfo);
connect(m_getResultThread, &ReceiveResultThread::gotResultInfo, this, &SearchResultManager::gotResultInfo);
}
ReceiveResultThread::ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * result_queue, QObject *parent)
ReceiveResultThread::ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * resultQueue, QObject *parent): QThread(parent)
{
m_result_queue = result_queue;
m_resultQueue = resultQueue;
}
void ReceiveResultThread::stop()
{
this->requestInterruption();
this->wait();
this->quit();
}
void ReceiveResultThread::run()
{
QTimer *m_timer = new QTimer;
m_timer->setInterval(3000);
bool is_empty;
while(!isInterruptionRequested()) {
is_empty = false;
if(!m_result_queue->isEmpty()) {
Q_EMIT this->gotResultInfo(m_result_queue->dequeue());
QTimer *timer = new QTimer;
timer->setInterval(3000);
} else {
is_empty = true;
while(!isInterruptionRequested()) {
SearchPluginIface::ResultInfo oneResult = m_resultQueue->tryDequeue();
if(oneResult.name.isEmpty()) {
if(!timer->isActive()) {
timer->start();
}
if(m_timer->isActive() && m_timer->remainingTime() < 0.01) {
this->requestInterruption();
}
if(is_empty && !m_timer->isActive()) {
m_timer->start();
} else if(!is_empty) {
m_timer->stop();
} else {
msleep(100);
} else {
timer->stop();
Q_EMIT gotResultInfo(oneResult);
}
if(timer->isActive() && timer->remainingTime() < 0.01 && m_resultQueue->isEmpty()) {
this->requestInterruption();
}
}
delete m_timer;

View File

@ -25,21 +25,22 @@
#include <QThread>
#include <QTimer>
#include <QDebug>
#include "pluginmanage/search-plugin-manager.h"
#include "search-plugin-manager.h"
namespace UkuiSearch {
class ReceiveResultThread : public QThread {
Q_OBJECT
public:
ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * result_queue, QObject * parent = nullptr);
ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * resultQueue, QObject * parent = nullptr);
~ReceiveResultThread() = default;
void stop();
protected:
void run() override;
private:
DataQueue<SearchPluginIface::ResultInfo> * m_result_queue;
DataQueue<SearchPluginIface::ResultInfo> * m_resultQueue;
QTimer *m_timer = nullptr;
Q_SIGNALS:
void gotResultInfo(const SearchPluginIface::ResultInfo&);
@ -59,9 +60,9 @@ public Q_SLOTS:
private:
void initConnections();
QString m_plugin_id;
DataQueue<SearchPluginIface::ResultInfo> * m_result_queue;
ReceiveResultThread * m_get_result_thread = nullptr;
QString m_pluginId;
DataQueue<SearchPluginIface::ResultInfo> * m_resultQueue;
ReceiveResultThread * m_getResultThread = nullptr;
Q_SIGNALS:
void gotResultInfo(const SearchPluginIface::ResultInfo&);

View File

@ -33,7 +33,6 @@ AppSearchPlugin::AppSearchPlugin(QObject *parent) : QThread(parent), m_appSearch
AppSearchPlugin::~AppSearchPlugin()
{
this->quit();
this->wait();
if (m_timer) {
@ -161,17 +160,15 @@ QWidget *AppSearchPlugin::detailPage(const ResultInfo &ri)
void AppSearchPlugin::run()
{
m_timer->setInterval(3000);
while(!isInterruptionRequested()) {
if (m_appSearchResults->isEmpty()) {
ResultItem oneResult = m_appSearchResults->tryDequeue();
if(oneResult.getSearchId() == 0 && oneResult.getItemKey().isEmpty() && oneResult.getExtral().isEmpty()) {
if(!m_timer->isActive()) {
m_timer->start();
}
msleep(100);
} else {
if (m_timer->isActive()) {
m_timer->stop();
}
ResultItem oneResult = m_appSearchResults->dequeue();
SearchPluginIface::ResultInfo ri;
ri.actionKey = oneResult.getExtral().at(0).toString();
ri.name = oneResult.getExtral().at(1).toString();
@ -184,12 +181,9 @@ void AppSearchPlugin::run()
m_searchResult->enqueue(ri);
}
if (m_timer->isActive() && m_timer->remainingTime() < 0.01) {
m_timer->setInterval(3000);
if(m_timer->isActive() && m_timer->remainingTime() < 0.01 && m_appSearchResults->isEmpty()) {
this->requestInterruption();
}
msleep(100);
}
}

View File

@ -27,6 +27,14 @@ public:
QMutexLocker locker(&m_mutex);
return QList<T>::isEmpty();
}
inline T tryDequeue() {
QMutexLocker locker(&m_mutex);
if(QList<T>::isEmpty()) {
return T();
} else {
return QList<T>::takeFirst();
}
}
private:
QMutex m_mutex;
};

View File

@ -42,6 +42,15 @@ public:
QVector<DescriptionInfo> description;
QString actionKey;
int type;
ResultInfo(const QIcon &iconToSet = QIcon(), const QString &nameToSet = QString(),
const QVector<DescriptionInfo> &descriptionToSet = QVector<DescriptionInfo>(),
const QString &actionKeyToSet = QString(), const int &typeToSet = 0) {
icon = iconToSet;
name = nameToSet;
description = descriptionToSet;
actionKey = actionKeyToSet;
type = typeToSet;
}
};
virtual ~SearchPluginIface() {}

View File

@ -16,7 +16,7 @@ public:
QVariantList getExtral();
private:
size_t m_searchId;
size_t m_searchId = 0;
QString m_itemKey;
QVariantList m_extral;
//and something else...