mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-21 22:04:56 -06:00
ide: Fixed some parser deadlock issues (and added detection)
git-svn-id: svn://ultimatepp.org/upp/trunk@14681 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
464661d97d
commit
0de514b9f2
8 changed files with 58 additions and 32 deletions
|
|
@ -226,7 +226,7 @@ void PreprocessParse(CppBase& base, Stream& in, int file, const String& path,
|
|||
Event<int, const String&> error);
|
||||
String PreprocessCpp(const String& src, const String& path);
|
||||
|
||||
ParserContext AssistParse(CppBase& base, const String& src, const String& path_, Event<int, const String&> error);
|
||||
ParserContext AssistParse(const String& src, const String& path_, Event<int, const String&> error);
|
||||
|
||||
void SimpleParse(CppBase& cpp, const String& txt, const String& cls);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ String PreprocessCpp(const String& src, const String& path)
|
|||
return cpp.output;
|
||||
}
|
||||
|
||||
ParserContext AssistParse(CppBase& base, const String& src, const String& path_, Event<int, const String&> error)
|
||||
ParserContext AssistParse(const String& src, const String& path_, Event<int, const String&> error)
|
||||
{
|
||||
String path = NormalizeSourcePath(path_);
|
||||
Cpp cpp;
|
||||
|
|
@ -64,7 +64,8 @@ ParserContext AssistParse(CppBase& base, const String& src, const String& path_,
|
|||
Parser parser;
|
||||
parser.dobody = true; // will do bodies and not write anything to base
|
||||
StringStream pin(cpp.output);
|
||||
parser.Do(pin, base, Null, Null, GetFileTitle(path), error,
|
||||
CppBase dummy;
|
||||
parser.Do(pin, dummy, Null, Null, GetFileTitle(path), error,
|
||||
Vector<String>(), cpp.namespace_stack, cpp.namespace_using); // needs CodeBase to identify type names
|
||||
return pick(parser);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ public:
|
|||
virtual ~Pusher();
|
||||
};
|
||||
|
||||
|
||||
class Button : public Pusher {
|
||||
public:
|
||||
virtual void Paint(Draw& draw);
|
||||
|
|
|
|||
|
|
@ -22,20 +22,35 @@
|
|||
|
||||
static StaticMutex sGLock;
|
||||
static thread_local int sGLockLevel = 0;
|
||||
|
||||
CodeBaseLock::CodeBaseLock()
|
||||
|
||||
bool DeadLockCheck()
|
||||
{
|
||||
if(sGLockLevel) {
|
||||
PostCallback([] { Exclamation("Internal error (deadlock on sGLock)"); });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LockCodeBase()
|
||||
{
|
||||
if(sGLockLevel++ == 0)
|
||||
sGLock.Enter();
|
||||
}
|
||||
|
||||
CodeBaseLock::~CodeBaseLock()
|
||||
void UnlockCodeBase()
|
||||
{
|
||||
ASSERT(sGLockLevel > 0);
|
||||
if(--sGLockLevel == 0)
|
||||
if(sGLockLevel > 0 && --sGLockLevel == 0)
|
||||
sGLock.Leave();
|
||||
}
|
||||
|
||||
void UnlockCodeBaseAll()
|
||||
{
|
||||
if(sGLockLevel > 0)
|
||||
sGLock.Leave();
|
||||
sGLockLevel = 0; // just in case
|
||||
}
|
||||
|
||||
INITIALIZER(CodeBase)
|
||||
{
|
||||
void InitializeTopicModule();
|
||||
|
|
@ -121,7 +136,7 @@ void BrowserScanError(int line, const String& text, int file)
|
|||
|
||||
void SerializeCodeBase(Stream& s)
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
MLOG(s.IsLoading());
|
||||
source_file.Serialize(s);
|
||||
|
|
@ -134,7 +149,7 @@ void SerializeCodeBase(Stream& s)
|
|||
|
||||
void SaveCodeBase()
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
LTIMING("SaveCodeBase");
|
||||
LLOG("Save code base " << CodeBase().GetCount());
|
||||
|
|
@ -148,7 +163,7 @@ void SaveCodeBase()
|
|||
|
||||
bool TryLoadCodeBase(const char *pattern)
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return false;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
LLOG("+++ Trying to load " << pattern);
|
||||
FindFile ff(pattern);
|
||||
|
|
@ -176,7 +191,7 @@ bool TryLoadCodeBase(const char *pattern)
|
|||
|
||||
void LoadCodeBase()
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
MLOG("LoadCodeBase start: " << MemoryUsedKb());
|
||||
TryLoadCodeBase(CodeBaseCacheFile()) ||
|
||||
|
|
@ -191,7 +206,7 @@ void FinishCodeBase()
|
|||
{
|
||||
LTIMING("FinishBase");
|
||||
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
Qualify(CodeBase());
|
||||
}
|
||||
|
|
@ -199,7 +214,7 @@ void FinishCodeBase()
|
|||
void LoadDefs()
|
||||
{
|
||||
LTIMING("LoadDefs");
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
Vector<String> defs;
|
||||
defs.Add(ConfigFile("global.defs"));
|
||||
|
|
@ -230,7 +245,7 @@ void LoadDefs()
|
|||
|
||||
void BaseInfoSync(Progress& pi)
|
||||
{ // clears temporary caches (file times etc..)
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
PPSync(TheIde()->IdeGetIncludePath());
|
||||
|
||||
|
|
@ -313,7 +328,7 @@ bool CheckFile0(SourceFileInfo& f, const String& path)
|
|||
bool CheckFile(SourceFileInfo& f, const String& path)
|
||||
{
|
||||
LTIMING("CheckFile");
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return false;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
return CheckFile0(f, path);
|
||||
}
|
||||
|
|
@ -321,7 +336,7 @@ bool CheckFile(SourceFileInfo& f, const String& path)
|
|||
void UpdateCodeBase2(Progress& pi)
|
||||
{
|
||||
CLOG("============= UpdateCodeBase2 " << GetSysTime());
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
Index<int> parse_file;
|
||||
{
|
||||
|
|
@ -416,9 +431,6 @@ void CodeBaseScanFile0(Stream& in, const String& fn)
|
|||
{
|
||||
LLOG("===== CodeBaseScanFile " << fn);
|
||||
|
||||
ASSERT(sGLockLevel == 0);
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
|
||||
InvalidateFileTimeCache(NormalizeSourcePath(fn));
|
||||
PPSync(TheIde()->IdeGetIncludePath());
|
||||
|
||||
|
|
@ -436,6 +448,8 @@ void CodeBaseScanFile0(Stream& in, const String& fn)
|
|||
|
||||
void CodeBaseScanFile(Stream& in, const String& fn)
|
||||
{
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
CodeBaseScanFile0(in, fn);
|
||||
FinishCodeBase();
|
||||
}
|
||||
|
|
@ -443,11 +457,11 @@ void CodeBaseScanFile(Stream& in, const String& fn)
|
|||
void CodeBaseScanFile(const String& fn, bool auto_check)
|
||||
{
|
||||
LLOG("CodeBaseScanFile " << fn);
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
String md5sum = GetPPMD5(fn);
|
||||
FileIn in(fn);
|
||||
CodeBaseScanFile(in, fn);
|
||||
CodeBaseScanFile0(in, fn);
|
||||
int file = GetSourceFileIndex(fn);
|
||||
SourceFileInfo& f = source_file[file];
|
||||
CLOG("CodeBaseScanFile " << fn << ", " << md5sum << " " << f.md5sum);
|
||||
|
|
@ -463,7 +477,7 @@ void CodeBaseScanFile(const String& fn, bool auto_check)
|
|||
void ClearCodeBase()
|
||||
{
|
||||
// TODO: Create combined defs
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
CleanPP();
|
||||
CodeBase().Clear();
|
||||
|
|
@ -475,7 +489,7 @@ void SyncCodeBase()
|
|||
LTIMING("SyncCodeBase");
|
||||
LTIMESTOP("SyncCodeBase");
|
||||
CLOG("============= Sync code base");
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
if(IsNull(IdeGetCurrentMainPackage())) {
|
||||
ClearCodeBase();
|
||||
|
|
@ -489,7 +503,7 @@ void SyncCodeBase()
|
|||
|
||||
void NewCodeBase()
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
ReduceCodeBaseCache();
|
||||
if(IsNull(IdeGetCurrentMainPackage())) {
|
||||
|
|
@ -510,7 +524,7 @@ void NewCodeBase()
|
|||
|
||||
void RescanCodeBase()
|
||||
{
|
||||
ASSERT(sGLockLevel == 0);
|
||||
if(DeadLockCheck()) return;
|
||||
Mutex::Lock __(CppBaseMutex);
|
||||
ClearCodeBase();
|
||||
s_console = true;
|
||||
|
|
|
|||
|
|
@ -20,9 +20,13 @@ class Browser;
|
|||
|
||||
void ReduceCacheFolder(const char *path, int max_total);
|
||||
|
||||
void LockCodeBase();
|
||||
void UnlockCodeBase();
|
||||
void UnlockCodeBaseAll();
|
||||
|
||||
struct CodeBaseLock { // Use when accessing CodeBase
|
||||
CodeBaseLock();
|
||||
~CodeBaseLock();
|
||||
CodeBaseLock() { LockCodeBase(); }
|
||||
~CodeBaseLock() { UnlockCodeBase(); }
|
||||
};
|
||||
|
||||
CppBase& CodeBase();
|
||||
|
|
|
|||
|
|
@ -459,10 +459,11 @@ void Ide::JumpToDefinition(const Array<CppItem>& n, int q, const String& scope)
|
|||
}
|
||||
i++;
|
||||
}
|
||||
const CppItem& pos = n[qimpl >= 0 ? qimpl : qcpp >= 0 ? qcpp : q];
|
||||
CppItem pos = n[qimpl >= 0 ? qimpl : qcpp >= 0 ? qcpp : q];
|
||||
String path = GetSourceFilePath(pos.file);
|
||||
editastext.RemoveKey(path);
|
||||
editashex.RemoveKey(path);
|
||||
UnlockCodeBaseAll();
|
||||
if(!GotoDesignerFile(path, scope, pos.name, pos.line))
|
||||
GotoCpp(pos);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,16 +14,19 @@
|
|||
|
||||
String ResolveTParam(const String& type, const Vector<String>& tparam)
|
||||
{
|
||||
CodeBaseLock __;
|
||||
return ResolveTParam(CodeBase(), type, tparam);
|
||||
}
|
||||
|
||||
void ResolveTParam(Vector<String>& type, const Vector<String>& tparam)
|
||||
{
|
||||
CodeBaseLock __;
|
||||
return ResolveTParam(CodeBase(), type, tparam);
|
||||
}
|
||||
|
||||
String Qualify(const String& scope, const String& type, const String& usings)
|
||||
{
|
||||
CodeBaseLock __;
|
||||
return Qualify(CodeBase(), scope, type, usings);
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +44,7 @@ void AssistEditor::Context(ParserContext& parser, int pos)
|
|||
|
||||
theide->ScanFile(true);
|
||||
|
||||
parser = AssistParse(CodeBase(), Get(0, pos), theide->editfile, AssistScanError);
|
||||
parser = AssistParse(Get(0, pos), theide->editfile, AssistScanError);
|
||||
inbody = parser.IsInBody();
|
||||
#ifdef _DEBUG
|
||||
PutVerbose("body: " + AsString(inbody));
|
||||
|
|
@ -54,6 +57,7 @@ void AssistEditor::Context(ParserContext& parser, int pos)
|
|||
|
||||
Index<String> AssistEditor::EvaluateExpressionType(const ParserContext& parser, const Vector<String>& xp)
|
||||
{
|
||||
CodeBaseLock __;
|
||||
return GetExpressionType(CodeBase(), parser, xp);
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +75,7 @@ void AssistEditor::GatherItems(const String& type, bool only_public, Index<Strin
|
|||
{
|
||||
LTIMING("GatherItems");
|
||||
LLOG("---- GatherItems " << type);
|
||||
CodeBaseLock __;
|
||||
if(in_types.Find(type) >= 0) {
|
||||
LLOG("-> recursion, exiting");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ bool Ide::SwapSIf(const char *cref)
|
|||
break;
|
||||
}
|
||||
}
|
||||
GotoCpp(*n[i % n.GetCount()]);
|
||||
CppItem m = *n[i % n.GetCount()];
|
||||
UnlockCodeBaseAll();
|
||||
GotoCpp(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue