Skip to content

Commit 13d327a

Browse files
committed
Fix multi-threading issues if SERVER_BASED_SEARCH=YES
1 parent cdee91f commit 13d327a

14 files changed

+104
-49
lines changed

src/docbookgen.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -251,14 +251,6 @@ void DocbookCodeGenerator::writeLineNumber(const QCString &ref,const QCString &f
251251
m_col=0;
252252
}
253253

254-
void DocbookCodeGenerator::setCurrentDoc(const Definition *,const QCString &,bool)
255-
{
256-
}
257-
258-
void DocbookCodeGenerator::addWord(const QCString &,bool)
259-
{
260-
}
261-
262254
void DocbookCodeGenerator::finish()
263255
{
264256
endCodeLine();

src/docbookgen.h

-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class DocbookCodeGenerator : public CodeOutputInterface
4747
void writeCodeAnchor(const QCString &);
4848
void writeLineNumber(const QCString &extRef,const QCString &compId,
4949
const QCString &anchorId,int l, bool writeLineAnchor);
50-
void setCurrentDoc(const Definition *,const QCString &,bool);
51-
void addWord(const QCString &,bool);
5250
void finish();
5351
void startCodeFragment(const QCString &style);
5452
void endCodeFragment(const QCString &style);

src/docparser.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ struct DocParserContext
151151
class DocParser : public IDocParser
152152
{
153153
public:
154+
~DocParser()
155+
{
156+
if (Doxygen::searchIndex)
157+
{
158+
searchData.transfer(*Doxygen::searchIndex);
159+
}
160+
}
154161
void pushContext();
155162
void popContext();
156163
void handleImg(DocNode *parent,DocNodeList &children,const HtmlAttribList &tagHtmlAttribs);
@@ -191,6 +198,7 @@ class DocParser : public IDocParser
191198
std::stack< DocParserContext > contextStack;
192199
DocParserContext context;
193200
DocTokenizer tokenizer;
201+
SIDataCollection searchData;
194202
};
195203

196204
std::unique_ptr<IDocParser> createDocParser()
@@ -1993,7 +2001,7 @@ DocWord::DocWord(DocParser &parser,DocNode *parent,const QCString &word) :
19932001
//printf("new word %s url=%s\n",qPrint(word),qPrint(parser.context.searchUrl));
19942002
if (Doxygen::searchIndex && !parser.context.searchUrl.isEmpty())
19952003
{
1996-
Doxygen::searchIndex->addWord(word,FALSE);
2004+
parser.searchData.addWord(word,false);
19972005
}
19982006
}
19992007

@@ -2011,7 +2019,7 @@ DocLinkedWord::DocLinkedWord(DocParser &parser,DocNode *parent,const QCString &w
20112019
// qPrint(word),qPrint(parser.context.searchUrl),qPrint(tooltip));
20122020
if (Doxygen::searchIndex && !parser.context.searchUrl.isEmpty())
20132021
{
2014-
Doxygen::searchIndex->addWord(word,FALSE);
2022+
parser.searchData.addWord(word,false);
20152023
}
20162024
}
20172025

@@ -7654,12 +7662,12 @@ DocRoot *validatingParseDoc(IDocParser &parserIntf,
76547662
if (md)
76557663
{
76567664
parser.context.searchUrl=md->getOutputFileBase();
7657-
Doxygen::searchIndex->setCurrentDoc(md,md->anchor(),FALSE);
7665+
parser.searchData.setCurrentDoc(md,md->anchor(),false);
76587666
}
76597667
else if (ctx)
76607668
{
76617669
parser.context.searchUrl=ctx->getOutputFileBase();
7662-
Doxygen::searchIndex->setCurrentDoc(ctx,ctx->anchor(),FALSE);
7670+
parser.searchData.setCurrentDoc(ctx,ctx->anchor(),false);
76637671
}
76647672
}
76657673
else

src/doxygen.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -7989,6 +7989,7 @@ static void generateFileSources()
79897989
msg("Parsing code for file %s...\n",qPrint(fd->docName()));
79907990
fd->parseSource(parser);
79917991
}
7992+
ol.indexSearchData();
79927993
};
79937994
if (!Doxygen::inputNameLinkedMap->empty())
79947995
{
@@ -8121,6 +8122,7 @@ static void generateFileSources()
81218122
for (auto &f : results)
81228123
{
81238124
auto ctx = f.get();
8125+
ctx->ol.indexSearchData();
81248126
}
81258127
}
81268128
else // single threaded version

src/htmlgen.cpp

-16
Original file line numberDiff line numberDiff line change
@@ -3065,22 +3065,6 @@ void HtmlGenerator::endMemberDeclaration(const QCString &anchor,const QCString &
30653065
m_t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
30663066
}
30673067

