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 <memory>
7 #include <mutex>
8 #include <type_traits>
9 
10 namespace Leviathan {
11 
12 
13 // Individual lock objects //
14 using Mutex = std::mutex;
15 using RecursiveMutex = std::recursive_mutex;
16 using Lock = std::unique_lock<std::mutex>;
17 using RecursiveLock = std::lock_guard<std::recursive_mutex>;
18 
19 template<class LockType>
21 // {
22 //
23 // using LType = void;
24 //};
25 
26 template<>
28 
29  using LType = Lock;
30 };
31 
32 template<>
34 
36 };
37 
38 
39 class Locker {
40 
41  template<typename T>
42  static T* TurnToPointer(T& obj)
43  {
44  return &obj;
45  }
46 
47  template<typename T>
48  static T* TurnToPointer(T* obj)
49  {
50  return obj;
51  }
52 
53 public:
54  template<typename ObjectClass>
55  static auto& AcessLock(const ObjectClass* object)
56  {
57  return TurnToPointer(object)->ObjectsLock;
58  }
59 
60  template<typename ObjectClass>
61  static auto& AcessLock(const ObjectClass& object)
62  {
63  return TurnToPointer(object)->ObjectsLock;
64  }
65 
66  template<typename ObjectClass>
67  static auto Object(const ObjectClass* object)
68  {
69  return Unique(TurnToPointer(object)->ObjectsLock);
70  }
71 
72  template<typename ObjectClass>
73  static auto Object(const ObjectClass& object)
74  {
75  return Unique(TurnToPointer(object)->ObjectsLock);
76  }
77 
78  template<typename ObjectClass>
79  static auto Object(std::shared_ptr<ObjectClass>& object)
80  {
81  return Unique(object->ObjectsLock);
82  }
83 
84  template<typename ObjectClass>
85  static auto Object(std::unique_ptr<ObjectClass>& object)
86  {
87  return Unique(object->ObjectsLock);
88  }
89 
90  template<class LockType>
91  static auto Unique(LockType& lockref)
92  {
93  return typename LockTypeResolver<LockType>::LType(lockref);
94  }
95 };
96 
97 #define GUARD_LOCK() \
98  typename Leviathan::LockTypeResolver< \
99  std::remove_reference_t<decltype(Leviathan::Locker::AcessLock(this))>>::LType \
100  guard(Leviathan::Locker::AcessLock(this));
101 
102 #define GUARD_LOCK_NAME(y) \
103  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
104  Leviathan::Locker::AcessLock(this))>>::LType y(Leviathan::Locker::AcessLock(this));
105 
106 #define GUARD_LOCK_OTHER(x) \
107  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
108  Leviathan::Locker::AcessLock(x))>>::LType guard(Leviathan::Locker::AcessLock(x));
109 
110 #define GUARD_LOCK_OTHER(x) \
111  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
112  Leviathan::Locker::AcessLock(x))>>::LType guard(Leviathan::Locker::AcessLock(x));
113 #define GUARD_LOCK_OTHER_NAME(x, y) \
114  typename Leviathan::LockTypeResolver<std::remove_reference_t<decltype( \
115  Leviathan::Locker::AcessLock(x))>>::LType y(Leviathan::Locker::AcessLock(x));
116 
118 #define REQUIRE_LOCKED(x) LEVIATHAN_ASSERT(x.owns_lock(), "Mutex doesn't own lock");
119 
122 template<class MutexType>
124 public:
127 
129  {
130  // Apparently there is no way to verify this...
131  // if(!guard.owns_lock(&this->ObjectsLock))
132  // throw InvalidAccess("wrong lock owner");
133  }
134 
135  FORCE_INLINE void VerifyLock(Lock& lockit) const
136  {
137  // Make sure that the lock is locked //
138  LEVIATHAN_ASSERT(lockit.owns_lock(), "lock not locked");
139  }
140 
144  mutable MutexType ObjectsLock;
145 };
146 
149 
154 
155 } // namespace Leviathan
156 
157 #ifdef LEAK_INTO_GLOBAL
158 using Leviathan::Lock;
159 using Leviathan::Mutex;
162 
164 #endif // LEAK_INTO_GLOBAL
FORCE_INLINE void VerifyLock(RecursiveLock &guard) const
Definition: ThreadSafe.h:128
Allows the inherited object to be locked.
Definition: ThreadSafe.h:123
std::recursive_mutex RecursiveMutex
Definition: ThreadSafe.h:15
static auto Object(std::unique_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:85
#define FORCE_INLINE
Definition: Include.h:126
static auto Object(std::shared_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:79
static auto Object(const ObjectClass *object)
Definition: ThreadSafe.h:67
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:17
static auto Object(const ObjectClass &object)
Definition: ThreadSafe.h:73
static auto Unique(LockType &lockref)
Definition: ThreadSafe.h:91
std::mutex Mutex
Definition: ThreadSafe.h:14
static auto & AcessLock(const ObjectClass *object)
Definition: ThreadSafe.h:55
FORCE_INLINE void VerifyLock(Lock &lockit) const
Definition: ThreadSafe.h:135
ThreadSafeGeneric< Mutex > ThreadSafe
Simple lockable objects, no recursive locking.
Definition: ThreadSafe.h:148
#define DLLEXPORT
Definition: Include.h:115
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:16
static auto & AcessLock(const ObjectClass &object)
Definition: ThreadSafe.h:61