GEOSX
MultiMutexesLock.hpp
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 #ifndef MULTIMUTEXESLOCK_HPP
15 #define MULTIMUTEXESLOCK_HPP
16 
17 #include <mutex>
18 #include <tuple>
19 
20 #include "codingUtilities/Utilities.hpp"
21 
22 namespace geos
23 {
24 
28 template< typename ... Mutexes >
30 {
31 public:
36  MultiMutexesLock( Mutexes &... mutexes )
37  : m_islocked( false ), m_mutexes( mutexes ... )
38  {
39  lock();
40  }
41 
46  {
47  unlock();
48  }
49 
53  void lock()
54  {
55  if( m_islocked ) return;
56  apply( []( auto && ... mutexes ){ std::lock( mutexes ... ); }, m_mutexes );
57  m_islocked = true;
58  }
59 
63  void unlock()
64  {
65  if( !m_islocked ) return;
66  forEachArgInTuple( m_mutexes, []( auto & mutex, auto ){ mutex.unlock(); } );
67  m_islocked = false;
68  }
69 
70 private:
72  bool m_islocked;
74  std::tuple< Mutexes &... > m_mutexes;
75 };
76 
82 template< typename ... Mutexes >
83 auto make_multilock( Mutexes && ... mutexes )
84 {
85  return MultiMutexesLock< Mutexes... >( std::forward< Mutexes >( mutexes )... );
86 }
87 }
88 #endif // MULTIMUTEXESLOCK_HPP
Class to handle locks using 2 mutexes.
~MultiMutexesLock()
Unlock the mutexes and destroy the locks.
void lock()
Lock the two mutexes using std::lock is not already owning lock.
MultiMutexesLock(Mutexes &... mutexes)
Construct a multi mutexes lock and lock the mutexes.
void unlock()
Unlock the two mutexes is owning them.
auto make_multilock(Mutexes &&... mutexes)
Helper to construct MultiMutexesLock (usage auto lock = make_multilock( mutex1, mutex2,...