Honeycomb  0.1
Component-Model Framework
Unique.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Misc/Enum.h"
6 #include "Honey/Chrono/Clock.h"
8 
9 namespace honey
10 {
11 
12 template<class Lockable> class SharedLock;
13 
14 namespace lock
15 {
16  enum class Op
17  {
18  lock,
19  tryLock,
20  adopt,
21  defer
22  };
23 
26  template<class Lock>
27  function<void ()> lockGuard(Lock& lock) { return [&] { lock.lock(); }; }
28  template<class Lock>
29  function<void ()> unlockGuard(Lock& lock) { return [&] { lock.unlock(); }; }
30  template<class Lock>
31  function<void ()> releaseGuard(Lock& lock) { return [&] { lock.release(); }; }
33 }
34 
36 
40 template<class Lockable_>
41 class UniqueLock : mt::NoCopy
42 {
43 public:
44  typedef Lockable_ Lockable;
45 
46  UniqueLock() : _lock(nullptr), _owns(false) {}
47 
49  UniqueLock(Lockable& lock, lock::Op op = lock::Op::lock) : _lock(&lock), _owns(false)
50  {
51  switch (op)
52  {
53  case lock::Op::lock:
54  this->lock();
55  break;
56  case lock::Op::tryLock:
57  tryLock();
58  break;
59  case lock::Op::adopt:
60  _owns = true;
61  break;
62  case lock::Op::defer:
63  break;
64  }
65  }
66 
67  template<class Rep, class Period>
68  UniqueLock(Lockable& lock, Duration<Rep,Period> time) : _lock(&lock), _owns(false) { tryLock(time); }
69  template<class Clock, class Dur>
70  UniqueLock(Lockable& lock, TimePoint<Clock,Dur> time) : _lock(&lock), _owns(false) { tryLock(time); }
71 
72  UniqueLock(UniqueLock&& rhs) noexcept { operator=(move(rhs)); }
74  UniqueLock(SharedLock<Lockable>&& rhs) { operator=(move(rhs)); }
75 
77  ~UniqueLock() { if (_owns) unlock(); }
78 
80  {
81  _lock = rhs._lock; _owns = rhs._owns;
82  rhs._lock = nullptr; rhs._owns = false;
83  return *this;
84  }
85 
87  {
88  _lock = &rhs.mutex(); _owns = true;
89  _lock->unlockShared();
90  _lock->lock();
91  rhs.release();
92  return *this;
93  }
94 
95  void lock()
96  {
97  assert(_lock, "Lock has been released");
98  assert(!_owns, "Lock already held");
99  _lock->lock();
100  _owns = true;
101  }
102 
103  void unlock()
104  {
105  assert(_lock, "Lock has been released");
106  assert(_owns, "Lock not held");
107  _lock->unlock();
108  _owns = false;
109  }
110 
111  bool tryLock()
112  {
113  assert(_lock, "Lock has been released");
114  assert(!_owns, "Lock already held");
115  return _owns = _lock->tryLock();
116  }
117 
118  template<class Rep, class Period>
120  {
121  assert(_lock, "Lock has been released");
122  assert(!_owns, "Lock already held");
123  return _owns = _lock->tryLock(time);
124  }
125 
126  template<class Clock, class Dur>
128  {
129  assert(_lock, "Lock has been released");
130  assert(!_owns, "Lock already held");
131  return _owns = _lock->tryLock(time);
132  }
133 
135  bool owns() const { return _owns; }
137  explicit operator bool() const { return owns(); }
138 
140  Lockable& mutex()
141  {
142  assert(_lock, "Lock has been released");
143  return *_lock;
144  }
145 
147  Lockable& release()
148  {
149  Lockable& ret = mutex();
150  _lock = nullptr;
151  _owns = false;
152  return ret;
153  }
154 
155 private:
156  Lockable* _lock;
157  bool _owns;
158 };
159 
160 }
Lockable & mutex()
Get the referenced mutex.
Definition: Unique.h:140
A scoped lock that references any lockable. Locks on construction and unlocks on destruction.
Definition: Mutex.h:10
TimePoint represented by a duration since a clock's epoch time.
Definition: TimePoint.h:11
Lock (blocking)
bool owns() const
Check if mutex is locked by this instance.
Definition: Unique.h:135
~UniqueLock()
Unlock the mutex if we own it.
Definition: Unique.h:77
function< void()> releaseGuard(Lock &lock)
Definition: Unique.h:31
Try to lock (non-blocking)
void lock(Locks &&...locks)
Lock all lockables safely without deadlocking.
Definition: Util.h:110
UniqueLock(Lockable &lock, Duration< Rep, Period > time)
Definition: Unique.h:68
UniqueLock(Lockable &lock, TimePoint< Clock, Dur > time)
Definition: Unique.h:70
UniqueLock(UniqueLock &&rhs) noexcept
Definition: Unique.h:72
Lockable & release()
Release the mutex from further operations. The mutex will no longer be owned and its state will remai...
Definition: Unique.h:147
UniqueLock(SharedLock< Lockable > &&rhs)
Unlock shared lock (reader) and block until unique lock (writer) is acquired. The shared lock is rele...
Definition: Unique.h:74
bool tryLock(TimePoint< Clock, Dur > time)
Definition: Unique.h:127
function< void()> lockGuard(Lock &lock)
Definition: Unique.h:27
void unlock()
Definition: Unique.h:103
UniqueLock(Lockable &lock, lock::Op op=lock::Op::lock)
Construct with a reference to a mutex and an operation to perform on construction.
Definition: Unique.h:49
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
Lockable_ Lockable
Definition: Unique.h:44
Not yet locked, will lock manually.
void lock()
Definition: Unique.h:95
Duration represented by repetitions of a period. The period must be a ratio.
Definition: Duration.h:7
bool tryLock()
Definition: Unique.h:111
function< void()> unlockGuard(Lock &lock)
Definition: Unique.h:29
Op
Definition: Unique.h:16
UniqueLock & operator=(UniqueLock &&rhs)
Definition: Unique.h:79
bool tryLock(Duration< Rep, Period > time)
Definition: Unique.h:119
A scoped lock that references a shared mutex. Does a shared read lock on construction and unlocks on ...
Definition: Shared.h:15
Global Honeycomb namespace.
UniqueLock & operator=(SharedLock< Lockable > &&rhs)
Definition: Unique.h:86
Already locked.
UniqueLock()
Definition: Unique.h:46