Browse Source

Last crash when writing code hopefully fixed. Taking care now not to read from view-buffer in a thread (only do this in GTK-main-thread).

merge-requests/365/head
eidheim 11 years ago
parent
commit
0bd7470d28
  1. 55
      juci/source.cc
  2. 7
      juci/source.h

55
juci/source.cc

@ -240,7 +240,7 @@ HighlightToken(clang::Token *token,
// Constructor for Controller // Constructor for Controller
Source::Controller::Controller(const Source::Config &config, Source::Controller::Controller(const Source::Config &config,
Notebook::Controller &notebook) : Notebook::Controller &notebook) :
config(config), notebook(notebook) { config(config), notebook(notebook), parse_thread_go(false), parse_thread_mapped(false) {
INFO("Source Controller with childs constructed"); INFO("Source Controller with childs constructed");
view.signal_key_press_event().connect(sigc::mem_fun(*this, &Source::Controller::OnKeyPress), false); view.signal_key_press_event().connect(sigc::mem_fun(*this, &Source::Controller::OnKeyPress), false);
view.set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); view.set_smart_home_end(Gsv::SMART_HOME_END_BEFORE);
@ -316,35 +316,50 @@ void Source::Controller::OnOpenFile(const string &filepath) {
notebook.index()); notebook.index());
view.OnUpdateSyntax(parser.ExtractTokens(start_offset, end_offset), config); view.OnUpdateSyntax(parser.ExtractTokens(start_offset, end_offset), config);
//OnUpdateSyntax must happen in main thread, so the parse-thread //GTK-calls must happen in main thread, so the parse_thread
//sends a signal to the main thread that it is to call the following function: //sends signals to the main thread that it is to call the following functions:
parsing_done.connect([this](){ parse_start.connect([this]{
if(parse_thread_buffers_mutex.try_lock()) {
notebook.MapBuffers(&this->parse_thread_buffers);
parse_thread_mapped=true;
parse_thread_buffers_mutex.unlock();
}
parse_thread_go=true;
});
parse_done.connect([this](){
if(parse_thread_mapped) {
INFO("Updating syntax"); INFO("Updating syntax");
view. view.
OnUpdateSyntax(parser.ExtractTokens(0, buffer()->get_text().size()), config); OnUpdateSyntax(parser.ExtractTokens(0, buffer()->get_text().size()), config);
INFO("Syntax updated"); INFO("Syntax updated");
}
else {
parse_thread_go=true;
}
}); });
buffer()->signal_end_user_action().connect([this]() { std::thread parse_thread([this]() {
std::thread parse([this]() {
if (parsing.try_lock()) {
INFO("Starting parsing");
while(true) { while(true) {
const std::string raw = buffer()->get_text().raw(); while(!parse_thread_go) std::this_thread::yield();
std::map<std::string, std::string> buffers; if(!parse_thread_mapped) {
notebook.MapBuffers(&buffers); parse_thread_go=false;
buffers[parser.file_path] = raw; parse_start();
if (parser.ReParse(buffers) == 0 && }
raw == buffer()->get_text().raw()) { else if (parse_thread_mapped && parsing.try_lock() && parse_thread_buffers_mutex.try_lock()) {
break; parser.ReParse(this->parse_thread_buffers);
} parse_thread_go=false;
}
parsing.unlock(); parsing.unlock();
parsing_done(); parse_thread_buffers_mutex.unlock();
INFO("Parsing completed"); parse_done();
}
} }
}); });
parse.detach(); parse_thread.detach();
buffer()->signal_changed().connect([this]() {
parse_thread_mapped=false;
parse_thread_go=true;
}); });
} }
} }

7
juci/source.h

@ -146,7 +146,12 @@ namespace Source {
void OnLineEdit(); void OnLineEdit();
void OnSaveFile(); void OnSaveFile();
std::mutex parsing; std::mutex parsing;
Glib::Dispatcher parsing_done; Glib::Dispatcher parse_done;
Glib::Dispatcher parse_start;
std::map<std::string, std::string> parse_thread_buffers;
std::mutex parse_thread_buffers_mutex;
std::atomic<bool> parse_thread_go;
std::atomic<bool> parse_thread_mapped;
const Config& config; const Config& config;
Notebook::Controller& notebook; //TODO: should maybe be const, but that involves a small change in libclangmm Notebook::Controller& notebook; //TODO: should maybe be const, but that involves a small change in libclangmm

Loading…
Cancel
Save