Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:33

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_LOCKEDHANDLE
0012 #define GAUDIKERNEL_LOCKEDHANDLE 1
0013 
0014 #include <mutex>
0015 
0016 // =======================================================================
0017 /** @class LockedHandle
0018  *
0019  *  Provides automatic lock/unlock access to a class upon deref of ptr.
0020  *  default type of mutex to use is a std::mutex, but this can be
0021  *  overridden with a second template parameter, as long as the type
0022  *  provides the lock() and unlock() functions
0023  *
0024  *  @code
0025  *
0026  *  std::mutex the_mutex;
0027  *  Obj *o = new Obj();
0028  *  LockedHandle<Obj> lh(o, &the_mutex);
0029  *  o->doSomething();
0030  *
0031  *  @endcode
0032  *
0033  *  @author Charles Leggett / Goetz Gaycken
0034  *  @date   2016-07-01
0035  */
0036 
0037 template <class T, class MutexType = std::mutex>
0038 class LockedHandle {
0039 public:
0040   LockedHandle( T* ptr, MutexType& mut ) : m_ptr( ptr ), m_mutex( &mut ) {}
0041   LockedHandle( T* ptr, MutexType* mut ) : m_ptr( ptr ), m_mutex( mut ) {}
0042   LockedHandle( T* ptr ) : m_ptr( ptr ), m_mutex( 0 ) {}
0043   LockedHandle() : m_ptr( nullptr ), m_mutex( nullptr ) {}
0044 
0045   void set( T* ptr, MutexType* mut ) {
0046     m_ptr   = ptr;
0047     m_mutex = mut;
0048   }
0049 
0050   void setMutex( MutexType* mut ) { m_mutex = mut; }
0051 
0052   T* get() const { return m_ptr; }
0053 
0054   class Guard {
0055     Guard( const Guard& a ) = delete;
0056 
0057   public:
0058     Guard( Guard&& a ) : m_ptr( a.m_ptr ), m_mutex( a.m_mutex ) { a.m_mutex = nullptr; }
0059 
0060     Guard( T* ptr, MutexType& mutex ) : m_ptr( ptr ), m_mutex( &mutex ) { m_mutex->lock(); }
0061     ~Guard() { m_mutex->unlock(); }
0062     T& operator*() { return *m_ptr; }
0063     T* operator->() { return m_ptr; }
0064 
0065     operator T&() { return *m_ptr; }
0066 
0067   private:
0068     T*         m_ptr{ nullptr };
0069     MutexType* m_mutex{ nullptr };
0070   };
0071 
0072   class ConstGuard {
0073     ConstGuard( const ConstGuard& a ) = delete;
0074 
0075   public:
0076     ConstGuard( ConstGuard&& a ) : m_ptr( a.m_ptr ), m_mutex( a.m_mutex ) { a.m_mutex = nullptr; }
0077 
0078     ConstGuard( const T* ptr, MutexType& mutex ) : m_ptr( ptr ), m_mutex( &mutex ) { m_mutex->lock(); }
0079     ~ConstGuard() { m_mutex->unlock(); }
0080     const T& operator*() const { return *m_ptr; }
0081     const T* operator->() const { return m_ptr; }
0082 
0083     operator const T&() const { return *m_ptr; }
0084 
0085   private:
0086     const T*   m_ptr;
0087     MutexType* m_mutex;
0088   };
0089 
0090   /// Aquire and release the lock before and after the object is accessed.
0091   Guard operator*() { return Guard( m_ptr, *m_mutex ); }
0092 
0093   /// Aquire and release the lock before and after the object is accessed.
0094   Guard operator->() { return Guard( m_ptr, *m_mutex ); }
0095 
0096   /// Aquire and release the lock before and after the const object is accessed.
0097   ConstGuard operator*() const { return ConstGuard( m_ptr, *m_mutex ); }
0098 
0099   /// Aquire and release the lock before and after the const object is accessed.
0100   ConstGuard operator->() const { return ConstGuard( m_ptr, *m_mutex ); }
0101 
0102   operator bool() const { return m_ptr; }
0103 
0104 private:
0105   T*                 m_ptr;
0106   mutable MutexType* m_mutex;
0107 };
0108 
0109 #endif