-
Notifications
You must be signed in to change notification settings - Fork 519
/
Mutex.h
100 lines (83 loc) · 1.96 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2011 Viewfinder. All rights reserved.
// Author: Peter Mattis.
#ifndef VIEWFINDER_MUTEX_H
#define VIEWFINDER_MUTEX_H
#import <functional>
#import <pthread.h>
#import "Logging.h"
#import "Utils.h"
#import "WallTime.h"
class Mutex {
typedef std::function<bool ()> Predicate;
public:
Mutex()
: cond_(NULL) {
pthread_mutex_init(&mu_, NULL);
}
~Mutex();
void Lock() {
pthread_mutex_lock(&mu_);
}
bool TryLock() {
return pthread_mutex_trylock(&mu_) == 0;
}
void Unlock() {
if (cond_) {
pthread_cond_broadcast(cond_);
}
pthread_mutex_unlock(&mu_);
}
void Wait(const Predicate& pred);
bool TimedWait(WallTime max_wait, const Predicate& pred);
// In debug builds, fail a CHECK if the lock is not held. This does not
// guarantee that the lock is held by the current thread, but it allows
// unittests to catch cases where the lock is not held at all.
void AssertHeld() {
#ifdef DEBUG
const int result = pthread_mutex_trylock(&mu_);
if (result == 0) {
pthread_mutex_unlock(&mu_);
DIE("mutex was not held");
}
#endif // DEBUG
}
private:
pthread_mutex_t mu_;
pthread_cond_t* cond_;
private:
// Catch the error of writing Mutex when intending MutexLock.
Mutex(Mutex*) = delete;
// Disallow "evil" constructors
Mutex(const Mutex&) = delete;
void operator=(const Mutex&) = delete;
};
class MutexLock {
public:
explicit MutexLock(Mutex *mu)
: mu_(mu) {
mu_->Lock();
}
~MutexLock() {
mu_->Unlock();
}
private:
Mutex * const mu_;
private:
// Disallow "evil" constructors
MutexLock(const MutexLock&);
void operator=(const MutexLock&);
};
// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
// #define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
class Barrier {
public:
Barrier(int n)
: count_(n) {
}
void Signal();
void Wait();
private:
Mutex mu_;
int count_;
};
#endif // VIEWFINDER_MUTEX_H