From 082a5f63f8b0a5d0fc942cbab4b4f39b40459b3f Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Thu, 6 Sep 2018 17:08:18 +0200
Subject: [PATCH] webgui: use special mutex in canvas painter to protect I/O

When many threads tries to stream same class for first time - it causes
I/O problem while many TClass and TStreamerInfo instances need to be
created. Probably global ROOT mutex has to be used.
---
 gui/canvaspainter/v7/src/TCanvasPainter.cxx | 23 ++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/gui/canvaspainter/v7/src/TCanvasPainter.cxx b/gui/canvaspainter/v7/src/TCanvasPainter.cxx
index 69150ace1a7..ad4b861ac3b 100644
--- a/gui/canvaspainter/v7/src/TCanvasPainter.cxx
+++ b/gui/canvaspainter/v7/src/TCanvasPainter.cxx
@@ -23,6 +23,8 @@
 #include <ROOT/TWebWindow.hxx>
 #include <ROOT/TWebWindowsManager.hxx>
 
+// #include "TVirtualMutex.h"
+
 #include <memory>
 #include <string>
 #include <vector>
@@ -30,6 +32,7 @@
 #include <thread>
 #include <chrono>
 #include <fstream>
+#include <mutex>
 
 #include "TList.h"
 #include "TROOT.h"
@@ -612,12 +615,22 @@ std::string ROOT::Experimental::TCanvasPainter::CreateSnapshot(const ROOT::Exper
    fPadDisplayItem->SetTitle(can.GetTitle());
    fPadDisplayItem->SetWindowSize(can.GetSize());
 
-   TString res = TBufferJSON::ToJSON(fPadDisplayItem.get(), 23);
+   static std::mutex sIOMutex;
+
+   TString res;
+
+   {
+      std::lock_guard<std::mutex> grd(sIOMutex);
 
-   if (!fNextDumpName.empty()) {
-      TBufferJSON::ExportToFile(fNextDumpName.c_str(), fPadDisplayItem.get(),
-         gROOT->GetClass("ROOT::Experimental::RPadDisplayItem"));
-      fNextDumpName.clear();
+      // R__LOCKGUARD(gROOTMutex);
+
+      res = TBufferJSON::ToJSON(fPadDisplayItem.get(), 23);
+
+      if (!fNextDumpName.empty()) {
+         TBufferJSON::ExportToFile(fNextDumpName.c_str(), fPadDisplayItem.get(),
+            gROOT->GetClass("ROOT::Experimental::RPadDisplayItem"));
+         fNextDumpName.clear();
+      }
    }
 
    fPadDisplayItem.reset(); // no need to keep memory any longer
-- 
GitLab