From 510591abe36a7521fe60e4a55b012b23e9a3108f Mon Sep 17 00:00:00 2001 From: Christopher Jones Date: Mon, 22 Jun 2015 16:54:02 +0200 Subject: [PATCH] Made file access in SimHitPrinter thread safe Since multiple instances of SimHitPrinter all share the same output file via a static and those instances can be running on different threads the file has to be protected by a mutex. In addition, the creation of the file itself is done in a thread safe way. --- SimG4CMS/Muon/interface/SimHitPrinter.h | 3 ++- SimG4CMS/Muon/src/SimHitPrinter.cc | 35 ++++++++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/SimG4CMS/Muon/interface/SimHitPrinter.h b/SimG4CMS/Muon/interface/SimHitPrinter.h index 64a64cb217d9c..e4ff8361f2391 100644 --- a/SimG4CMS/Muon/interface/SimHitPrinter.h +++ b/SimG4CMS/Muon/interface/SimHitPrinter.h @@ -18,6 +18,7 @@ #include "DataFormats/GeometryVector/interface/LocalPoint.h" #include +#include class SimHitPrinter { public: @@ -34,7 +35,7 @@ class SimHitPrinter { void printLocal(LocalPoint,LocalPoint) const; void printGlobal(GlobalPoint) const; private: - static std::ofstream * theFile; + static std::atomic theFile; }; #endif diff --git a/SimG4CMS/Muon/src/SimHitPrinter.cc b/SimG4CMS/Muon/src/SimHitPrinter.cc index 5d324a2abdf05..4d7c7887732d3 100644 --- a/SimG4CMS/Muon/src/SimHitPrinter.cc +++ b/SimG4CMS/Muon/src/SimHitPrinter.cc @@ -2,13 +2,25 @@ #include #include +#include +#include -std::ofstream * SimHitPrinter::theFile(0); +std::atomic SimHitPrinter::theFile(nullptr); + +namespace { + std::mutex fileMutex; +} SimHitPrinter::SimHitPrinter(std::string filename){ if (theFile) return; const char* theName = filename.c_str(); - theFile = new std::ofstream(theName, std::ios::out); + auto f = std::make_unique(theName, std::ios::out); + + std::ofstream* previous = nullptr; + if(theFile.compare_exchange_strong(previous,f.get()) ) { + //this thread was the first one to try to set the value + f.release(); + } } SimHitPrinter::~SimHitPrinter(){ @@ -21,6 +33,8 @@ void SimHitPrinter::startNewSimHit(std::string s){ std::cout.setf(std::ios::scientific,std::ios::floatfield); std::cout.precision(6); std::cout << "SimHit in "< guard{fileMutex}; (*theFile).width(10); (*theFile).setf(std::ios::right,std::ios::adjustfield); (*theFile).setf(std::ios::scientific|std::ios::uppercase|std::ios::showpos,std::ios::floatfield); @@ -29,11 +43,13 @@ void SimHitPrinter::startNewSimHit(std::string s){ } void SimHitPrinter::startNewEvent(int num){ + std::lock_guard guard{fileMutex}; (*theFile) << "Event "< guard{fileMutex}; (*theFile) << " id "; (*theFile).width(10); (*theFile).setf(std::ios::right,std::ios::adjustfield); @@ -42,6 +58,7 @@ void SimHitPrinter::printId(int id) const{ void SimHitPrinter::printTrack(int id) const{ std::cout << " Track: "< guard{fileMutex}; (*theFile) << " trk "; (*theFile).width(10); (*theFile).setf(std::ios::right,std::ios::adjustfield); @@ -50,34 +67,38 @@ void SimHitPrinter::printTrack(int id) const{ void SimHitPrinter::printPabs(float pabs) const{ std::cout << " Pabs: "< guard{fileMutex}; (*theFile) << " p "< guard{fileMutex}; (*theFile) << " e "< guard{fileMutex}; (*theFile).width(10); (*theFile).setf(std::ios::right,std::ios::adjustfield); (*theFile).setf(std::ios::floatfield); (*theFile).precision(6); - std::cout << " Local(en/ex): "< guard{fileMutex}; (*theFile).width(10); (*theFile).setf(std::ios::right,std::ios::adjustfield); (*theFile).setf(std::ios::floatfield); (*theFile).precision(6); - std::cout << " Global(en): "<