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()