3068-
void HtmlGenerator::setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile)
3069-
{
3070-
if (Doxygen::searchIndex)
3071-
{
3072-
Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
3073-
}
3074-
}
3075-
3076-
void HtmlGenerator::addWord(const QCString &word,bool hiPriority)
3077-
{
3078-
if (Doxygen::searchIndex)
3079-
{
3080-
Doxygen::searchIndex->addWord(word,hiPriority);
3081-
}
3082-
}
3083-
30843068
QCString HtmlGenerator::getMathJaxMacros()
30853069
{
30863070
return getConvertLatexMacro();

src/htmlgen.h

-4
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class HtmlCodeGenerator : public CodeOutputInterface
4444
void startFontClass(const QCString &s);
4545
void endFontClass();
4646
void writeCodeAnchor(const QCString &anchor);
47-
void setCurrentDoc(const Definition *,const QCString &,bool) {}
48-
void addWord(const QCString &,bool) {}
4947
void startCodeFragment(const QCString &style);
5048
void endCodeFragment(const QCString &);
5149

@@ -117,8 +115,6 @@ class HtmlGenerator : public OutputGenerator
117115
{ m_codeGen.endCodeFragment(style); }
118116
// ---------------------------
119117

120-
void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile);
121-
void addWord(const QCString &word,bool hiPriority);
122118
void writeDoc(DocNode *,const Definition *,const MemberDef *,int id);
123119

124120
void startFile(const QCString &name,const QCString &manName,const QCString &title,int id);

src/latexgen.h

-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ class LatexCodeGenerator : public CodeOutputInterface
5050
void startFontClass(const QCString &) override;
5151
void endFontClass() override;
5252
void writeCodeAnchor(const QCString &) override {}
53-
void setCurrentDoc(const Definition *,const QCString &,bool) override {}
54-
void addWord(const QCString &,bool) override {}
5553
void startCodeFragment(const QCString &style) override;
5654
void endCodeFragment(const QCString &style) override;
5755

src/mangen.h

-2
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,6 @@ class ManGenerator : public OutputGenerator
253253
void endLabels();
254254

255255
void writeCodeAnchor(const QCString &) {}
256-
void setCurrentDoc(const Definition *,const QCString &,bool) {}
257-
void addWord(const QCString &,bool) {}
258256

259257
private:
260258
bool m_firstCol = true;

src/outputgen.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ class CodeOutputInterface
136136
*/
137137
virtual void writeCodeAnchor(const QCString &name) = 0;
138138

139-
virtual void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) = 0;
140-
virtual void addWord(const QCString &word,bool hiPriority) = 0;
139+
virtual void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile) {}
140+
virtual void addWord(const QCString &word,bool hiPriority) {}
141141

142142
/*! Starts a source code fragment. The fragment will be
143143
* fed to the code parser (see code.h) for syntax highlighting

src/outputlist.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#include "index.h" // for IndexSections
2424
#include "outputgen.h"
25+
#include "searchindex.h" // for SIDataCollection
26+
#include "doxygen.h"
2527

2628
class ClassDiagram;
2729
class DotClassGraph;
@@ -485,10 +487,22 @@ class OutputList : public OutputDocInterface
485487
{ forall(&OutputGenerator::endFontClass); }
486488
void writeCodeAnchor(const QCString &name)
487489
{ forall(&OutputGenerator::writeCodeAnchor,name); }
490+
488491
void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile)
489-
{ forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); }
492+
{ /*forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile);*/
493+
m_searchData.setCurrentDoc(context,anchor,isSourceFile);
494+
}
490495
void addWord(const QCString &word,bool hiPriority)
491-
{ forall(&OutputGenerator::addWord,word,hiPriority); }
496+
{ /*forall(&OutputGenerator::addWord,word,hiPriority);*/
497+
m_searchData.addWord(word,hiPriority);
498+
}
499+
void indexSearchData()
500+
{
501+
if (Doxygen::searchIndex)
502+
{
503+
m_searchData.transfer(*Doxygen::searchIndex);
504+
}
505+
}
492506

493507
void startPlainFile(const QCString &name)
494508
{ forall(&OutputGenerator::startPlainFile,name); }
@@ -515,6 +529,7 @@ class OutputList : public OutputDocInterface
515529

516530
std::vector< std::unique_ptr<OutputGenerator> > m_outputs;
517531
int m_id;
532+
SIDataCollection m_searchData;
518533

519534
};
520535

src/rtfgen.h

-2
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,6 @@ class RTFGenerator : public OutputGenerator
261261
void endFontClass();
262262

