Skip to content
Snippets Groups Projects
Commit 6568fb2f authored by Axel Naumann's avatar Axel Naumann
Browse files

Use new TMutex::Reset/Restore() to clear any and all locks active before entering user code.

This is kosher because the locks were taken to forbid other threads from modifying state while this thread is modifying state.
But this thread will not modify any state while the user code is active; thus while that user code is active,
the mutex can be completely reset, and restored once the user code returns.
parent 2fe15edf
No related branches found
No related tags found
No related merge requests found
......@@ -354,20 +354,23 @@ void TCling__PrintStackTrace() {
/// Lock the interpreter.
extern "C"
void TCling__LockInterpreterMutex() {
if (gInterpreterMutex) gInterpreterMutex->Lock();
void TCling__RestoreInterpreterMutex(void* state) {
if (gInterpreterMutex && state) {
std::unique_ptr<TVirtualMutex::State> uniqueP{static_cast<TVirtualMutex::State*>(state)};
gInterpreterMutex->Restore(std::move(uniqueP));
}
}
////////////////////////////////////////////////////////////////////////////////
/// Unlock the interpreter.
extern "C"
bool TCling__UnlockInterpreterMutex() {
void* TCling__ResetInterpreterMutex() {
if (gInterpreterMutex) {
gInterpreterMutex->UnLock();
return true;
auto uniqueP = gInterpreterMutex->Reset();
return uniqueP.release();
}
return false;
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
......
......@@ -61,8 +61,8 @@ extern "C" {
void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
llvm::StringRef canonicalName);
void TCling__PrintStackTrace();
void TCling__LockInterpreterMutex();
bool TCling__UnlockInterpreterMutex();
void TCling__RestoreInterpreterMutex(void* state);
void* TCling__ResetInterpreterMutex();
}
TClingCallbacks::TClingCallbacks(cling::Interpreter* interp)
......@@ -788,12 +788,12 @@ void TClingCallbacks::PrintStackTrace() {
void TClingCallbacks::EnteringUserCode() {
// We can safely assume that if the lock exist already when we are in Cling code,
// then the lock has (or should been taken) already. So it is fair to unlock it.
fMutexExistedWhenEnteringUserCode.push(TCling__UnlockInterpreterMutex());
// then the lock has (or should been taken) already. Any action (that caused callers
// to take the lock) is halted during ProcessLine. So it is fair to unlock it.
fMutexStatesWhenEnteringUserCode.push(TCling__ResetInterpreterMutex());
}
void TClingCallbacks::ReturnedFromUserCode() {
if (fMutexExistedWhenEnteringUserCode.top())
TCling__LockInterpreterMutex();
fMutexExistedWhenEnteringUserCode.pop();
TCling__RestoreInterpreterMutex(fMutexStatesWhenEnteringUserCode.top());
fMutexStatesWhenEnteringUserCode.pop();
}
......@@ -45,7 +45,7 @@ private:
bool fIsAutoParsingSuspended;
bool fPPOldFlag;
bool fPPChanged;
std::stack<bool> fMutexExistedWhenEnteringUserCode;
std::stack<void*> fMutexStatesWhenEnteringUserCode;
public:
TClingCallbacks(cling::Interpreter* interp);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment