forked from snakster/cpp.react
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConcurrency.h
More file actions
132 lines (105 loc) · 3.28 KB
/
Concurrency.h
File metadata and controls
132 lines (105 loc) · 3.28 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright Sebastian Jeckel 2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#include "react/detail/Defs.h"
#include <mutex>
#include <condition_variable>
/***************************************/ REACT_IMPL_BEGIN /**************************************/
class BlockingCondition
{
public:
inline void Block()
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
blocked_ = true;
}// ~mutex_
inline void Unblock()
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
blocked_ = false;
condition_.notify_all();
}// ~mutex_
inline void WaitForUnblock()
{
std::unique_lock<std::mutex> lock(mutex_);
condition_.wait(lock, [this] { return !blocked_; });
}
inline bool IsBlocked()
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
return blocked_;
}// ~mutex_
template <typename F>
auto Run(F&& func) -> decltype(func(false))
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
return func(blocked_);
}// ~mutex_
template <typename F>
bool RunIfBlocked(F&& func)
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
if (!blocked_)
return false;
func();
return true;
}// ~mutex_
template <typename F>
bool RunIfUnblocked(F&& func)
{// mutex_
std::lock_guard<std::mutex> scopedLock(mutex_);
if (blocked_)
return false;
func();
return true;
}// ~mutex_
private:
std::mutex mutex_;
std::condition_variable condition_;
bool blocked_ = false;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
/// ThreadLocalPtr
///////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
class ThreadLocalStaticPtr
{
public:
static T* Get() { return ptr_; }
static void Set(T* ptr) { ptr_ = ptr; }
static void Reset() { ptr_ = nullptr; }
static bool IsNull() { return ptr_ == nullptr; }
ThreadLocalStaticPtr() = delete;
private:
static __declspec(thread) T* ptr_;
};
template <typename T>
T* ThreadLocalStaticPtr<T>::ptr_(nullptr);
///////////////////////////////////////////////////////////////////////////////////////////////////
/// ConditionalCriticalSection
///////////////////////////////////////////////////////////////////////////////////////////////////
template <typename TMutex, bool is_enabled>
class ConditionalCriticalSection;
template <typename TMutex>
class ConditionalCriticalSection<TMutex,false>
{
public:
template <typename F>
void Access(const F& f) { f(); }
};
template <typename TMutex>
class ConditionalCriticalSection<TMutex,true>
{
public:
template <typename F>
void Access(const F& f)
{// mutex_
std::lock_guard<TMutex> lock(mutex_);
f();
}// ~mutex_
private:
TMutex mutex_;
};
/****************************************/ REACT_IMPL_END /***************************************/