Use a shared_ptr to make sure that the rcldb referenced by the current query remains valid

This commit is contained in:
Jean-Francois Dockes 2019-04-11 15:05:44 +02:00
parent 1a1e59520d
commit 9e61f25b17
13 changed files with 48 additions and 54 deletions

View File

@ -81,7 +81,7 @@ void deleteAllTempFiles()
Uncomp::clearcache(); Uncomp::clearcache();
} }
Rcl::Db *rcldb; std::shared_ptr<Rcl::Db> rcldb;
int recollNeedsExit; int recollNeedsExit;
RclMain *mainWindow; RclMain *mainWindow;
@ -96,8 +96,7 @@ bool maybeOpenDb(string &reason, bool force, bool *maindberror)
LOGDEB2("maybeOpenDb: force " << force << "\n"); LOGDEB2("maybeOpenDb: force " << force << "\n");
if (force) { if (force) {
delete rcldb; rcldb = std::shared_ptr<Rcl::Db>(new Rcl::Db(theconfig));
rcldb = new Rcl::Db(theconfig);
} }
rcldb->rmQueryDb(""); rcldb->rmQueryDb("");
for (const auto& dbdir : prefs.activeExtraDbs) { for (const auto& dbdir : prefs.activeExtraDbs) {
@ -142,10 +141,11 @@ bool getStemLangs(vector<string>& vlangs)
} }
} }
// This is never called because we _Exit() in rclmain_w.cpp
static void recollCleanup() static void recollCleanup()
{ {
LOGDEB2("recollCleanup: closing database\n" ); LOGDEB2("recollCleanup: closing database\n" );
deleteZ(rcldb); rcldb.reset();
deleteZ(theconfig); deleteZ(theconfig);
deleteAllTempFiles(); deleteAllTempFiles();

View File

@ -859,7 +859,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
// Enter document in document history // Enter document in document history
historyEnterDoc(rcldb, g_dynconf, idoc); historyEnterDoc(rcldb.get(), g_dynconf, idoc);
editor->setFocus(); editor->setFocus();
emit(previewExposed(this, m_searchId, docnum)); emit(previewExposed(this, m_searchId, docnum));

View File

@ -67,10 +67,10 @@ void RclMain::viewUrl()
return; return;
// StartNativeViewer needs a db source to call getEnclosing() on. // StartNativeViewer needs a db source to call getEnclosing() on.
Rcl::Query *query = new Rcl::Query(rcldb); Rcl::Query *query = new Rcl::Query(rcldb.get());
DocSequenceDb *src = DocSequenceDb *src = new DocSequenceDb(
new DocSequenceDb(std::shared_ptr<Rcl::Query>(query), "", rcldb, std::shared_ptr<Rcl::Query>(query), "",
std::shared_ptr<Rcl::SearchData>(new Rcl::SearchData)); std::shared_ptr<Rcl::SearchData>(new Rcl::SearchData));
m_source = std::shared_ptr<DocSequence>(src); m_source = std::shared_ptr<DocSequence>(src);
@ -458,7 +458,7 @@ void RclMain::execViewer(const map<string, string>& subs, bool enterHistory,
} }
if (enterHistory) if (enterHistory)
historyEnterDoc(rcldb, g_dynconf, doc); historyEnterDoc(rcldb.get(), g_dynconf, doc);
// Do the zeitgeist thing // Do the zeitgeist thing
zg_send_event(ZGSEND_OPEN, doc); zg_send_event(ZGSEND_OPEN, doc);

View File

@ -736,12 +736,12 @@ void RclMain::startSearch(std::shared_ptr<Rcl::SearchData> sdata, bool issimple)
rcldb->setSynGroupsFile(""); rcldb->setSynGroupsFile("");
} }
Rcl::Query *query = new Rcl::Query(rcldb); Rcl::Query *query = new Rcl::Query(rcldb.get());
query->setCollapseDuplicates(prefs.collapseDuplicates); query->setCollapseDuplicates(prefs.collapseDuplicates);
curPreview = 0; curPreview = 0;
DocSequenceDb *src = DocSequenceDb *src =
new DocSequenceDb(std::shared_ptr<Rcl::Query>(query), new DocSequenceDb(rcldb, std::shared_ptr<Rcl::Query>(query),
string(tr("Query results").toUtf8()), sdata); string(tr("Query results").toUtf8()), sdata);
src->setAbstractParams(prefs.queryBuildAbstract, src->setAbstractParams(prefs.queryBuildAbstract,
prefs.queryReplaceAbstract); prefs.queryReplaceAbstract);

View File

