-
Notifications
You must be signed in to change notification settings - Fork 0
/
mutex.h
84 lines (67 loc) · 1.78 KB
/
mutex.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef MUTEX_H_
#define MUTEX_H_
#include <condition_variable>
#include <functional>
#include <shared_mutex>
#include "thread_safety.h"
/*
Mutex mu;
bool done = false GUARDED_BY(mu);
int returnvalue GUARDED_BY(mu);
auto fn = [&mu, &done, &returnvalue]()
{
auto myval = some_function();
MutexLock l(&mu);
done = true;
returnvalue = myval;
};
_executor->execute(std::move(fn));
ReaderMutexLock l(&mu);
mu.await(&done);
// Now returnvalue can be used safely
*/
class CAPABILITY("mutex") Mutex {
public:
Mutex() = default;
~Mutex() = default;
Mutex(Mutex&) = delete;
Mutex operator=(Mutex&) = delete;
void lock() ACQUIRE() { _mu.lock(); }
void unlock() RELEASE() {
_mu.unlock();
_cv.notify_all();
}
void readerLock() ACQUIRE_SHARED() { _mu.lock_shared(); }
void readerUnlock() RELEASE_SHARED() { _mu.unlock_shared(); }
void await(std::function<bool()> cond_) ASSERT_SHARED_CAPABILITY(this) {
struct Locker {
explicit Locker(Mutex* mu_) : _mu(mu_) {}
void lock() ACQUIRE_SHARED(_mu) { _mu->readerLock(); }
void unlock() RELEASE_SHARED(_mu) { _mu->readerUnlock(); }
Mutex* _mu;
};
Locker l(this);
_cv.wait(l, cond_);
}
void await(bool* cond_) ASSERT_SHARED_CAPABILITY(this) {
return await([cond_]() { return *cond_; });
}
private:
std::shared_mutex _mu;
std::condition_variable_any _cv;
};
class SCOPED_CAPABILITY MutexLock {
public:
MutexLock(Mutex* mu) ACQUIRE(mu) : _mu(mu) { _mu->lock(); }
~MutexLock() RELEASE(_mu) { _mu->unlock(); }
private:
Mutex* _mu;
};
class SCOPED_CAPABILITY ReaderMutexLock {
public:
ReaderMutexLock(Mutex* mu) ACQUIRE_SHARED(mu) : _mu(mu) { _mu->readerLock(); }
~ReaderMutexLock() RELEASE_SHARED(_mu) { _mu->readerUnlock(); }
private:
Mutex* _mu;
};
#endif // MUTEX_H_