forked from openkylin/ukui-search
修复偶现的由于队列处理不当导致的搜索应用崩溃问题。
This commit is contained in:
parent
4fdc102102
commit
a6a5b7846a
|
@ -23,21 +23,21 @@
|
||||||
using namespace UkuiSearch;
|
using namespace UkuiSearch;
|
||||||
SearchResultManager::SearchResultManager(const QString& plugin_id, QObject *parent) : QObject(parent)
|
SearchResultManager::SearchResultManager(const QString& plugin_id, QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
m_plugin_id = plugin_id;
|
m_pluginId = plugin_id;
|
||||||
m_result_queue = new DataQueue<SearchPluginIface::ResultInfo>;
|
m_resultQueue = new DataQueue<SearchPluginIface::ResultInfo>;
|
||||||
m_get_result_thread = new ReceiveResultThread(m_result_queue, this);
|
m_getResultThread = new ReceiveResultThread(m_resultQueue, this);
|
||||||
initConnections();
|
initConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchResultManager::startSearch(const QString &keyword)
|
void SearchResultManager::startSearch(const QString &keyword)
|
||||||
{
|
{
|
||||||
qDebug()<<m_plugin_id<<"started";
|
qDebug()<<m_pluginId<<"started";
|
||||||
if(! m_get_result_thread->isRunning()) {
|
if(! m_getResultThread->isRunning()) {
|
||||||
m_get_result_thread->start();
|
m_getResultThread->start();
|
||||||
}
|
}
|
||||||
m_result_queue->clear();
|
m_resultQueue->clear();
|
||||||
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_pluginId);
|
||||||
plugin->KeywordSearch(keyword, m_result_queue);
|
plugin->KeywordSearch(keyword, m_resultQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,54 +45,49 @@ void SearchResultManager::startSearch(const QString &keyword)
|
||||||
*/
|
*/
|
||||||
void SearchResultManager::stopSearch()
|
void SearchResultManager::stopSearch()
|
||||||
{
|
{
|
||||||
if(m_get_result_thread->isRunning()) {
|
if(m_getResultThread->isRunning()) {
|
||||||
qDebug()<<m_plugin_id<<"stopped";
|
m_getResultThread->stop();
|
||||||
m_get_result_thread->stop();
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_pluginId);
|
||||||
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
|
|
||||||
plugin->stopSearch();
|
plugin->stopSearch();
|
||||||
// m_get_result_thread->quit();
|
qDebug() << m_pluginId << "stopped";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchResultManager::initConnections()
|
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()
|
void ReceiveResultThread::stop()
|
||||||
{
|
{
|
||||||
this->requestInterruption();
|
this->requestInterruption();
|
||||||
this->wait();
|
this->wait();
|
||||||
this->quit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveResultThread::run()
|
void ReceiveResultThread::run()
|
||||||
{
|
{
|
||||||
QTimer *m_timer = new QTimer;
|
QTimer *timer = new QTimer;
|
||||||
m_timer->setInterval(3000);
|
timer->setInterval(3000);
|
||||||
bool is_empty;
|
|
||||||
while(!isInterruptionRequested()) {
|
|
||||||
is_empty = false;
|
|
||||||
if(!m_result_queue->isEmpty()) {
|
|
||||||
Q_EMIT this->gotResultInfo(m_result_queue->dequeue());
|
|
||||||
|
|
||||||
} else {
|
while(!isInterruptionRequested()) {
|
||||||
is_empty = true;
|
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);
|
msleep(100);
|
||||||
|
} else {
|
||||||
|
timer->stop();
|
||||||
|
Q_EMIT gotResultInfo(oneResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timer->isActive() && timer->remainingTime() < 0.01 && m_resultQueue->isEmpty()) {
|
||||||
|
this->requestInterruption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete m_timer;
|
delete m_timer;
|
||||||
|
|
|
@ -25,21 +25,22 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "pluginmanage/search-plugin-manager.h"
|
#include "search-plugin-manager.h"
|
||||||
|
|
||||||
namespace UkuiSearch {
|
namespace UkuiSearch {
|
||||||
|
|
||||||
class ReceiveResultThread : public QThread {
|
class ReceiveResultThread : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * result_queue, QObject * parent = nullptr);
|
ReceiveResultThread(DataQueue<SearchPluginIface::ResultInfo> * resultQueue, QObject * parent = nullptr);
|
||||||
~ReceiveResultThread() = default;
|
~ReceiveResultThread() = default;
|
||||||
void stop();
|
void stop();
|
||||||
protected:
|
protected:
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataQueue<SearchPluginIface::ResultInfo> * m_result_queue;
|
DataQueue<SearchPluginIface::ResultInfo> * m_resultQueue;
|
||||||
|
QTimer *m_timer = nullptr;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
||||||
|
@ -59,9 +60,9 @@ public Q_SLOTS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initConnections();
|
void initConnections();
|
||||||
QString m_plugin_id;
|
QString m_pluginId;
|
||||||
DataQueue<SearchPluginIface::ResultInfo> * m_result_queue;
|
DataQueue<SearchPluginIface::ResultInfo> * m_resultQueue;
|
||||||
ReceiveResultThread * m_get_result_thread = nullptr;
|
ReceiveResultThread * m_getResultThread = nullptr;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
||||||
|
|
|
@ -33,7 +33,6 @@ AppSearchPlugin::AppSearchPlugin(QObject *parent) : QThread(parent), m_appSearch
|
||||||
|
|
||||||
AppSearchPlugin::~AppSearchPlugin()
|
AppSearchPlugin::~AppSearchPlugin()
|
||||||
{
|
{
|
||||||
this->quit();
|
|
||||||
this->wait();
|
this->wait();
|
||||||
|
|
||||||
if (m_timer) {
|
if (m_timer) {
|
||||||
|
@ -161,17 +160,15 @@ QWidget *AppSearchPlugin::detailPage(const ResultInfo &ri)
|
||||||
|
|
||||||
void AppSearchPlugin::run()
|
void AppSearchPlugin::run()
|
||||||
{
|
{
|
||||||
m_timer->setInterval(3000);
|
|
||||||
while(!isInterruptionRequested()) {
|
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()) {
|
if(!m_timer->isActive()) {
|
||||||
m_timer->start();
|
m_timer->start();
|
||||||
}
|
}
|
||||||
|
msleep(100);
|
||||||
} else {
|
} else {
|
||||||
if (m_timer->isActive()) {
|
|
||||||
m_timer->stop();
|
m_timer->stop();
|
||||||
}
|
|
||||||
ResultItem oneResult = m_appSearchResults->dequeue();
|
|
||||||
SearchPluginIface::ResultInfo ri;
|
SearchPluginIface::ResultInfo ri;
|
||||||
ri.actionKey = oneResult.getExtral().at(0).toString();
|
ri.actionKey = oneResult.getExtral().at(0).toString();
|
||||||
ri.name = oneResult.getExtral().at(1).toString();
|
ri.name = oneResult.getExtral().at(1).toString();
|
||||||
|
@ -184,12 +181,9 @@ void AppSearchPlugin::run()
|
||||||
m_searchResult->enqueue(ri);
|
m_searchResult->enqueue(ri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_timer->isActive() && m_timer->remainingTime() < 0.01) {
|
if(m_timer->isActive() && m_timer->remainingTime() < 0.01 && m_appSearchResults->isEmpty()) {
|
||||||
m_timer->setInterval(3000);
|
|
||||||
this->requestInterruption();
|
this->requestInterruption();
|
||||||
}
|
}
|
||||||
|
|
||||||
msleep(100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,14 @@ public:
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
return QList<T>::isEmpty();
|
return QList<T>::isEmpty();
|
||||||
}
|
}
|
||||||
|
inline T tryDequeue() {
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
if(QList<T>::isEmpty()) {
|
||||||
|
return T();
|
||||||
|
} else {
|
||||||
|
return QList<T>::takeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,15 @@ public:
|
||||||
QVector<DescriptionInfo> description;
|
QVector<DescriptionInfo> description;
|
||||||
QString actionKey;
|
QString actionKey;
|
||||||
int type;
|
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() {}
|
virtual ~SearchPluginIface() {}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public:
|
||||||
QVariantList getExtral();
|
QVariantList getExtral();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t m_searchId;
|
size_t m_searchId = 0;
|
||||||
QString m_itemKey;
|
QString m_itemKey;
|
||||||
QVariantList m_extral;
|
QVariantList m_extral;
|
||||||
//and something else...
|
//and something else...
|
||||||
|
|
Loading…
Reference in New Issue