@ -18,6 +18,7 @@
#define _RECOLL_H_INCLUDED_ #define _RECOLL_H_INCLUDED_
#include <string> #include <string>
#include <memory>
#include "rclconfig.h" #include "rclconfig.h"
#include "rcldb.h" #include "rcldb.h"
@ -40,7 +41,7 @@ extern TempFile *rememberTempFile(TempFile);
extern void forgetTempFile(string &fn); extern void forgetTempFile(string &fn);
extern void deleteAllTempFiles(); extern void deleteAllTempFiles();
extern Rcl::Db *rcldb; extern std::shared_ptr<Rcl::Db> rcldb;
extern int recollNeedsExit; extern int recollNeedsExit;
extern void startManual(const string& helpindex); extern void startManual(const string& helpindex);

View File

@ -338,7 +338,7 @@ void SpellW::showStats()
string q = string("mime:") + *it; string q = string("mime:") + *it;
Rcl::SearchData *sd = wasaStringToRcl(theconfig, "", q, reason); Rcl::SearchData *sd = wasaStringToRcl(theconfig, "", q, reason);
std::shared_ptr<Rcl::SearchData> rq(sd); std::shared_ptr<Rcl::SearchData> rq(sd);
Rcl::Query query(rcldb); Rcl::Query query(rcldb.get());
if (!query.setQuery(rq)) { if (!query.setQuery(rq)) {
LOGERR("Query setup failed: " << (query.getReason()) << "" ); LOGERR("Query setup failed: " << (query.getReason()) << "" );
return; return;

View File

@ -41,8 +41,8 @@ int DocSequence::getSeqSlice(int offs, int cnt, vector<ResListEntry>& result)
bool DocSequence::getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc) bool DocSequence::getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc)
{ {
Rcl::Db *db = getDb(); std::shared_ptr<Rcl::Db> db = getDb();
if (db == 0) { if (!db) {
LOGERR("DocSequence::getEnclosing: no db\n" ); LOGERR("DocSequence::getEnclosing: no db\n" );
return false; return false;
} }

View File

@ -166,7 +166,7 @@ class DocSequence {
protected: protected:
friend class DocSeqModifier; friend class DocSeqModifier;
virtual Rcl::Db *getDb() = 0; virtual std::shared_ptr<Rcl::Db> getDb() = 0;
static std::mutex o_dblock; static std::mutex o_dblock;
static std::string o_sort_trans; static std::string o_sort_trans;
static std::string o_filt_trans; static std::string o_filt_trans;
@ -247,8 +247,7 @@ public:
} }
protected: protected:
virtual Rcl::Db *getDb() virtual std::shared_ptr<Rcl::Db> getDb() {
{
if (!m_seq) if (!m_seq)
return 0; return 0;
return m_seq->getDb(); return m_seq->getDb();

View File

@ -28,9 +28,10 @@
using std::list; using std::list;
DocSequenceDb::DocSequenceDb(std::shared_ptr<Rcl::Query> q, const string &t, DocSequenceDb::DocSequenceDb(std::shared_ptr<Rcl::Db> db,
std::shared_ptr<Rcl::Query> q, const string &t,
std::shared_ptr<Rcl::SearchData> sdata) std::shared_ptr<Rcl::SearchData> sdata)
: DocSequence(t), m_q(q), m_sdata(sdata), m_fsdata(sdata), : DocSequence(t), m_db(db), m_q(q), m_sdata(sdata), m_fsdata(sdata),
m_rescnt(-1), m_rescnt(-1),
m_queryBuildAbstract(true), m_queryBuildAbstract(true),
m_queryReplaceAbstract(false), m_queryReplaceAbstract(false),
@ -131,11 +132,6 @@ int DocSequenceDb::getFirstMatchPage(Rcl::Doc &doc, string& term)
return -1; return -1;
} }
Rcl::Db *DocSequenceDb::getDb()
{
return m_q ? m_q->whatDb() : 0;
}
list<string> DocSequenceDb::expand(Rcl::Doc &doc) list<string> DocSequenceDb::expand(Rcl::Doc &doc)
{ {
std::unique_lock<std::mutex> locker(o_dblock); std::unique_lock<std::mutex> locker(o_dblock);

View File

@ -25,7 +25,8 @@
/** A DocSequence from a Db query */ /** A DocSequence from a Db query */
class DocSequenceDb : public DocSequence { class DocSequenceDb : public DocSequence {
public: public:
DocSequenceDb(std::shared_ptr<Rcl::Query> q, const string &t, DocSequenceDb(std::shared_ptr<Rcl::Db> db,
std::shared_ptr<Rcl::Query> q, const string &t,
std::shared_ptr<Rcl::SearchData> sdata); std::shared_ptr<Rcl::SearchData> sdata);
virtual ~DocSequenceDb() {} virtual ~DocSequenceDb() {}
virtual bool getDoc(int num, Rcl::Doc &doc, string * = 0); virtual bool getDoc(int num, Rcl::Doc &doc, string * = 0);
@ -58,8 +59,11 @@ class DocSequenceDb : public DocSequence {
virtual string title(); virtual string title();
protected: protected:
virtual Rcl::Db *getDb(); virtual std::shared_ptr<Rcl::Db> getDb() {
return m_db;
}
private: private:
std::shared_ptr<Rcl::Db> m_db;
std::shared_ptr<Rcl::Query> m_q; std::shared_ptr<Rcl::Query> m_q;
std::shared_ptr<Rcl::SearchData> m_sdata; std::shared_ptr<Rcl::SearchData> m_sdata;
std::shared_ptr<Rcl::SearchData> m_fsdata; // Filtered std::shared_ptr<Rcl::SearchData> m_fsdata; // Filtered

View File

@ -17,6 +17,8 @@
#ifndef _DOCSEQDOCS_H_INCLUDED_ #ifndef _DOCSEQDOCS_H_INCLUDED_
#define _DOCSEQDOCS_H_INCLUDED_ #define _DOCSEQDOCS_H_INCLUDED_
#include <memory>
#include "docseq.h" #include "docseq.h"
#include "rcldoc.h" #include "rcldoc.h"
@ -27,16 +29,13 @@ namespace Rcl {
/** A DocSequence that's just built from a bunch of docs */ /** A DocSequence that's just built from a bunch of docs */
class DocSequenceDocs : public DocSequence { class DocSequenceDocs : public DocSequence {
public: public:
DocSequenceDocs(Rcl::Db *d, const std::vector<Rcl::Doc> docs, DocSequenceDocs(std::shared_ptr<Rcl::Db> d,
const string &t) const std::vector<Rcl::Doc> docs, const string &t)
: DocSequence(t), m_db(d), m_docs(docs) : DocSequence(t), m_db(d), m_docs(docs) {
{
} }
virtual ~DocSequenceDocs() virtual ~DocSequenceDocs() {
{
} }
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0) virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0) {
{
if (sh) if (sh)
*sh = string(); *sh = string();
if (num < 0 || num >= int(m_docs.size())) if (num < 0 || num >= int(m_docs.size()))
@ -44,25 +43,21 @@ class DocSequenceDocs : public DocSequence {
doc = m_docs[num]; doc = m_docs[num];
return true; return true;
} }
virtual int getResCnt() virtual int getResCnt() {
{
return m_docs.size(); return m_docs.size();
} }
virtual string getDescription() virtual string getDescription() {
{
return m_description; return m_description;
} }
void setDescription(const string& desc) void setDescription(const string& desc) {
{
m_description = desc; m_description = desc;
} }
protected: protected:
virtual Rcl::Db *getDb() virtual std::shared_ptr<Rcl::Db> getDb() {
{
return m_db; return m_db;
} }
private: private:
Rcl::Db *m_db; std::shared_ptr<Rcl::Db> m_db;
string m_description; string m_description;
std::vector<Rcl::Doc> m_docs; std::vector<Rcl::Doc> m_docs;
}; };

View File

@ -159,11 +159,6 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh)
return ret; return ret;
} }
Rcl::Db *DocSequenceHistory::getDb()
{
return m_db;
}
int DocSequenceHistory::getResCnt() int DocSequenceHistory::getResCnt()
{ {
if (m_history.empty()) if (m_history.empty())

View File

@ -19,6 +19,7 @@
#include <time.h> #include <time.h>
#include <vector> #include <vector>
#include <memory>
#include "docseq.h" #include "docseq.h"
#include "dynconf.h" #include "dynconf.h"
@ -47,8 +48,9 @@ class RclDHistoryEntry : public DynConfEntry {
* metadata for an url key */ * metadata for an url key */
class DocSequenceHistory : public DocSequence { class DocSequenceHistory : public DocSequence {
public: public:
DocSequenceHistory(Rcl::Db *d, RclDynConf *h, const std::string &t) DocSequenceHistory(std::shared_ptr<Rcl::Db> db, RclDynConf *h,
: DocSequence(t), m_db(d), m_hist(h) {} const std::string &t)
: DocSequence(t), m_db(db), m_hist(h) {}
virtual ~DocSequenceHistory() {} virtual ~DocSequenceHistory() {}
virtual bool getDoc(int num, Rcl::Doc &doc, std::string *sh = 0); virtual bool getDoc(int num, Rcl::Doc &doc, std::string *sh = 0);
@ -56,9 +58,11 @@ class DocSequenceHistory : public DocSequence {
virtual std::string getDescription() {return m_description;} virtual std::string getDescription() {return m_description;}
void setDescription(const std::string& desc) {m_description = desc;} void setDescription(const std::string& desc) {m_description = desc;}
protected: protected:
virtual Rcl::Db *getDb(); virtual std::shared_ptr<Rcl::Db> getDb() {
return m_db;
}
private: private:
Rcl::Db *m_db; std::shared_ptr<Rcl::Db> m_db;
RclDynConf *m_hist; RclDynConf *m_hist;
time_t m_prevtime{-1}; time_t m_prevtime{-1};
std::string m_description; // This is just an nls translated 'doc history' std::string m_description; // This is just an nls translated 'doc history'