263263
void writeCodeAnchor(const QCString &) {}
264-
void setCurrentDoc(const Definition *,const QCString &,bool) {}
265-
void addWord(const QCString &,bool) {}
266264

267265
static bool preProcessFileInplace(const QCString &path,const QCString &name);
268266

src/searchindex.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <ctype.h>
1818
#include <assert.h>
1919
#include <sstream>
20+
#include <mutex>
2021

2122
#include "searchindex.h"
2223
#include "config.h"
@@ -386,6 +387,27 @@ void SearchIndex::write(const QCString &fileName)
386387

387388
}
388389

390+
static std::mutex g_transferSearchIndexMutex;
391+
392+
void SIDataCollection::transfer(SearchIndexIntf &intf)
393+
{
394+
std::lock_guard<std::mutex> lock(g_transferSearchIndexMutex);
395+
for (const auto &v : m_data)
396+
{
397+
if (std::holds_alternative<SIData_Word>(v))
398+
{
399+
const auto &d = std::get<SIData_Word>(v);
400+
intf.addWord(d.word,d.hiPrio);
401+
}
402+
else if (std::holds_alternative<SIData_CurrentDoc>(v))
403+
{
404+
const auto &d = std::get<SIData_CurrentDoc>(v);
405+
intf.setCurrentDoc(d.ctx,d.anchor,d.isSourceFile);
406+
}
407+
}
408+
m_data.clear();
409+
}
410+
389411

390412
//---------------------------------------------------------------------------
391413
// the following part is for writing an external search index

src/searchindex.h

+49-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
#include <string>
2424
#include <array>
2525
#include <functional>
26+
#include <variant>
2627

2728
#include "qcstring.h"
2829

2930
class Definition;
31+
class SearchIndexIntf;
3032

3133
/*! Initialize the search indexer */
3234
void initSearchIndexer();
@@ -35,6 +37,49 @@ void finalizeSearchIndexer();
3537

3638
//------- server side search index ----------------------
3739

40+
41+
// --- intermediate data ------
42+
struct SIData_CurrentDoc
43+
{
44+
SIData_CurrentDoc(const Definition *d,const QCString &a,bool b)
45+
: ctx(d), anchor(a), isSourceFile(b) {}
46+
const Definition *ctx = 0;
47+
QCString anchor;
48+
bool isSourceFile;
49+
};
50+
51+
struct SIData_Word
52+
{
53+
SIData_Word(const QCString &w,bool b)
54+
: word(w), hiPrio(b) {}
55+
QCString word;
56+
bool hiPrio;
57+
};
58+
59+
// class to aggregate the search data collected on a worker thread
60+
// and later transfer it to the search index on the main thread.
61+
class SIDataCollection
62+
{
63+
public:
64+
void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile)
65+
{
66+
m_data.emplace_back(SIData_CurrentDoc(ctx,anchor,isSourceFile));
67+
}
68+
void addWord(const QCString &word,bool hiPriority)
69+
{
70+
m_data.emplace_back(SIData_Word(word,hiPriority));
71+
}
72+
73+
// transfer the collected data to the given search index
74+
void transfer(SearchIndexIntf &intf);
75+
76+
private:
77+
using SIData = std::variant<SIData_CurrentDoc,SIData_Word>;
78+
std::vector<SIData> m_data;
79+
};
80+
81+
//-----------------------------
82+
3883
struct URL
3984
{
4085
URL(QCString n,QCString u) : name(n), url(u) {}
@@ -64,6 +109,7 @@ class IndexWord
64109
URLInfoMap m_urls;
65110
};
66111

112+
67113
class SearchIndexIntf
68114
{
69115
public:
@@ -100,9 +146,9 @@ class SearchIndexExternal : public SearchIndexIntf
100146
struct Private;
101147
public:
102148
SearchIndexExternal();
103-
void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile);
104-
void addWord(const QCString &word,bool hiPriority);
105-
void write(const QCString &file);
149+
void setCurrentDoc(const Definition *ctx,const QCString &anchor,bool isSourceFile) override;
150+
void addWord(const QCString &word,bool hiPriority) override;
151+
void write(const QCString &file) override;
106152
private:
107153
std::unique_ptr<Private> p;
108154
};

src/xmlgen.h

-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ class XMLCodeGenerator : public CodeOutputInterface
3939
void writeCodeAnchor(const QCString &) override;
4040
void writeLineNumber(const QCString &extRef,const QCString &compId,
4141
const QCString &anchorId,int l,bool writeLineAnchor) override;
42-
void setCurrentDoc(const Definition *,const QCString &,bool) override {}
43-
void addWord(const QCString &,bool) override {}
4442
void startCodeFragment(const QCString &) override;
4543
void endCodeFragment(const QCString &) override;
4644

0 commit comments

Comments
 (0)