Skip to content

Commit 6fe51e5

Browse files
authored
Merge pull request #183 from kmatheussen/master
Fix race conditions when initializing static variables. (Fix for issue #181)
2 parents 98e87c3 + 20c9369 commit 6fe51e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+210
-183
lines changed

include/lucene++/Synchronize.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#ifndef SYNCHRONIZE_H
88
#define SYNCHRONIZE_H
99

10+
#include <atomic>
1011
#include <boost/thread/recursive_mutex.hpp>
12+
#include <boost/thread/mutex.hpp>
1113
#include "Lucene.h"
1214

1315
namespace Lucene {
@@ -60,6 +62,21 @@ class LPPAPI SyncLock {
6062
void lock(int32_t timeout);
6163
};
6264

65+
66+
#define LUCENE_RUN_ONCE(Command) \
67+
do { \
68+
static std::atomic<bool> RUN_ONCE_hasRun = {}; \
69+
if (!RUN_ONCE_hasRun) { \
70+
static boost::mutex RUN_ONCE_mutex; \
71+
boost::mutex::scoped_lock RUN_ONCE_lock(RUN_ONCE_mutex); \
72+
if (!RUN_ONCE_hasRun) { \
73+
Command; \
74+
RUN_ONCE_hasRun = true; \
75+
} \
76+
} \
77+
} while(0)
78+
79+
6380
}
6481

6582
#endif

src/contrib/analyzers/common/analysis/ar/ArabicAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ ArabicAnalyzer::~ArabicAnalyzer() {
8989

9090
const HashSet<String> ArabicAnalyzer::getDefaultStopSet() {
9191
static HashSet<String> stopSet;
92-
if (!stopSet) {
92+
LUCENE_RUN_ONCE(
9393
String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE));
9494
Collection<String> words(StringUtils::split(stopWords, L"\n"));
9595
stopSet = HashSet<String>::newInstance(words.begin(), words.end());
96-
}
96+
);
9797
return stopSet;
9898
}
9999

