Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:13:11

0001 #ifndef FWCore_Utilities_CallNTimesNoWait_h
0002 #define FWCore_Utilities_CallNTimesNoWait_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/Utilities
0006 // Class  :     CallNTimesNoWait
0007 //
0008 /**\class edm::CallNTimesNoWait CallNTimesNoWait.h "CallNTimesNoWait.h"
0009 
0010  Description: Thread safe way to do something N times
0011 
0012  Usage:
0013     This class allows one to safely do a 'non-side-effect' operation N times in a job.
0014  An example use would be
0015  \code
0016     void myFunc( int iValue) {
0017       static CallNTimesNoWait message{2};
0018       message([&]() { edm::LogInfo("IWantToKnow")<<"called with "<<iValue; } );
0019  \endcode
0020  The important thing to remember, is there is no guarantee that the operation being run
0021  finishes before a thread which doesn't get to run the operation reaches the code following
0022  the call. Therefore it is useful to suppress messages but should not be used to do something
0023  like filling a container with values since the filling is not guaranteed to complete before
0024  another thread skips the call.
0025 */
0026 //
0027 // Original Author:  Chris Jones
0028 //         Created:  Fri, 15 Nov 2013 14:29:41 GMT
0029 //
0030 
0031 // system include files
0032 #include <atomic>
0033 
0034 // user include files
0035 
0036 // forward declarations
0037 namespace edm {
0038   class CallNTimesNoWait {
0039   public:
0040     CallNTimesNoWait(unsigned short iNTimes) : m_ntimes(static_cast<int>(iNTimes) - 1), m_done(false) {}
0041 
0042     template <typename T>
0043     void operator()(T iCall) {
0044       if (not m_done.load(std::memory_order_acquire)) {
0045         if (m_ntimes.fetch_sub(1, std::memory_order_acq_rel) < 0) {
0046           m_done.store(true, std::memory_order_release);
0047           return;
0048         };
0049         iCall();
0050       }
0051     }
0052 
0053   private:
0054     std::atomic<int> m_ntimes;
0055     std::atomic<bool> m_done;
0056   };
0057 }  // namespace edm
0058 
0059 #endif