diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index 27ed74ddd8fd93fbd985d546887dd44121e1ef42..b5822d95e7c1bc05397c53e0c8fbac6abb8b28f5 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -230,6 +230,9 @@ std::map<std::string, std::string> &Msg::GetCommandLineStrings() void Msg::SetProgressMeterStep(int step) { +#if defined(_OPENMP) +#pragma omp critical +#endif _progressMeterStep = step; } @@ -588,15 +591,10 @@ void Msg::Info(const char *fmt, ...) if(_client) _client->Info(str); #if defined(HAVE_FLTK) -#if defined(_OPENMP) - #pragma omp critical -#endif - { - if(FlGui::available()){ - FlGui::instance()->check(); - std::string tmp = std::string("Info : ") + str; - FlGui::instance()->addMessage(tmp.c_str()); - } + if(FlGui::available()){ + FlGui::instance()->check(); + std::string tmp = std::string("Info : ") + str; + FlGui::instance()->addMessage(tmp.c_str()); } #endif @@ -629,16 +627,11 @@ void Msg::Direct(const char *fmt, ...) if(_client) _client->Info(str); #if defined(HAVE_FLTK) -#if defined(_OPENMP) -#pragma omp master -#endif - { - if(FlGui::available()){ - FlGui::instance()->check(); - std::string tmp = std::string(CTX::instance()->guiColorScheme ? "@B136@." : "@C4@.") - + str; - FlGui::instance()->addMessage(tmp.c_str()); - } + if(FlGui::available()){ + FlGui::instance()->check(); + std::string tmp = std::string(CTX::instance()->guiColorScheme ? "@B136@." : "@C4@.") + + str; + FlGui::instance()->addMessage(tmp.c_str()); } #endif @@ -675,18 +668,13 @@ void Msg::StatusBar(bool log, const char *fmt, ...) if(_client && log) _client->Info(str); #if defined(HAVE_FLTK) -#if defined(_OPENMP) -#pragma omp master -#endif - { - if(FlGui::available()){ - if(log) FlGui::instance()->check(); - if(!log || _verbosity > 4) - FlGui::instance()->setStatus(str); - if(log){ - std::string tmp = std::string("Info : ") + str; - FlGui::instance()->addMessage(tmp.c_str()); - } + if(FlGui::available()){ + if(log) FlGui::instance()->check(); + if(!log || _verbosity > 4) + FlGui::instance()->setStatus(str); + if(log){ + std::string tmp = std::string("Info : ") + str; + FlGui::instance()->addMessage(tmp.c_str()); } } #endif @@ -784,8 +772,13 @@ void Msg::ProgressMeter(int n, int N, bool log, const char *fmt, ...) fflush(stdout); } - while(_progressMeterCurrent < percent) - _progressMeterCurrent += _progressMeterStep; +#if defined(_OPENMP) +#pragma omp critical +#endif + { + while(_progressMeterCurrent < percent) + _progressMeterCurrent += _progressMeterStep; + } } } diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index c6b24ba52607faab5ab27d37f40ea4ef833b653f..a0b5021ccb366b53492049395de08736dcbd8ebd 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -52,13 +52,41 @@ #endif // check (now!) if there are any pending events, and process them -void FlGui::check(){ Fl::check(); } +void FlGui::check() +{ + if(Msg::GetThreadNum() == 0) Fl::check(); +} // wait (possibly indefinitely) for any events, then process them -void FlGui::wait(){ Fl::wait(); } +void FlGui::wait() +{ + if(Msg::GetThreadNum() == 0) Fl::wait(); +} // wait (at most time seconds) for any events, then process them -void FlGui::wait(double time){ Fl::wait(time); } +void FlGui::wait(double time) +{ + if(Msg::GetThreadNum() == 0) Fl::wait(time); +} + +void FlGui::lock() +{ +#if defined(_OPENMP) + if(Msg::GetThreadNum() > 0){ + Fl::lock(); + } +#endif +} + +void FlGui::unlock() +{ +#if defined(_OPENMP) + if(Msg::GetThreadNum() > 0){ + Fl::unlock(); + //Fl::awake(); + } +#endif +} void FlGui::setOpenedThroughMacFinder(const std::string &name) { @@ -300,6 +328,11 @@ FlGui::FlGui(int argc, char **argv) Fl::error = error_handler; Fl::fatal = fatal_error_handler; +#if defined(_OPENMP) + // tell fltk we're in multi-threaded mode + Fl::lock(); +#endif + // set X display if(CTX::instance()->display.size()) Fl::display(CTX::instance()->display.c_str()); @@ -464,7 +497,6 @@ bool FlGui::available() return (_instance != 0); } - FlGui *FlGui::instance(int argc, char **argv) { if(!_instance){ @@ -1229,8 +1261,9 @@ void window_cb(Fl_Widget *w, void *data) void FlGui::addMessage(const char *msg) { - for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++){ FlGui::instance()->graph[i]->addMessage(msg); + } } void FlGui::saveMessages(const char *fileName) diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h index 3ed9d80b83100e68275e7e53c782a022cb39a909..b1ad8bd291dd7cc9d2b9e692ef3d5f03cb231120 100644 --- a/Fltk/FlGui.h +++ b/Fltk/FlGui.h @@ -89,6 +89,9 @@ class FlGui{ static void wait(); // wait (at most time seconds) for any events, then process them static void wait(double time); + // lock/unlock child threads + static void lock(); + static void unlock(); // is a file opened through the Mac Finder? static void setOpenedThroughMacFinder(const std::string &name); static std::string getOpenedThroughMacFinder(); diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index f651872319348ea7e5280814cef1467c2778f37c..58fb24fa31841594254655053312527cb2991193 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -3508,10 +3508,19 @@ int graphicWindow::getMessageHeight() void graphicWindow::addMessage(const char *msg) { if(!_browser) return; - _messages.push_back(msg); - _browser->add(msg); - if(_autoScrollMessages && _win->shown() && _browser->h() >= FL_NORMAL_SIZE) - _browser->bottomline(_browser->size()); + + // this routine can be called from multiple threads, e.g. via Msg::Info calls + // in meshGFace(). We should use FlGui::lock/unlock, but currently this does + // not seem to work (17/02/2017) +#if defined(_OPENMP) +#pragma omp critical +#endif + { + _messages.push_back(msg); + _browser->add(msg); + if(_autoScrollMessages && _win->shown() && _browser->h() >= FL_NORMAL_SIZE) + _browser->bottomline(_browser->size()); + } } void graphicWindow::clearMessages()