Use local lock reset state instead of a global stack.

Fixes threading issues: multiple threads storing and restoring mutex state, the
stack being modified concurrently etc.
This commit is contained in:
Axel Naumann 2017-08-30 11:28:59 +02:00 committed by sftnight
parent 8cfa532b72
commit 62bcd0aa3b
3 changed files with 19 additions and 10 deletions

View File

@ -170,11 +170,13 @@ namespace cling {
/// printing) cling will calling `EnteringUserCode()`, and once
/// done call `ReturnedFromUserCode()`. Typically the user provided locks
/// would be unlock by `EnteringUserCode()` and lock back in
/// `ReturnedFromUserCode()`.
virtual void EnteringUserCode() {}
/// `ReturnedFromUserCode()`. State can be returned from EnteringUserCode
/// and made use of in ReturnedFromUserCode(), to identify pairs of these
/// calls.
virtual void* EnteringUserCode() { return nullptr; }
///\brief See `EnteringFromUserCode()`!
virtual void ReturnedFromUserCode() {}
virtual void ReturnedFromUserCode(void*) {}
///\brief DynamicScopes only! Set to true if it is currently evaluating a
/// dynamic expr.

View File

@ -17,10 +17,11 @@ namespace cling {
///\brief Unlocks and then upon destruction locks the interpreter again.
struct EnterUserCodeRTTI {
InterpreterCallbacks* fCallbacks; // callbacks used to un/lock.
void* fStateInfo = nullptr; // info provided to ReturnedFromUserCode().
EnterUserCodeRTTI(InterpreterCallbacks* callbacks): fCallbacks(callbacks)
{
if (fCallbacks)
fCallbacks->EnteringUserCode();
fStateInfo = fCallbacks->EnteringUserCode();
}
EnterUserCodeRTTI(Interpreter& interp): EnterUserCodeRTTI(interp.getCallbacks())
@ -28,7 +29,7 @@ namespace cling {
~EnterUserCodeRTTI() {
if (fCallbacks)
fCallbacks->ReturnedFromUserCode();
fCallbacks->ReturnedFromUserCode(fStateInfo);
}
};
}

View File

@ -124,14 +124,20 @@ namespace cling {
cb->PrintStackTrace();
}
void EnteringUserCode() override {
for (auto&& cb : m_Callbacks)
cb->EnteringUserCode();
void* EnteringUserCode() override {
void* ret = nullptr;
for (auto&& cb : m_Callbacks) {
if (void* myret = cb->EnteringUserCode()) {
assert(!ret && "Multiple state infos are not supported!");
ret = myret;
}
}
return ret;
}
void ReturnedFromUserCode() override {
void ReturnedFromUserCode(void* StateInfo) override {
for (auto&& cb : m_Callbacks)
cb->ReturnedFromUserCode();
cb->ReturnedFromUserCode(StateInfo);
}
};
} // end namespace cling