Skip to content

Commit d3e3fda

Browse files
committed
* Move reparse to background thread
1 parent 662f69e commit d3e3fda

File tree

6 files changed

+77
-4
lines changed

6 files changed

+77
-4
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ Code::Blocks plugin integrating various features of LLVM Clang.
77

88
========
99
### Wish/todo list
10-
- [ ] Threaded parsing
1110
- [ ] Settings page
1211
- [ ] Autocomplete output format
1312
- [ ] Diagnostics visualization
1413
- [ ] More...
1514
- [ ] Preemptive codecomplete results caching
16-
- [ ] Asynchronous codecomplete queries
1715
- [ ] Resolve crash on fast exit
1816
- [ ] Support MSVC projects/unrecognized command line flags
1917
- [ ] Resolve mysterious crashes...

clangplugin.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,16 @@ void ClangPlugin::OnAttach()
155155
Connect(idHightlightTimer, wxEVT_TIMER, wxTimerEventHandler(ClangPlugin::OnTimer));
156156
Connect(idGotoDeclaration, wxEVT_COMMAND_MENU_SELECTED, /*wxMenuEventHandler*/wxCommandEventHandler(ClangPlugin::OnGotoDeclaration), nullptr, this);
157157
Connect(EVT_PARSE_CC_READY, wxCommandEventHandler(ClangPlugin::OnCodeCompleteReady));
158+
Connect(EVT_REPARSE_DONE, wxCommandEventHandler(ClangPlugin::OnReparseDone));
158159
m_EditorHookId = EditorHooks::RegisterHook(new EditorHooks::HookFunctor<ClangPlugin>(this, &ClangPlugin::OnEditorHook));
159160
}
160161

161162
void ClangPlugin::OnRelease(bool WXUNUSED(appShutDown))
162163
{
163164
wxMutexLocker locker(m_ProxyMutex);
164165
EditorHooks::UnregisterHook(m_EditorHookId);
166+
Disconnect(wxID_ANY, EVT_REPARSE_DONE);
167+
Disconnect(wxID_ANY, EVT_PARSE_CC_READY);
165168
Disconnect(idGotoDeclaration);
166169
Disconnect(idHightlightTimer);
167170
Disconnect(idDiagnosticTimer);
@@ -639,6 +642,17 @@ void ClangPlugin::OnCodeCompleteReady(wxCommandEvent& event)
639642
m_AsyncStatusCC = ascNone;
640643
}
641644

645+
void ClangPlugin::OnReparseDone(wxCommandEvent& WXUNUSED(event))
646+
{
647+
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
648+
if (!ed || ed != m_pLastEditor)
649+
return;
650+
if (m_ProxyMutex.TryLock() != wxMUTEX_NO_ERROR)
651+
return;
652+
MutexUnlocker unlocker(m_ProxyMutex);
653+
DiagnoseEd(ed, dlMinimal);
654+
}
655+
642656
wxString ClangPlugin::GetCompilerInclDirs(const wxString& compId)
643657
{
644658
std::map<wxString, wxString>::const_iterator idItr = m_compInclDirs.find(compId);
@@ -894,7 +908,10 @@ void ClangPlugin::OnTimer(wxTimerEvent& event)
894908
return;
895909

896910
if (m_ProxyMutex.TryLock() != wxMUTEX_NO_ERROR)
911+
{
912+
m_EdOpenTimer.Start(ED_OPEN_DELAY, wxTIMER_ONE_SHOT);
897913
return;
914+
}
898915
MutexUnlocker unlocker(m_ProxyMutex);
899916
if (m_Proxy.GetTranslationUnitId(ed->GetFilename()) != wxNOT_FOUND)
900917
{
@@ -927,7 +944,10 @@ void ClangPlugin::OnTimer(wxTimerEvent& event)
927944
if (!ed)
928945
return;
929946
if (m_ProxyMutex.TryLock() != wxMUTEX_NO_ERROR)
947+
{
948+
m_ReparseTimer.Start(REPARSE_DELAY, wxTIMER_ONE_SHOT);
930949
return;
950+
}
931951
MutexUnlocker unlocker(m_ProxyMutex);
932952

933953
if (ed != m_pLastEditor)
@@ -944,8 +964,13 @@ void ClangPlugin::OnTimer(wxTimerEvent& event)
944964
if (ed && ed->GetModified())
945965
unsavedFiles.insert(std::make_pair(ed->GetFilename(), ed->GetControl()->GetText()));
946966
}
947-
m_Proxy.Reparse(m_TranslUnitId, unsavedFiles);
948-
DiagnoseEd(m_pLastEditor, dlMinimal);
967+
ParseThreadReparse* parseThread = new ParseThreadReparse(m_Proxy, m_ProxyMutex, m_TranslUnitId, unsavedFiles, this);
968+
parseThread->Create();
969+
if (parseThread->Run() != wxTHREAD_NO_ERROR)
970+
{
971+
delete parseThread;
972+
parseThread = nullptr;
973+
}
949974
}
950975
// m_DiagnosticTimer, m_HightlightTime
951976
else if (evId == idDiagnosticTimer || evId == idHightlightTimer)
@@ -954,7 +979,13 @@ void ClangPlugin::OnTimer(wxTimerEvent& event)
954979
if (!ed)
955980
return;
956981
if (m_ProxyMutex.TryLock() != wxMUTEX_NO_ERROR)
982+
{
983+
if (evId == idDiagnosticTimer)
984+
m_DiagnosticTimer.Start(DIAGNOSTIC_DELAY, wxTIMER_ONE_SHOT);
985+
else
986+
m_HightlightTimer.Start(HIGHTLIGHT_DELAY, wxTIMER_ONE_SHOT);
957987
return;
988+
}
958989
MutexUnlocker unlocker(m_ProxyMutex);
959990

