We need recursive locks to synchronize access.

We can certainly revert to simple locks, but then have to do synchronization differently than the Java target does, which is not in the scope of the current work.
This commit is contained in:
Mike Lischke 2016-04-30 13:14:57 +02:00
parent 8cd043a6de
commit 99ada0550f
13 changed files with 19 additions and 18 deletions

View File

@ -238,7 +238,7 @@ const atn::ATN& Parser::getATNWithBypassAlts() {
throw UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.");
}
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
// XXX: using the entire serialized ATN as key into the map is a big resource waste.
// How large can that thing become?
@ -572,7 +572,7 @@ std::vector<std::wstring> Parser::getRuleInvocationStack(Ref<RuleContext> p) {
std::vector<std::wstring> Parser::getDFAStrings() {
atn::ParserATNSimulator *simulator = getInterpreter<atn::ParserATNSimulator>();
if (!simulator->decisionToDFA.empty()) {
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
std::vector<std::wstring> s;
for (size_t d = 0; d < simulator->decisionToDFA.size(); d++) {
@ -587,7 +587,7 @@ std::vector<std::wstring> Parser::getDFAStrings() {
void Parser::dumpDFA() {
atn::ParserATNSimulator *simulator = getInterpreter<atn::ParserATNSimulator>();
if (!simulator->decisionToDFA.empty()) {
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
bool seenOne = false;
for (size_t d = 0; d < simulator->decisionToDFA.size(); d++) {
dfa::DFA &dfa = simulator->decisionToDFA[d];

View File

@ -425,7 +425,7 @@ namespace runtime {
std::vector<int> _precedenceStack;
//Mutex to manage synchronized access for multithreading in the parser
std::mutex mtx;
std::recursive_mutex mtx;
/// <summary>
/// Specifies whether or not the parser should construct a parse tree during

View File

@ -60,7 +60,7 @@ Ref<dfa::Vocabulary> Recognizer::getVocabulary() const {
std::map<std::wstring, size_t> Recognizer::getTokenTypeMap() {
Ref<dfa::Vocabulary> vocabulary = getVocabulary();
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
std::map<std::wstring, size_t> result;
auto iterator = _tokenTypeMapCache.find(vocabulary);
if (iterator != _tokenTypeMapCache.end()) {
@ -90,7 +90,7 @@ std::map<std::wstring, size_t> Recognizer::getRuleIndexMap() {
throw L"The current recognizer does not provide a list of rule names.";
}
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
std::map<std::wstring, size_t> result;
auto iterator = _ruleIndexMapCache.find(ruleNames);
if (iterator != _ruleIndexMapCache.end()) {

View File

@ -181,7 +181,7 @@ namespace runtime {
ProxyErrorListener _proxListener; // Manages a collection of listeners.
// Mutex to manage synchronized access for multithreading.
std::mutex mtx;
std::recursive_mutex mtx;
int _stateNumber;

View File

@ -56,7 +56,7 @@ Ref<PredictionContextCache> ATNSimulator::getSharedContextCache() {
}
Ref<PredictionContext> ATNSimulator::getCachedContext(Ref<PredictionContext> context) {
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
std::map<Ref<PredictionContext>, Ref<PredictionContext>> visited;
return PredictionContext::getCachedContext(context, _sharedContextCache, visited);
}

View File

@ -85,7 +85,7 @@ namespace atn {
protected:
// Mutex to manage synchronized access for multithreading
std::mutex mtx;
std::recursive_mutex mtx;
/// <summary>
/// The context cache maps all PredictionContext objects that are equals()

View File

@ -563,7 +563,7 @@ void LexerATNSimulator::addDFAEdge(dfa::DFAState *p, ssize_t t, dfa::DFAState *q
std::wcout << std::wstring(L"EDGE ") << p << std::wstring(L" -> ") << q << std::wstring(L" upon ") << (static_cast<wchar_t>(t)) << std::endl;
}
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
if (p->edges.empty()) {
// make room for tokens 1..n and -1 masquerading as index 0
p->edges.resize(MAX_DFA_EDGE - MIN_DFA_EDGE + 1);
@ -595,7 +595,7 @@ dfa::DFAState *LexerATNSimulator::addDFAState(Ref<ATNConfigSet> configs) {
dfa::DFA &dfa = _decisionToDFA[_mode];
{
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
auto iterator = dfa.states.find(proposed);
if (iterator != dfa.states.end()) {

View File

@ -1205,7 +1205,7 @@ dfa::DFAState *ParserATNSimulator::addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from
}
{
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
if (from->edges.empty())
from->edges.resize(atn.maxTokenType + 1 + 1);
from->edges[(size_t)(t + 1)] = to; // connect
@ -1228,7 +1228,7 @@ dfa::DFAState *ParserATNSimulator::addDFAState(dfa::DFA &dfa, dfa::DFAState *D)
}
{
std::lock_guard<std::mutex> lck(mtx);
std::lock_guard<std::recursive_mutex> lck(mtx);
auto existing = dfa.states.find(D);
if (existing != dfa.states.end()) {

View File

@ -290,7 +290,7 @@ namespace atn {
PredictionMode mode;
// Mutex to manage synchronized access for multithreading in the parser atn simulator.
std::mutex _lock;
std::recursive_mutex _lock;
/// <summary>
/// Each prediction operation uses a cache for merge of prediction contexts.

View File

@ -106,7 +106,7 @@ void DFA::setPrecedenceStartState(int precedence, DFAState *startState) {
// synchronization on s0 here is ok. when the DFA is turned into a
// precedence DFA, s0 will be initialized once and not updated again
std::unique_lock<std::mutex> lock(_lock);
std::unique_lock<std::recursive_mutex> lock(_lock);
{
// s0.edges is never null for a precedence DFA
if (precedence >= (int)s0->edges.size()) {

View File

@ -109,7 +109,7 @@ namespace dfa {
*/
bool _precedenceDfa;
std::mutex _lock; // To synchronize access to s0.
std::recursive_mutex _lock; // To synchronize access to s0.
};
} // namespace atn

View File

@ -29,11 +29,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "VocabularyImpl.h"
#include "LexerDFASerializer.h"
using namespace org::antlr::v4::runtime::dfa;
LexerDFASerializer::LexerDFASerializer(DFA *dfa) : DFASerializer(dfa, lexerTokenNames_) {
LexerDFASerializer::LexerDFASerializer(DFA *dfa) : DFASerializer(dfa, VocabularyImpl::EMPTY_VOCABULARY) {
}
std::wstring LexerDFASerializer::getEdgeLabel(size_t i) const {

View File

@ -44,7 +44,6 @@ namespace dfa {
LexerDFASerializer(DFA *dfa);
protected:
std::vector<std::wstring> lexerTokenNames_;
virtual std::wstring getEdgeLabel(size_t i) const override;
};