Open Lighting Architecture  0.9.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FuturePrivate.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * FuturePrivate.h
17  * An experimental implementation of Futures.
18  * Copyright (C) 2010 Simon Newton
19  */
20 
21 #ifndef INCLUDE_OLA_THREAD_FUTUREPRIVATE_H_
22 #define INCLUDE_OLA_THREAD_FUTUREPRIVATE_H_
23 
24 #include <ola/Logging.h>
25 #include <ola/base/Macro.h>
26 #include <ola/thread/Mutex.h>
27 
28 namespace ola {
29 namespace thread {
30 
31 template <typename T>
32 class FutureImpl {
33  public:
34  FutureImpl()
35  : m_ref_count(1),
36  m_is_set(false),
37  m_value() {
38  }
39 
40  void Ref() {
41  {
42  MutexLocker l(&m_mutex);
43  m_ref_count++;
44  }
45  }
46 
47  void DeRef() {
48  unsigned int ref_count = 0;
49  {
50  MutexLocker l(&m_mutex);
51  ref_count = --m_ref_count;
52  }
53  if (ref_count == 0) {
54  delete this;
55  }
56  }
57 
58  bool IsComplete() const {
59  MutexLocker l(&m_mutex);
60  return m_is_set;
61  }
62 
63  const T& Get() const {
64  MutexLocker l(&m_mutex);
65  if (m_is_set) {
66  return m_value;
67  }
68  m_condition.Wait(&m_mutex);
69  return m_value;
70  }
71 
72  void Set(const T &t) {
73  {
74  MutexLocker l(&m_mutex);
75  if (m_is_set) {
76  OLA_FATAL << "Double call to FutureImpl::Set()";
77  return;
78  }
79  m_is_set = true;
80  m_value = t;
81  }
82  m_condition.Broadcast();
83  }
84 
85  private:
86  mutable Mutex m_mutex;
87  mutable ConditionVariable m_condition;
88  unsigned int m_ref_count;
89  bool m_is_set;
90  T m_value;
91 
92  DISALLOW_COPY_AND_ASSIGN(FutureImpl<T>);
93 };
94 
98 template <>
99 class FutureImpl<void> {
100  public:
101  FutureImpl()
102  : m_ref_count(1),
103  m_is_set(false) {
104  }
105 
106  void Ref() {
107  {
108  MutexLocker l(&m_mutex);
109  m_ref_count++;
110  }
111  }
112 
113  void DeRef() {
114  unsigned int ref_count = 0;
115  {
116  MutexLocker l(&m_mutex);
117  ref_count = --m_ref_count;
118  }
119  if (ref_count == 0) {
120  delete this;
121  }
122  }
123 
124  bool IsComplete() const {
125  MutexLocker l(&m_mutex);
126  return m_is_set;
127  }
128 
129  void Get() const {
130  MutexLocker l(&m_mutex);
131  if (m_is_set) {
132  return;
133  }
134  m_condition.Wait(&m_mutex);
135  }
136 
137  void Set() {
138  {
139  MutexLocker l(&m_mutex);
140  if (m_is_set) {
141  OLA_FATAL << "Double call to FutureImpl::Set()";
142  return;
143  }
144  m_is_set = true;
145  }
146  m_condition.Broadcast();
147  }
148 
149  private:
150  mutable Mutex m_mutex;
151  mutable ConditionVariable m_condition;
152  unsigned int m_ref_count;
153  bool m_is_set;
154 
155  DISALLOW_COPY_AND_ASSIGN(FutureImpl<void>);
156 };
157 
158 } // namespace thread
159 } // namespace ola
160 #endif // INCLUDE_OLA_THREAD_FUTUREPRIVATE_H_