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-2016 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
6 #include <memory>
7 #include <mutex>
8 
9 namespace Leviathan{
10 
11 
12 // Individual lock objects //
13 using Mutex = std::mutex;
14 using RecursiveMutex = std::recursive_mutex;
15 using Lock = std::unique_lock<std::mutex>;
16 using RecursiveLock = std::lock_guard<std::recursive_mutex>;
17 
18 template<class LockType>
20 
21  using LType = void;
22 };
23 
24 template<> struct LockTypeResolver<Mutex>{
25 
26  using LType = Lock;
27 };
28 
29 template<> struct LockTypeResolver<RecursiveMutex>{
30 
32 };
33 
34 class Locker{
35 
36  template<typename T>
37  static T* TurnToPointer(T &obj){
38  return &obj;
39  }
40 
41  template<typename T>
42  static T* TurnToPointer(T* obj){
43  return obj;
44  }
45 
46 public:
47 
48 
49  template<typename ObjectClass>
50  static auto Object(const ObjectClass* object){
51 
52  return Unique(TurnToPointer(object)->ObjectsLock);
53  }
54 
55  template<typename ObjectClass>
56  static auto Object(const ObjectClass &object){
57 
58  return Unique(TurnToPointer(object)->ObjectsLock);
59  }
60 
61  template<typename ObjectClass>
62  static auto Object(std::shared_ptr<ObjectClass> &object){
63 
64  return Unique(object->ObjectsLock);
65  }
66 
67  template<typename ObjectClass>
68  static auto Object(std::unique_ptr<ObjectClass> &object){
69 
70  return Unique(object->ObjectsLock);
71  }
72 
73  template<class LockType>
74  static auto Unique(LockType &lockref){
75 
76  return typename LockTypeResolver<LockType>::LType(lockref);
77  }
78 };
79 
80 #if 0
81 // These prevent copy elision
82 #define GUARD_LOCK() auto guard = std::move(Leviathan::Locker::Object(this));
83 
84 #define GUARD_LOCK_OTHER(x) auto guard = std::move(Leviathan::Locker::Object(x));
85 #define GUARD_LOCK_NAME(y) auto y = std::move(Leviathan::Locker::Object(this));
86 #define GUARD_LOCK_OTHER_NAME(x,y) auto y = std::move(Leviathan::Locker::Object(x));
87 
88 #define UNIQUE_LOCK_OBJECT_OTHER(x) auto lockit = std::move(Leviathan::Locker::Object(x));
89 #define UNIQUE_LOCK_THIS() auto lockit = std::move(Leviathan::Locker::Object(this));
90 #else
91 #define GUARD_LOCK() auto guard = (Leviathan::Locker::Object(this));
92 
93 #define GUARD_LOCK_OTHER(x) auto guard = (Leviathan::Locker::Object(x));
94 #define GUARD_LOCK_NAME(y) auto y = (Leviathan::Locker::Object(this));
95 #define GUARD_LOCK_OTHER_NAME(x,y) auto y = (Leviathan::Locker::Object(x));
96 
97 #define UNIQUE_LOCK_OBJECT_OTHER(x) auto lockit = (Leviathan::Locker::Object(x));
98 #define UNIQUE_LOCK_THIS() auto lockit = (Leviathan::Locker::Object(this));
99 #endif
100 
102 #define REQUIRE_LOCKED(x) LEVIATHAN_ASSERT(x.owns_lock(), "Mutex doesn't own lock");
103 
106 template<class MutexType>
108 public:
111 
113  // Apparently there is no way to verify this...
114  // if(!guard.owns_lock(&this->ObjectsLock))
115  // throw InvalidAccess("wrong lock owner");
116  }
117 
118  FORCE_INLINE void VerifyLock(Lock &lockit) const{
119 
120  // Make sure that the lock is locked //
121  LEVIATHAN_ASSERT(lockit.owns_lock(), "lock not locked");
122  }
123 
127  mutable MutexType ObjectsLock;
128 };
129 
132 
137 
138 
139 }
140 
141 #ifdef LEAK_INTO_GLOBAL
142 using Leviathan::Mutex;
144 using Leviathan::Lock;
146 
148 #endif // LEAK_INTO_GLOBAL
149 
FORCE_INLINE void VerifyLock(RecursiveLock &guard) const
Definition: ThreadSafe.h:112
Allows the inherited object to be locked.
Definition: ThreadSafe.h:107
std::recursive_mutex RecursiveMutex
Definition: ThreadSafe.h:14
static auto Object(std::unique_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:68
#define FORCE_INLINE
Definition: Include.h:129
static auto Object(std::shared_ptr< ObjectClass > &object)
Definition: ThreadSafe.h:62
static auto Object(const ObjectClass *object)
Definition: ThreadSafe.h:50
std::lock_guard< std::recursive_mutex > RecursiveLock
Definition: ThreadSafe.h:16
static auto Object(const ObjectClass &object)
Definition: ThreadSafe.h:56
static auto Unique(LockType &lockref)
Definition: ThreadSafe.h:74
std::mutex Mutex
Definition: ThreadSafe.h:13
FORCE_INLINE void VerifyLock(Lock &lockit) const
Definition: ThreadSafe.h:118
ThreadSafeGeneric< Mutex > ThreadSafe
Simple lockable objects, no recursive locking.
Definition: ThreadSafe.h:131
#define DLLEXPORT
Definition: Include.h:118
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:15