QuantumLibrary
quantum_promise_impl.h
1 /*
2 ** Copyright 2018 Bloomberg Finance L.P.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 //NOTE: DO NOT INCLUDE DIRECTLY
17 
18 //##############################################################################################
19 //#################################### IMPLEMENTATIONS #########################################
20 //##############################################################################################
21 #include <quantum/quantum_allocator.h>
22 
23 namespace Bloomberg {
24 namespace quantum {
25 
26 //==============================================================================================
27 // class IThreadPromise
28 //==============================================================================================
29 template <template<class> class PROMISE, class T>
30 template <class V, class>
32 {
33  return static_cast<Impl*>(this)->set(std::forward<V>(value));
34 }
35 
36 template <template<class> class PROMISE, class T>
37 template <class V, class>
39 {
40  static_cast<Impl*>(this)->push(std::forward<V>(value));
41 }
42 
43 template <template<class> class PROMISE, class T>
44 template <class V, class>
46 {
47  return static_cast<Impl*>(this)->closeBuffer();
48 }
49 
50 //==============================================================================================
51 // class ICoroPromise
52 //==============================================================================================
53 template <template<class> class PROMISE, class T>
54 template <class V, class>
56 {
57  return static_cast<Impl*>(this)->set(sync, std::forward<V>(value));
58 }
59 
60 template <template<class> class PROMISE, class T>
61 template <class V, class>
63 {
64  static_cast<Impl*>(this)->push(sync, std::forward<V>(value));
65 }
66 
67 template <template<class> class PROMISE, class T>
68 template <class V, class>
70 {
71  return static_cast<Impl*>(this)->closeBuffer();
72 }
73 
74 //==============================================================================================
75 // class Promise
76 //==============================================================================================
77 #ifndef __QUANTUM_PROMISE_ALLOC_SIZE
78  #define __QUANTUM_PROMISE_ALLOC_SIZE __QUANTUM_DEFAULT_POOL_ALLOC_SIZE
79 #endif
80 #ifndef __QUANTUM_USE_DEFAULT_ALLOCATOR
81  #ifdef __QUANTUM_ALLOCATE_POOL_FROM_HEAP
83  #else
84  using PromiseAllocator = StackAllocator<Promise<int>, __QUANTUM_PROMISE_ALLOC_SIZE>;
85  #endif
86 #else
88 #endif
89 
90 template <class T>
92  IThreadPromise<Promise, T>(this),
93  ICoroPromise<Promise, T>(this),
94  _sharedState(new SharedState<T>()),
95  _terminated ATOMIC_FLAG_INIT
96 {}
97 
98 template <class T>
100 {
101  terminate();
102 }
103 
104 template <class T>
106 {
107  if (!_terminated.test_and_set())
108  {
109  if (_sharedState) _sharedState->breakPromise();
110  }
111 }
112 
113 template <class T>
114 bool Promise<T>::valid() const
115 {
116  return _sharedState != nullptr;
117 }
118 
119 template <class T>
120 int Promise<T>::setException(std::exception_ptr ex)
121 {
122  if (!_sharedState) ThrowFutureException(FutureState::NoState);
123  return _sharedState->setException(ex);
124 }
125 
126 template <class T>
128 {
129  if (!_sharedState) ThrowFutureException(FutureState::NoState);
130  return FuturePtr<T>(new Future<T>(_sharedState), Future<T>::deleter);
131 }
132 
133 template <class T>
135 {
136  if (!_sharedState) ThrowFutureException(FutureState::NoState);
137  return FuturePtr<T>(new Future<T>(_sharedState), Future<T>::deleter);
138 }
139 
140 template <class T>
141 template <class V, class>
142 int Promise<T>::set(V&& value)
143 {
144  if (!_sharedState) ThrowFutureException(FutureState::NoState);
145  return _sharedState->set(std::forward<V>(value));
146 }
147 
148 template <class T>
150 {
151  if (!_sharedState) ThrowFutureException(FutureState::NoState);
152  return FuturePtr<T>(new Future<T>(_sharedState), Future<T>::deleter);
153 }
154 
155 template <class T>
156 template <class V, class>
157 int Promise<T>::set(ICoroSync::Ptr sync, V&& value)
158 {
159  if (!_sharedState) ThrowFutureException(FutureState::NoState);
160  return _sharedState->set(sync, std::forward<V>(value));
161 }
162 
163 template <class T>
165 {
166  if (!_sharedState) ThrowFutureException(FutureState::NoState);
167  return FuturePtr<T>(new Future<T>(_sharedState), Future<T>::deleter);
168 }
169 
170 template <class T>
171 template <class V, class>
172 void Promise<T>::push(V&& value)
173 {
174  if (!_sharedState) ThrowFutureException(FutureState::NoState);
175  _sharedState->push(std::forward<V>(value));
176 }
177 
178 template <class T>
179 template <class V, class>
180 void Promise<T>::push(ICoroSync::Ptr sync, V&& value)
181 {
182  if (!_sharedState) ThrowFutureException(FutureState::NoState);
183  _sharedState->push(sync, std::forward<V>(value));
184 }
185 
186 template <class T>
187 template <class V, class>
189 {
190  if (!_sharedState) ThrowFutureException(FutureState::NoState);
191  return _sharedState->closeBuffer();
192 }
193 
194 template <class T>
195 void* Promise<T>::operator new(size_t)
196 {
198 }
199 
200 template <class T>
201 void Promise<T>::operator delete(void* p)
202 {
204 }
205 
206 template <class T>
208 {
209 #ifndef __QUANTUM_USE_DEFAULT_ALLOCATOR
211 #else
212  delete p;
213 #endif
214 }
215 
216 }}
static AllocType & instance(std::enable_if_t<!A::default_constructor::value, uint16_t > size)
Definition: quantum_allocator.h:56
Definition: quantum_buffer_impl.h:22
typename ICoroFuture< T >::Ptr CoroFuturePtr
Definition: quantum_icoro_future.h:72
Shared state used between a Promise and a Future to exchange values.
Definition: quantum_shared_state.h:38
Definition: quantum_allocator.h:36
void push(V &&value)
Definition: quantum_promise_impl.h:172
int set(ICoroSync::Ptr sync, V &&value)
Set the promised value.
Definition: quantum_promise_impl.h:55
ThreadFuturePtr< T > getIThreadFuture() const
Get the associated thread future.
Definition: quantum_promise_impl.h:149
int closeBuffer()
Close a promise buffer.
Definition: quantum_promise_impl.h:45
int setException(std::exception_ptr ex) final
Set an exception in this promise.
Definition: quantum_promise_impl.h:120
bool valid() const final
Determines if this promise still has a shared state with the corresponding future object.
Definition: quantum_promise_impl.h:114
int set(V &&value)
Definition: quantum_promise_impl.h:142
void push(V &&value)
Push a single value into the promise buffer.
Definition: quantum_promise_impl.h:38
std::shared_ptr< ICoroSync > Ptr
Definition: quantum_icoro_sync.h:36
static void deleter(Promise< T > *p)
Definition: quantum_promise_impl.h:207
Class representing a promised value.
Definition: quantum_icoro_promise.h:77
ICoroFutureBase::Ptr getICoroFutureBase() const final
Get a coroutine-compatible interface used to access the associated future.
Definition: quantum_promise_impl.h:134
Exposes methods to access and manipulate a non-coroutine promise (i.e. used in a thread)
Definition: quantum_ithread_promise.h:34
Provides a stack-based object pool to the underlying ContiguousPoolManager. The default buffer size i...
Definition: quantum_stack_allocator.h:34
Class representing a promised future. Can only be instantiated via a Promise object.
Definition: quantum_icoro_future.h:27
typename Future< T >::Ptr FuturePtr
Definition: quantum_future.h:91
Promise()
Definition: quantum_promise_impl.h:91
static size_type & promiseAllocSize()
Get/set if the default size for promise object pools.
Definition: quantum_allocator_traits.h:114
std::shared_ptr< ICoroFutureBase > Ptr
Definition: quantum_icoro_future_base.h:34
void ThrowFutureException(FutureState state)
Definition: quantum_future_state.h:130
std::shared_ptr< IThreadFutureBase > Ptr
Definition: quantum_ithread_future_base.h:34
void terminate() final
Terminates the object.
Definition: quantum_promise_impl.h:105
Provides a heap-based object pool to the underlying ContiguousPoolManager. The default buffer size is...
Definition: quantum_heap_allocator.h:33
typename IThreadFuture< T >::Ptr ThreadFuturePtr
Definition: quantum_ithread_future.h:69
Exposes methods to access and manipulate a coroutine-compatible promise.
Definition: quantum_icoro_promise.h:33
int closeBuffer()
Close a promise buffer.
Definition: quantum_promise_impl.h:69
int set(V &&value)
Set the promised value.
Definition: quantum_promise_impl.h:31
int closeBuffer()
Definition: quantum_promise_impl.h:188
void push(ICoroSync::Ptr sync, V &&value)
Push a single value into the promise buffer.
Definition: quantum_promise_impl.h:62
Shared state between Promise and Future is invalid.
IThreadFutureBase::Ptr getIThreadFutureBase() const final
Get a thread-compatible interface used to access the associated future.
Definition: quantum_promise_impl.h:127
CoroFuturePtr< T > getICoroFuture() const
Get the associated coroutine future.
Definition: quantum_promise_impl.h:164