[Automaton] Make Automaton thread-safe

In an optimization to improve performance (rL375240) we added a std::shared_ptr
around the main table map. This is safe, but we also ended up making the
transcriber object a std::shared_ptr too. This has mutable state, so must be
copied when we copy the Automaton object. This is very cheap; the main optimization
was about the map `M` only.

Reported by Dan Palermo. No test as triggering this is rather hard from a unit test.
This commit is contained in:
James Molloy 2019-11-05 22:53:56 +00:00
parent 7060840bc9
commit 041f35c468
1 changed files with 11 additions and 1 deletions

View File

@ -117,6 +117,10 @@ public:
reset();
}
ArrayRef<NfaStatePair> getTransitionInfo() const {
return TransitionInfo;
}
void reset() {
Paths.clear();
Heads.clear();
@ -198,7 +202,13 @@ public:
M->emplace(std::make_pair(I.FromDfaState, I.Action),
std::make_pair(I.ToDfaState, I.InfoIdx));
}
Automaton(const Automaton &) = default;
Automaton(const Automaton &Other)
: M(Other.M), State(Other.State), Transcribe(Other.Transcribe) {
// Transcriber is not thread-safe, so create a new instance on copy.
if (Other.Transcriber)
Transcriber = std::make_shared<internal::NfaTranscriber>(
Other.Transcriber->getTransitionInfo());
}
/// Reset the automaton to its initial state.
void reset() {