Leviathan  0.8.0.0
Leviathan game engine
ThreadSafe.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2018 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
6 #include "Logger.h"
7 
8 #include <memory>
9 #include <mutex>
10 #include <type_traits>
11 
12 namespace Leviathan {
13 
14 
15 // Individual lock objects //
16 using Mutex = std::mutex;
17 using RecursiveMutex = std::recursive_mutex;
18 using Lock = std::unique_lock<std::mutex>;
19 using RecursiveLock = std::lock_guard<std::recursive_mutex>;
20 
21 template<class LockType>
23 // {
24 //
25 // using LType = void;
26 //};
27 
28 template<>
30 
31  using LType = Lock;
32 };
33 
34 template<>
36 
38 };
39 
40 
41 class Locker {
42 
43  template<typename T>
44  static T* TurnToPointer(const std::shared_ptr<T>& obj)
45  {
46  return obj.get();
47  }
48 
49  template<typename T>
50  static T* TurnToPointer(const std::unique_ptr<T>& obj)
51  {
52  return obj.get();
53  }
54 
55  template<typename T>
56  static T* TurnToPointer(T& obj)
57  {
58  return &obj;
59  }
60 
61  template<typename T>
62  static T* TurnToPointer(T* obj)
63  {
64  return obj;
65  }
66 
67 public:
68  template<typename ObjectClass>
69  static auto& AcessLock(const ObjectClass* object)
70  {
71  return TurnToPointer(object)->ObjectsLock;
72  }
73 
74  template<typename ObjectClass>
75  static auto& AcessLock(const ObjectClass& object)
76  {
77  return TurnToPointer(object)->ObjectsLock;
78  }
79 
80  template<typename ObjectClass>
81  static auto Object(const ObjectClass* object)
82  {
83  return Unique(TurnToPointer(object)->ObjectsLock);
84  }
85 
86  template<typename ObjectClass>
87  static auto Object(const ObjectClass& object)
88  {
89  return Unique(TurnToPointer(object)->ObjectsLock);
90  }
91 
92  template<typename ObjectClass>
93  static auto Object(std::shared_ptr<ObjectClass>& object)
94  {
95  return Unique(object->ObjectsLock);
96  }
97 
98  template<typename ObjectClass>
99  static auto Object(std::unique_ptr<ObjectClass>& object)
100  {
101  return Unique(object->ObjectsLock);
102  }
103 
104  template<class LockType>
105  static auto Unique(LockType& lockref)
106  {
107  return typename LockTypeResolver<LockType>::LType(lockref);
108  }
109 };
110 
111 #define GUARD_LOCK() \
112  typename Leviathan::LockTypeResolver< \
113  std::remove_reference_t<decltype(Leviathan::Locker::AcessLock(this))>>::LType \
114  guard(Leviathan::Locker::AcessLock(this));
115 
116 #define GUARD_LOCK_NAME(y) \
117  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
118  Leviathan::Locker::AcessLock(this))>>::LType y(Leviathan::Locker::AcessLock(this));
119 
120 #define GUARD_LOCK_OTHER(x) \
121  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
122  Leviathan::Locker::AcessLock(x))>>::LType guard(Leviathan::Locker::AcessLock(x));
123 
124 #define GUARD_LOCK_OTHER(x) \
125  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
126  Leviathan::Locker::AcessLock(x))>>::LType guard(Leviathan::Locker::AcessLock(x));
127 #define GUARD_LOCK_OTHER_NAME(x, y) \
128  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
129  Leviathan::Locker::AcessLock(x))>>::LType y(Leviathan::Locker::AcessLock(x));
130 
132 #define REQUIRE_LOCKED(x) LEVIATHAN_ASSERT(x.owns_lock(), "Mutex doesn't own lock");
133 
136 template<class MutexType>
138 public:
140 
143 
145  {
146  // Apparently there is no way to verify this...
147  // if(!guard.owns_lock(&this->ObjectsLock))
148  // throw InvalidAccess("wrong lock owner");
149  }
150 
151  FORCE_INLINE void VerifyLock(Lock& lockit) const
152  {
153  // Make sure that the lock is locked //
154  LEVIATHAN_ASSERT(lockit.owns_lock(), "lock not locked");
155  }
156 
160  mutable MutexType ObjectsLock;
161 };
162 
165 
170 
171 } // namespace Leviathan
172 
173 #ifdef LEAK_INTO_GLOBAL
174 using Leviathan::Lock;
175 using Leviathan::Mutex;
178 
180 #endif // LEAK_INTO_GLOBAL
FORCE_INLINE void VerifyLock(RecursiveLock &guard) const
Definition: ThreadSafe.h:144
Allows the inherited object to be locked.
Definition: ThreadSafe.h:137
std::recursive_mutex RecursiveMutex
Definition: ThreadSafe.h:17
static auto Object(std::unique_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:99
#define FORCE_INLINE
Definition: Include.h:95
static auto Object(std::shared_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:93
static auto Object(const ObjectClass *object)
Definition: ThreadSafe.h:81
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:19
static auto Object(const ObjectClass &object)
Definition: ThreadSafe.h:87
static auto Unique(LockType &lockref)
Definition: ThreadSafe.h:105
std::mutex Mutex
Definition: ThreadSafe.h:16
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:92
static auto & AcessLock(const ObjectClass *object)
Definition: ThreadSafe.h:69
FORCE_INLINE void VerifyLock(Lock &lockit) const
Definition: ThreadSafe.h:151
ThreadSafeGeneric< Mutex > ThreadSafe
Simple lockable objects, no recursive locking.
Definition: ThreadSafe.h:164
#define DLLEXPORT
Definition: Include.h:84
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18
typename LockTypeResolver< MutexType >::LType LockT
Definition: ThreadSafe.h:139
static auto & AcessLock(const ObjectClass &object)
Definition: ThreadSafe.h:75