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. 73
      juci/source.cc
  2. 7
      juci/source.h

73
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,36 +316,51 @@ 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]{
INFO("Updating syntax"); if(parse_thread_buffers_mutex.try_lock()) {
view. notebook.MapBuffers(&this->parse_thread_buffers);
OnUpdateSyntax(parser.ExtractTokens(0, buffer()->get_text().size()), config); parse_thread_mapped=true;
INFO("Syntax updated"); parse_thread_buffers_mutex.unlock();
}
parse_thread_go=true;
});
parse_done.connect([this](){
if(parse_thread_mapped) {
INFO("Updating syntax");
view.
OnUpdateSyntax(parser.ExtractTokens(0, buffer()->get_text().size()), config);
INFO("Syntax updated");
}
else {
parse_thread_go=true;
}
}); });
buffer()->signal_end_user_action().connect([this]() { std::thread parse_thread([this]() {
std::thread parse([this]() { while(true) {
if (parsing.try_lock()) { while(!parse_thread_go) std::this_thread::yield();
INFO("Starting parsing"); if(!parse_thread_mapped) {
while (true) { parse_thread_go=false;
const std::string raw = buffer()->get_text().raw(); parse_start();
std::map<std::string, std::string> buffers; }
notebook.MapBuffers(&buffers); else if (parse_thread_mapped && parsing.try_lock() && parse_thread_buffers_mutex.try_lock()) {
buffers[parser.file_path] = raw; parser.ReParse(this->parse_thread_buffers);
if (parser.ReParse(buffers) == 0 && parse_thread_go=false;
raw == buffer()->get_text().raw()) { parsing.unlock();
break; parse_thread_buffers_mutex.unlock();
} parse_done();
} }
parsing.unlock(); }
parsing_done(); });
INFO("Parsing completed"); parse_thread.detach();
}
}); buffer()->signal_changed().connect([this]() {
parse.detach(); 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