src/contrib/analyzers/common/analysis/ar/ArabicStemmer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ArabicStemmer::~ArabicStemmer() {
2727

2828
const Collection<String> ArabicStemmer::prefixes() {
2929
static Collection<String> _prefixes;
30-
if (!_prefixes) {
30+
LUCENE_RUN_ONCE(
3131
_prefixes = Collection<String>::newInstance();
3232
_prefixes.add(String(L"") + ALEF + LAM);
3333
_prefixes.add(String(L"") + WAW + ALEF + LAM);
@@ -36,13 +36,13 @@ const Collection<String> ArabicStemmer::prefixes() {
3636
_prefixes.add(String(L"") + FEH + ALEF + LAM);
3737
_prefixes.add(String(L"") + LAM + LAM);
3838
_prefixes.add(String(L"") + WAW);
39-
}
39+
);
4040
return _prefixes;
4141
}
4242

4343
const Collection<String> ArabicStemmer::suffixes() {
4444
static Collection<String> _suffixes;
45-
if (!_suffixes) {
45+
LUCENE_RUN_ONCE(
4646
_suffixes = Collection<String>::newInstance();
4747
_suffixes.add(String(L"") + HEH + ALEF);
4848
_suffixes.add(String(L"") + ALEF + NOON);
@@ -54,7 +54,7 @@ const Collection<String> ArabicStemmer::suffixes() {
5454
_suffixes.add(String(L"") + HEH);
5555
_suffixes.add(String(L"") + TEH_MARBUTA);
5656
_suffixes.add(String(L"") + YEH);
57-
}
57+
);
5858
return _suffixes;
5959
}
6060

src/contrib/analyzers/common/analysis/br/BrazilianAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ BrazilianAnalyzer::~BrazilianAnalyzer() {
5959

6060
const HashSet<String> BrazilianAnalyzer::getDefaultStopSet() {
6161
static HashSet<String> stopSet;
62-
if (!stopSet) {
62+
LUCENE_RUN_ONCE(
6363
stopSet = HashSet<String>::newInstance(_BRAZILIAN_STOP_WORDS, _BRAZILIAN_STOP_WORDS + SIZEOF_ARRAY(_BRAZILIAN_STOP_WORDS));
64-
}
64+
);
6565
return stopSet;
6666
}
6767

src/contrib/analyzers/common/analysis/cjk/CJKAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ CJKAnalyzer::~CJKAnalyzer() {
3636

3737
const HashSet<String> CJKAnalyzer::getDefaultStopSet() {
3838
static HashSet<String> stopSet;
39-
if (!stopSet) {
39+
LUCENE_RUN_ONCE(
4040
stopSet = HashSet<String>::newInstance(_STOP_WORDS, _STOP_WORDS + SIZEOF_ARRAY(_STOP_WORDS));
41-
}
41+
);
4242
return stopSet;
4343
}
4444

src/contrib/analyzers/common/analysis/cz/CzechAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ CzechAnalyzer::~CzechAnalyzer() {
8686

8787
const HashSet<String> CzechAnalyzer::getDefaultStopSet() {
8888
static HashSet<String> stopSet;
89-
if (!stopSet) {
89+
LUCENE_RUN_ONCE(
9090
String stopWords(UTF8_TO_STRING(_CZECH_STOP_WORDS));
9191
Collection<String> words(StringUtils::split(stopWords, L"\n"));
9292
stopSet = HashSet<String>::newInstance(words.begin(), words.end());
93-
}
93+
);
9494
return stopSet;
9595
}
9696

src/contrib/analyzers/common/analysis/de/GermanAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ GermanAnalyzer::~GermanAnalyzer() {
4545

4646
const HashSet<String> GermanAnalyzer::getDefaultStopSet() {
4747
static HashSet<String> stopSet;
48-
if (!stopSet) {
48+
LUCENE_RUN_ONCE(
4949
stopSet = HashSet<String>::newInstance(_GERMAN_STOP_WORDS, _GERMAN_STOP_WORDS + SIZEOF_ARRAY(_GERMAN_STOP_WORDS));
50-
}
50+
);
5151
return stopSet;
5252
}
5353

src/contrib/analyzers/common/analysis/el/GreekAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ GreekAnalyzer::~GreekAnalyzer() {
7373

7474
const HashSet<String> GreekAnalyzer::getDefaultStopSet() {
7575
static HashSet<String> stopSet;
76-
if (!stopSet) {
76+
LUCENE_RUN_ONCE(
7777
String stopWords(UTF8_TO_STRING(_GREEK_STOP_WORDS));
7878
Collection<String> words(StringUtils::split(stopWords, L"\n"));
7979
stopSet = HashSet<String>::newInstance(words.begin(), words.end());
80-
}
80+
);
8181
return stopSet;
8282
}
8383

src/contrib/analyzers/common/analysis/fa/PersianAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,11 @@ PersianAnalyzer::~PersianAnalyzer() {
205205

206206
const HashSet<String> PersianAnalyzer::getDefaultStopSet() {
207207
static HashSet<String> stopSet;
208-
if (!stopSet) {
208+
LUCENE_RUN_ONCE(
209209
String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE));
210210
Collection<String> words(StringUtils::split(stopWords, L"\n"));
211211
stopSet = HashSet<String>::newInstance(words.begin(), words.end());
212-
}
212+
);
213213
return stopSet;
214214
}
215215

src/contrib/analyzers/common/analysis/fr/FrenchAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ FrenchAnalyzer::~FrenchAnalyzer() {
6161

6262
const HashSet<String> FrenchAnalyzer::getDefaultStopSet() {
6363
static HashSet<String> stoptable;
64-
if (!stoptable) {
64+
LUCENE_RUN_ONCE(
6565
stoptable = HashSet<String>::newInstance(_FRENCH_STOP_WORDS, _FRENCH_STOP_WORDS + SIZEOF_ARRAY(_FRENCH_STOP_WORDS));
66-
}
66+
);
6767
return stoptable;
6868
}
6969

src/contrib/analyzers/common/analysis/fr/FrenchStemmer.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,40 +124,42 @@ void FrenchStemmer::step1() {
124124

125125
bool FrenchStemmer::step2a() {
126126
static Collection<String> search;
127-
if (!search) {
128-
static const wchar_t* _search[] = {
127+
static const wchar_t* _search[] = {
129128
L"\x00eemes", L"\x00eetes", L"iraIent", L"irait", L"irais", L"irai", L"iras", L"ira",
130129
L"irent", L"iriez", L"irez", L"irions", L"irons", L"iront", L"issaIent",
131130
L"issais", L"issantes", L"issante", L"issants", L"issant", L"issait",
132131
L"issais", L"issions", L"issons", L"issiez", L"issez", L"issent", L"isses",
133132
L"isse", L"ir", L"is", L"\x00eet", L"it", L"ies", L"ie", L"i"
134-
};
133+
};
134+
135+
LUCENE_RUN_ONCE(
135136
search = Collection<String>::newInstance(_search, _search + SIZEOF_ARRAY(_search));
136-
}
137+
);
138+
137139
return deleteFromIfTestVowelBeforeIn(RV, search, false, RV);
138140
}
139141

140142
void FrenchStemmer::step2b() {
141143
static Collection<String> suffix;
142-
if (!suffix) {
143-
static const wchar_t* _suffix[] = {
144+
static const wchar_t* _suffix[] = {
144145
L"eraIent", L"erais", L"erait", L"erai", L"eras", L"erions", L"eriez",
145146
L"erons", L"eront", L"erez", L"\x00e8rent", L"era", L"\x00e9es", L"iez", L"\x00e9e", L"\x00e9s",
146147
L"er", L"ez", L"\x00e9"
147-
};
148+
};
149+
LUCENE_RUN_ONCE(
148150
suffix = Collection<String>::newInstance(_suffix, _suffix + SIZEOF_ARRAY(_suffix));
149-
}
151+
);
150152
deleteFrom(RV, suffix);
151153

152154
static Collection<String> search;
153-
if (!search) {
154-
static const wchar_t* _search[] = {
155+
static const wchar_t* _search[] = {
155156
L"assions", L"assiez", L"assent", L"asses", L"asse", L"aIent", L"antes",
156157
L"aIent", L"Aient", L"ante", L"\x00e2mes", L"\x00e2tes", L"ants", L"ant", L"ait",
157158
L"a\x00eet", L"ais", L"Ait", L"A\x00eet", L"Ais", L"\x00e2t", L"as", L"ai", L"Ai", L"a"
158-
};
159-
search = Collection<String>::newInstance(_search, _search + SIZEOF_ARRAY(_search));
160-
}
159+
};
160+
LUCENE_RUN_ONCE(
161+
search = Collection<String>::newInstance(_search, _search + SIZEOF_ARRAY(_search));
162+
);
161163
deleteButSuffixFrom(RV, search, L"e", true);
162164

163165
deleteFrom(R2, newCollection<String>(L"ions"));

src/contrib/analyzers/common/analysis/nl/DutchAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ void DutchAnalyzer::initialize() {
5757

5858
const HashSet<String> DutchAnalyzer::getDefaultStopSet() {
5959
static HashSet<String> stoptable;
60-
if (!stoptable) {
60+
LUCENE_RUN_ONCE(
6161
stoptable = HashSet<String>::newInstance(_DUTCH_STOP_WORDS, _DUTCH_STOP_WORDS + SIZEOF_ARRAY(_DUTCH_STOP_WORDS));
62-
}
62+
);
6363
return stoptable;
6464
}
6565

src/contrib/analyzers/common/analysis/ru/RussianAnalyzer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ RussianAnalyzer::~RussianAnalyzer() {
7777

7878
const HashSet<String> RussianAnalyzer::getDefaultStopSet() {
7979
static HashSet<String> stopSet;
80-
if (!stopSet) {
80+
LUCENE_RUN_ONCE(
8181
String stopWords(UTF8_TO_STRING(DEFAULT_STOPWORD_FILE));
8282
Collection<String> words(StringUtils::split(stopWords, L"\n"));
8383
stopSet = HashSet<String>::newInstance(words.begin(), words.end());
84-
}
84+
);
8585
return stopSet;
8686
}
8787

0 commit comments

Comments
 (0)