diff --git a/src/debug_clang.cc b/src/debug_clang.cc index 63b53fd..11585ac 100644 --- a/src/debug_clang.cc +++ b/src/debug_clang.cc @@ -110,7 +110,7 @@ void Debug::Clang::start(const std::string &command, const boost::filesystem::pa debug_thread=std::thread([this, callback, status_callback, stop_callback]() { lldb::SBEvent event; while(true) { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(listener->GetNextEvent(event)) { if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) { auto state=process->GetStateFromEvent(event); @@ -178,7 +178,6 @@ void Debug::Clang::start(const std::string &command, const boost::filesystem::pa stop_callback("", 0, 0); process.reset(); this->state=lldb::StateType::eStateInvalid; - event_mutex.unlock(); return; } else if(state==lldb::StateType::eStateCrashed) { @@ -190,7 +189,6 @@ void Debug::Clang::start(const std::string &command, const boost::filesystem::pa stop_callback("", 0, 0); process.reset(); this->state=lldb::StateType::eStateInvalid; - event_mutex.unlock(); return; } } @@ -208,79 +206,72 @@ void Debug::Clang::start(const std::string &command, const boost::filesystem::pa Terminal::get().async_print(std::string(buffer, n), true); } } - event_mutex.unlock(); + lock.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } }); } void Debug::Clang::continue_debug() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) process->Continue(); - event_mutex.unlock(); } void Debug::Clang::stop() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateRunning) { auto error=process->Stop(); if(error.Fail()) Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); } - event_mutex.unlock(); } void Debug::Clang::kill() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(process) { auto error=process->Kill(); if(error.Fail()) Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); } - event_mutex.unlock(); } void Debug::Clang::step_over() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOver(); } - event_mutex.unlock(); } void Debug::Clang::step_into() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepInto(); } - event_mutex.unlock(); } void Debug::Clang::step_out() { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { process->GetSelectedThread().StepOut(); } - event_mutex.unlock(); } std::pair Debug::Clang::run_command(const std::string &command) { std::pair command_return; - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) { lldb::SBCommandReturnObject command_return_object; debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true); command_return.first=command_return_object.GetOutput(); command_return.second=command_return_object.GetError(); } - event_mutex.unlock(); return command_return; } std::vector Debug::Clang::get_backtrace() { std::vector backtrace; - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { auto thread=process->GetSelectedThread(); for(uint32_t c_f=0;c_f Debug::Clang::get_backtrace() { backtrace.emplace_back(backtrace_frame); } } - event_mutex.unlock(); return backtrace; } std::vector Debug::Clang::get_variables() { std::vector variables; - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { for(uint32_t c_t=0;c_tGetNumThreads();c_t++) { auto thread=process->GetThreadAtIndex(c_t); @@ -355,18 +345,16 @@ std::vector Debug::Clang::get_variables() { } } } - event_mutex.unlock(); return variables; } void Debug::Clang::select_frame(uint32_t frame_index, uint32_t thread_index_id) { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { if(thread_index_id!=0) process->SetSelectedThreadByIndexID(thread_index_id); process->GetSelectedThread().SetSelectedFrame(frame_index);; } - event_mutex.unlock(); } void Debug::Clang::delete_debug() { @@ -377,7 +365,7 @@ void Debug::Clang::delete_debug() { std::string Debug::Clang::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string variable_value; - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { auto frame=process->GetSelectedThread().GetSelectedFrame(); @@ -413,13 +401,12 @@ std::string Debug::Clang::get_value(const std::string &variable, const boost::fi } } } - event_mutex.unlock(); return variable_value; } std::string Debug::Clang::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string return_value; - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::StateType::eStateStopped) { auto thread=process->GetSelectedThread(); auto thread_return_value=thread.GetStopReturnValue(); @@ -437,45 +424,40 @@ std::string Debug::Clang::get_return_value(const boost::filesystem::path &file_p } } } - event_mutex.unlock(); return return_value; } bool Debug::Clang::is_invalid() { bool invalid; - event_mutex.lock(); + std::unique_lock lock(event_mutex); invalid=state==lldb::StateType::eStateInvalid; - event_mutex.unlock(); return invalid; } bool Debug::Clang::is_stopped() { bool stopped; - event_mutex.lock(); + std::unique_lock lock(event_mutex); stopped=state==lldb::StateType::eStateStopped; - event_mutex.unlock(); return stopped; } bool Debug::Clang::is_running() { bool running; - event_mutex.lock(); + std::unique_lock lock(event_mutex); running=state==lldb::StateType::eStateRunning; - event_mutex.unlock(); return running; } void Debug::Clang::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid()) Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+file_path.string()+":"+std::to_string(line_nr)+'\n', true); } - event_mutex.unlock(); } void Debug::Clang::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { - event_mutex.lock(); + std::unique_lock lock(event_mutex); if(state==lldb::eStateStopped || state==lldb::eStateRunning) { auto target=process->GetTarget(); for(int line_nr_try=line_nr;line_nr_try lock(event_mutex); if(state==lldb::StateType::eStateRunning) { process->PutSTDIN(buffer.c_str(), buffer.size()); } - event_mutex.unlock(); } diff --git a/src/directories.cc b/src/directories.cc index 5898c4c..2937374 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -147,22 +147,22 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { signal_test_expand_row().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){ if(iter->children().begin()->get_value(column_record.path)=="") { - update_mutex.lock(); + std::unique_lock lock(update_mutex); add_path(iter->get_value(column_record.path), *iter); - update_mutex.unlock(); } return false; }); signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path){ - update_mutex.lock(); - auto directory_str=iter->get_value(column_record.path).string(); - for(auto it=last_write_times.begin();it!=last_write_times.end();) { - if(directory_str==it->first.substr(0, directory_str.size())) - it=last_write_times.erase(it); - else - it++; + { + std::unique_lock lock(update_mutex); + auto directory_str=iter->get_value(column_record.path).string(); + for(auto it=last_write_times.begin();it!=last_write_times.end();) { + if(directory_str==it->first.substr(0, directory_str.size())) + it=last_write_times.erase(it); + else + it++; + } } - update_mutex.unlock(); auto children=iter->children(); if(children) { while(children) { @@ -179,7 +179,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { update_thread=std::thread([this](){ while(!stop_update_thread) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - update_mutex.lock(); + std::unique_lock lock(update_mutex); for(auto it=last_write_times.begin();it!=last_write_times.end();) { boost::system::error_code ec; auto last_write_time=boost::filesystem::last_write_time(it->first, ec); @@ -188,11 +188,10 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { if(last_write_time!=now && it->second.second(it->first); dispatcher.post([this, path, last_write_time] { - update_mutex.lock(); + std::unique_lock lock(update_mutex); auto it=last_write_times.find(*path); if(it!=last_write_times.end()) add_path(*path, it->second.first, last_write_time); - update_mutex.unlock(); }); } it++; @@ -200,7 +199,6 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { else it=last_write_times.erase(it); } - update_mutex.unlock(); } }); @@ -315,9 +313,10 @@ void Directories::open(const boost::filesystem::path &dir_path) { return; tree_store->clear(); - update_mutex.lock(); - last_write_times.clear(); - update_mutex.unlock(); + { + std::unique_lock lock(update_mutex); + last_write_times.clear(); + } //TODO: report that set_title does not handle '_' correctly? @@ -329,9 +328,10 @@ void Directories::open(const boost::filesystem::path &dir_path) { } get_column(0)->set_title(title); - update_mutex.lock(); - add_path(dir_path, Gtk::TreeModel::Row()); - update_mutex.unlock(); + { + std::unique_lock lock(update_mutex); + add_path(dir_path, Gtk::TreeModel::Row()); + } path=dir_path; @@ -340,11 +340,12 @@ void Directories::open(const boost::filesystem::path &dir_path) { void Directories::update() { JDEBUG("start"); - update_mutex.lock(); - for(auto &last_write_time: last_write_times) { - add_path(last_write_time.first, last_write_time.second.first); - } - update_mutex.unlock(); + { + std::unique_lock lock(update_mutex); + for(auto &last_write_time: last_write_times) { + add_path(last_write_time.first, last_write_time.second.first); + } + } JDEBUG("end"); } @@ -371,9 +372,8 @@ void Directories::select(const boost::filesystem::path &select_path) { for(auto &a_path: paths) { tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator &iter){ if(iter->get_value(column_record.path)==a_path) { - update_mutex.lock(); + std::unique_lock lock(update_mutex); add_path(a_path, *iter); - update_mutex.unlock(); return true; } return false; diff --git a/src/dispatcher.cc b/src/dispatcher.cc index e5cc42d..5d6cfaf 100644 --- a/src/dispatcher.cc +++ b/src/dispatcher.cc @@ -2,26 +2,24 @@ Dispatcher::Dispatcher() { connection=dispatcher.connect([this] { - functions_mutex.lock(); + std::unique_lock lock(functions_mutex); for(auto &function: functions) { function(); } functions.clear(); - functions_mutex.unlock(); }); } Dispatcher::~Dispatcher() { disconnect(); - functions_mutex.lock(); + std::unique_lock lock(functions_mutex); functions.clear(); - functions_mutex.unlock(); } void Dispatcher::post(std::function &&function) { - functions_mutex.lock(); + std::unique_lock lock(functions_mutex); functions.emplace_back(function); - functions_mutex.unlock(); + lock.unlock(); dispatcher(); } diff --git a/src/project.cc b/src/project.cc index 7ebc39f..fd44a5f 100644 --- a/src/project.cc +++ b/src/project.cc @@ -293,7 +293,7 @@ void Project::Clang::debug_start() { if(exit_status!=EXIT_SUCCESS) debugging=false; else { - debug_start_mutex.lock(); + std::unique_lock lock(debug_start_mutex); Debug::Clang::get().start(run_arguments, project_path, *breakpoints, [this, run_arguments](int exit_status){ debugging=false; Terminal::get().async_print(run_arguments+" returned: "+std::to_string(exit_status)+'\n'); @@ -310,7 +310,6 @@ void Project::Clang::debug_start() { debug_update_stop(); }); }); - debug_start_mutex.unlock(); } }); } @@ -497,9 +496,8 @@ void Project::Clang::debug_write(const std::string &buffer) { } void Project::Clang::debug_delete() { - debug_start_mutex.lock(); + std::unique_lock lock(debug_start_mutex); Debug::Clang::get().delete_debug(); - debug_start_mutex.unlock(); } #endif diff --git a/src/source_clang.cc b/src/source_clang.cc index d49aaab..c45e879 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -106,28 +106,31 @@ void Source::ClangViewParse::parse_initialize() { if(parse_state!=ParseState::PROCESSING) break; auto expected=ParseProcessState::STARTING; + std::unique_lock parse_lock(parse_mutex, std::defer_lock); if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { dispatcher.post([this] { auto expected=ParseProcessState::PREPROCESSING; - if(parse_mutex.try_lock()) { + std::unique_lock parse_lock(parse_mutex, std::defer_lock); + if(parse_lock.try_lock()) { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) parse_thread_buffer=get_buffer()->get_text(); - parse_mutex.unlock(); + parse_lock.unlock(); } else parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING); }); } - else if (parse_process_state==ParseProcessState::PROCESSING && parse_mutex.try_lock()) { + else if (parse_process_state==ParseProcessState::PROCESSING && parse_lock.try_lock()) { auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer.raw()); parsing_in_progress->done("done"); if(status==0) { auto expected=ParseProcessState::PROCESSING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); - parse_mutex.unlock(); + parse_lock.unlock(); dispatcher.post([this] { - if(parse_mutex.try_lock()) { + std::unique_lock parse_lock(parse_mutex, std::defer_lock); + if(parse_lock.try_lock()) { auto expected=ParseProcessState::POSTPROCESSING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { update_syntax(); @@ -135,16 +138,16 @@ void Source::ClangViewParse::parse_initialize() { parsed=true; set_status(""); } - parse_mutex.unlock(); + parse_lock.unlock(); } }); } else - parse_mutex.unlock(); + parse_lock.unlock(); } else { parse_state=ParseState::STOP; - parse_mutex.unlock(); + parse_lock.unlock(); dispatcher.post([this] { Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); set_status(""); @@ -623,16 +626,18 @@ void Source::ClangViewAutocomplete::autocomplete_check() { const boost::regex within_namespace("^(.*)([^a-zA-Z0-9_]+)([a-zA-Z0-9_]{3,})$"); boost::smatch sm; if(boost::regex_match(line, sm, in_specified_namespace)) { - prefix_mutex.lock(); - prefix=sm[3].str(); - prefix_mutex.unlock(); + { + std::unique_lock lock(prefix_mutex); + prefix=sm[3].str(); + } if(prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') autocomplete(); } else if(boost::regex_match(line, sm, within_namespace)) { - prefix_mutex.lock(); - prefix=sm[3].str(); - prefix_mutex.unlock(); + { + std::unique_lock lock(prefix_mutex); + prefix=sm[3].str(); + } if(prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') autocomplete(); } @@ -667,7 +672,7 @@ void Source::ClangViewAutocomplete::autocomplete() { pos--; } autocomplete_thread=std::thread([this, line_nr, column_nr, buffer](){ - parse_mutex.lock(); + std::unique_lock lock(parse_mutex); if(parse_state==ParseState::PROCESSING) { parse_process_state=ParseProcessState::IDLE; auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); @@ -726,7 +731,6 @@ void Source::ClangViewAutocomplete::autocomplete() { }); } } - parse_mutex.unlock(); }); } @@ -740,9 +744,10 @@ std::vector Source::ClangViewAu } if(autocomplete_state==AutocompleteState::STARTING) { - prefix_mutex.lock(); + std::unique_lock lock(prefix_mutex); auto prefix_copy=prefix; - prefix_mutex.unlock(); + lock.unlock(); + for (unsigned i = 0; i < results.size(); i++) { auto result=results.get(i); if(result.available()) { diff --git a/src/terminal.cc b/src/terminal.cc index ca7e020..c837535 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -9,9 +9,10 @@ Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { } Terminal::InProgress::~InProgress() { - stop_mutex.lock(); - stop=true; - stop_mutex.unlock(); + { + std::unique_lock lock(stop_mutex); + stop=true; + } if(wait_thread.joinable()) wait_thread.join(); } @@ -21,13 +22,11 @@ void Terminal::InProgress::start(const std::string& msg) { wait_thread=std::thread([this](){ size_t c=0; while(true) { - stop_mutex.lock(); - if(stop) { - stop_mutex.unlock(); - break; + { + std::unique_lock lock(stop_mutex); + if(stop) + break; } - else - stop_mutex.unlock(); if(c%100==0) Terminal::get().async_print(line_nr-1, "."); std::this_thread::sleep_for(std::chrono::milliseconds(10)); @@ -37,25 +36,21 @@ void Terminal::InProgress::start(const std::string& msg) { } void Terminal::InProgress::done(const std::string& msg) { - stop_mutex.lock(); + std::unique_lock lock(stop_mutex); if(!stop) { stop=true; - stop_mutex.unlock(); + lock.unlock(); Terminal::get().async_print(line_nr-1, msg); } - else - stop_mutex.unlock(); } void Terminal::InProgress::cancel(const std::string& msg) { - stop_mutex.lock(); + std::unique_lock lock(stop_mutex); if(!stop) { stop=true; - stop_mutex.unlock(); + lock.unlock(); Terminal::get().async_print(line_nr-1, msg); } - else - stop_mutex.unlock(); } Terminal::Terminal() { @@ -117,8 +112,8 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c } void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function callback) { - std::thread async_execute_thread([this, command, path, callback](){ - processes_mutex.lock(); + std::thread async_execute_thread([this, command, path, callback](){ + std::unique_lock processes_lock(processes_mutex); stdin_buffer.clear(); std::shared_ptr process(new Process(command, path.string(), [this](const char* bytes, size_t n) { async_print(std::string(bytes, n)); @@ -127,7 +122,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem }, true)); auto pid=process->get_id(); if (pid<=0) { - processes_mutex.unlock(); + processes_lock.unlock(); async_print("Error: failed to run command: " + command + "\n", true); if(callback) callback(-1); @@ -135,12 +130,12 @@ void Terminal::async_process(const std::string &command, const boost::filesystem } else { processes.emplace_back(process); - processes_mutex.unlock(); + processes_lock.unlock(); } auto exit_status=process->get_exit_status(); - processes_mutex.lock(); + processes_lock = std::unique_lock(processes_mutex); for(auto it=processes.begin();it!=processes.end();it++) { if((*it)->get_id()==pid) { processes.erase(it); @@ -148,7 +143,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem } } stdin_buffer.clear(); - processes_mutex.unlock(); + processes_lock.unlock(); if(callback) callback(exit_status); @@ -157,17 +152,15 @@ void Terminal::async_process(const std::string &command, const boost::filesystem } void Terminal::kill_last_async_process(bool force) { - processes_mutex.lock(); + std::unique_lock lock(processes_mutex); if(processes.size()>0) processes.back()->kill(force); - processes_mutex.unlock(); } void Terminal::kill_async_processes(bool force) { - processes_mutex.lock(); + std::unique_lock lock(processes_mutex); for(auto &process: processes) process->kill(force); - processes_mutex.unlock(); } size_t Terminal::print(const std::string &message, bool bold){ @@ -223,14 +216,16 @@ size_t Terminal::print(const std::string &message, bool bold){ std::shared_ptr Terminal::print_in_progress(std::string start_msg) { auto in_progress=std::shared_ptr(new Terminal::InProgress(start_msg), [this](Terminal::InProgress *in_progress) { - in_progresses_mutex.lock(); - in_progresses.erase(in_progress); - in_progresses_mutex.unlock(); + { + std::unique_lock lock(in_progresses_mutex); + in_progresses.erase(in_progress); + } delete in_progress; }); - in_progresses_mutex.lock(); - in_progresses.emplace(in_progress.get()); - in_progresses_mutex.unlock(); + { + std::unique_lock lock(in_progresses_mutex); + in_progresses.emplace(in_progress.get()); + } return in_progress; } @@ -277,20 +272,19 @@ void Terminal::configure() { } void Terminal::clear() { - in_progresses_mutex.lock(); + std::unique_lock lock(in_progresses_mutex); for(auto &in_progress: in_progresses) { - in_progress->stop_mutex.lock(); + std::unique_lock stop_lock(in_progress->stop_mutex); in_progress->stop=true; - in_progress->stop_mutex.unlock(); } - in_progresses_mutex.unlock(); + lock.unlock(); while(g_main_context_pending(NULL)) g_main_context_iteration(NULL, false); get_buffer()->set_text(""); } bool Terminal::on_key_press_event(GdkEventKey *event) { - processes_mutex.lock(); + std::unique_lock lock(processes_mutex); bool debug_is_running=false; #ifdef JUCI_ENABLE_DEBUG debug_is_running=Project::current_language?Project::current_language->debug_is_running():false; @@ -324,6 +318,5 @@ bool Terminal::on_key_press_event(GdkEventKey *event) { stdin_buffer.clear(); } } - processes_mutex.unlock(); return true; }