960991
if (ed != m_pLastEditor)

clangplugin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class ClangPlugin : public cbCodeCompletionPlugin
8787
/// Resolve the token under the cursor and open the relevant location
8888
void OnGotoDeclaration(wxCommandEvent& event);
8989
void OnCodeCompleteReady(wxCommandEvent& event);
90+
void OnReparseDone(wxCommandEvent& event);
9091

9192
enum DiagnosticLevel { dlMinimal, dlFull };
9293
/**

clangproxy.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "clangproxy.h"
88

9+
#include <clang-c/Documentation.h>
910
#include <wx/tokenzr.h>
1011

1112
#ifndef CB_PRECOMP

parsethread.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "parsethread.h"
44

55
DEFINE_LOCAL_EVENT_TYPE(EVT_PARSE_CC_READY)
6+
DEFINE_LOCAL_EVENT_TYPE(EVT_REPARSE_DONE)
67

78
ParseThreadCreate::ParseThreadCreate(ClangProxy& proxy, wxMutex& proxyMutex, const wxString& compileCommand,
89
const wxString& filename, const wxString& source) :
@@ -50,3 +51,24 @@ wxThread::ExitCode ParseThreadCodeComplete::Entry()
5051
m_pHandler->AddPendingEvent(evt);
5152
return 0;
5253
}
54+
55+
ParseThreadReparse::ParseThreadReparse(ClangProxy& proxy, wxMutex& proxyMutex, int translId,
56+
const std::map<wxString, wxString>& unsavedFiles,
57+
wxEvtHandler* handler) :
58+
m_Proxy(proxy), m_ProxyMutex(proxyMutex), m_TranslId(translId), m_pHandler(handler)
59+
{
60+
for (std::map<wxString, wxString>::const_iterator fileIt = unsavedFiles.begin();
61+
fileIt != unsavedFiles.end(); ++fileIt)
62+
{
63+
m_UnsavedFiles[fileIt->first.c_str()] = fileIt->second.c_str();
64+
}
65+
}
66+
67+
wxThread::ExitCode ParseThreadReparse::Entry()
68+
{
69+
wxMutexLocker locker(m_ProxyMutex);
70+
m_Proxy.Reparse(m_TranslId, m_UnsavedFiles);
71+
wxCommandEvent evt(EVT_REPARSE_DONE);
72+
m_pHandler->AddPendingEvent(evt);
73+
return 0;
74+
}

parsethread.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "clangproxy.h"
55

66
DECLARE_LOCAL_EVENT_TYPE(EVT_PARSE_CC_READY, -1)
7+
DECLARE_LOCAL_EVENT_TYPE(EVT_REPARSE_DONE, -1)
78

89
class ParseThreadCreate : public wxThread
910
{
@@ -47,4 +48,23 @@ class ParseThreadCodeComplete : public wxThread
4748
wxEvtHandler* m_pHandler;
4849
};
4950

51+
52+
class ParseThreadReparse : public wxThread
53+
{
54+
public:
55+
ParseThreadReparse(ClangProxy& proxy, wxMutex& proxyMutex, int translId,
56+
const std::map<wxString, wxString>& unsavedFiles, wxEvtHandler* handler);
57+
virtual ~ParseThreadReparse() {}
58+
59+
protected:
60+
virtual ExitCode Entry();
61+
62+
private:
63+
ClangProxy& m_Proxy;
64+
wxMutex& m_ProxyMutex;
65+
int m_TranslId;
66+
std::map<wxString, wxString> m_UnsavedFiles;
67+
wxEvtHandler* m_pHandler;
68+
};
69+
5070
#endif // PARSETHREAD_H

0 commit comments

Comments
 (0)