OnixS C++ CBOE CFE Binary Order Entry (BOE) Handler  1.11.0
API documentation
Future.h
Go to the documentation of this file.
1 /*
2 * Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3 *
4 * This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5 * and international copyright treaties.
6 *
7 * Access to and use of the software is governed by the terms of the applicable OnixS Software
8 * Services Agreement (the Agreement) and Customer end user license agreements granting
9 * a non-assignable, non-transferable and non-exclusive license to use the software
10 * for it's own data processing purposes under the terms defined in the Agreement.
11 *
12 * Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13 * of this source code or associated reference material to any other location for further reproduction
14 * or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15 *
16 * Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17 * the terms of the Agreement is a violation of copyright law.
18 */
19 #pragma once
20 
22 
23 #ifdef ONIXS_BATS_BOE_CXX11
24 # include <utility>
25 # include <exception>
26 #endif
27 
28 namespace OnixS {
29 namespace System {
30  class FutureSharedState;
31 }}
32 
33 namespace OnixS {
34 namespace CboeCFE {
35 namespace Trading {
36 namespace BOE {
37 namespace Threading
38 {
39 
40 /// State of a \c SharedFuture object (similar to std::future_status, @see http://en.cppreference.com/w/cpp/thread/future_status ).
42 {
43  enum Enum
44  {
45  /// the shared state is ready.
47  /// the shared state did not become ready before specified timeout duration has passed.
49  /// the shared state contains a deferred function, so the result will be computed only when explicitly requested.
50  deferred
51  };
52 };
53 
54 namespace Implementation {
55 
56 class FutureHelper;
57 
58 /// Base implementation of SharedFuture<T>.
60 {
61 public:
62  /// Check if a future instance is associated with an asynchronous result.
63  ///
64  /// Returns \c true if the *this has an associated asynchronous result, false otherwise.
65  bool valid() const ONIXS_BATS_BOE_NOEXCEPT
66  {
67  return state_ != ONIXS_BATS_BOE_NULLPTR;
68  }
69 
70  /// Returns \c true if the asynchronous result associated with this Future is ready
71  /// (has a value or exception stored in the shared state), \c false otherwise.
72  ///
73  /// There are often situations where a \c get() call on a Future may not be a blocking call,
74  /// or is only a blocking call under certain circumstances.
75  /// This method gives the ability to test for early completion and allows us to avoid
76  /// associating a continuation, which needs to be scheduled with some non-trivial overhead
77  /// and near-certain loss of cache efficiency.
78  ///
79  /// @throw std::logic_error if this instance does not refer to a shared state.
80  ONIXS_CBOE_CFE_BOE_API bool is_ready() const;
81 
82  /// Returns \c true if the asynchronous result associated with this Future has a stored value,
83  /// \c false otherwise.
84  ///
85  /// @throw std::logic_error if this instance does not refer to a shared state.
86  ONIXS_CBOE_CFE_BOE_API bool has_value() const;
87 
88  /// Returns \c true if the asynchronous result associated with this Future has a stored exception,
89  /// \c false otherwise.
90  ///
91  /// @throw std::logic_error if this instance does not refer to a shared state.
92  ONIXS_CBOE_CFE_BOE_API bool has_exception() const;
93 
94  enum
95  {
96  InfiniteTimeout = -1
97  };
98 
99  /// Waits for the result to become available during the timeout.
100  ///
101  /// \note Calling \c wait on the same Future from multiple threads is \e not safe;
102  /// the intended use is for each thread that waits on the same shared state to have a \e copy of a Future.
103  ///
104  /// \throw std::logic_error if this instance does not refer to a shared state.
105  ONIXS_CBOE_CFE_BOE_API FutureStatus::Enum wait(int timeoutInMs) const;
106 
107 protected:
109  : state_()
110  {}
111 
112  ONIXS_CBOE_CFE_BOE_API FutureBase(const FutureBase &other) ONIXS_BATS_BOE_NOEXCEPT;
113 
114  ONIXS_CBOE_CFE_BOE_API FutureBase &operator=(const FutureBase &other) ONIXS_BATS_BOE_NOEXCEPT;
115 
116 #ifdef ONIXS_BATS_BOE_CXX11
117 
118  ONIXS_CBOE_CFE_BOE_API FutureBase(FutureBase &&other) ONIXS_BATS_BOE_NOEXCEPT;
119 
120  ONIXS_CBOE_CFE_BOE_API FutureBase &operator=(FutureBase &&other) ONIXS_BATS_BOE_NOEXCEPT;
121 
122 #endif
123 
125  {};
126 
127  /// Initializes the instance with shared state.
128  ONIXS_CBOE_CFE_BOE_API FutureBase(const System::FutureSharedState *state) ONIXS_BATS_BOE_NOEXCEPT;
129 
130  /// Initializes the instance with shared state.
131  ONIXS_CBOE_CFE_BOE_API FutureBase(const System::FutureSharedState *state, moving_init_t) ONIXS_BATS_BOE_NOEXCEPT;
132 
133  /// Destroys a future object.
134  ///
135  /// If this is the last reference to the asynchronous result associated with *this (if any), then destroy that asynchronous result.
136  ONIXS_CBOE_CFE_BOE_API ~FutureBase() ONIXS_BATS_BOE_NOEXCEPT;
137 
138  ONIXS_CBOE_CFE_BOE_API void swap(FutureBase &other) ONIXS_BATS_BOE_NOEXCEPT;
139 
140  ONIXS_CBOE_CFE_BOE_API const void *getValuePtr() const;
141 
142  ONIXS_CBOE_CFE_BOE_API void getVoid() const;
143 
144 private:
145  const System::FutureSharedState *state_;
146 
147  friend class FutureHelper;
148 };
149 
150 template <typename T>
152 {
153  typedef const T &Type;
154 };
155 
156 template <>
157 struct FutureGetReturn<void>
158 {
159  typedef void Type;
160 };
161 
162 }
163 
164 /// Represents a future result of an asynchronous operation - a result that will eventually appear in the Future after
165 /// the processing is complete.
166 ///
167 /// The class template Future provides a mechanism to access the result of \e asynchronous operations :
168 /// \li An asynchronous operation (e.g. created via Promise) can provide a Future object to the creator of that asynchronous
169 /// operation (e.g. via Promise::get_future).
170 /// \li The creator of the asynchronous operation can then use a variety of methods to query, wait for, or extract a value from Future.
171 /// These methods may block if the asynchronous operation has not yet provided a value.
172 /// \li When the asynchronous operation is ready to send a result to the creator, it can do so by modifying <em> shared state </em>
173 /// (e.g. via Promise::set_value) that is linked to the creator's Future.
174 ///
175 /// Future is the synchronization object constructed around the \e receiving end of the Promise channel. It allows for the separation
176 /// of the initiation of an operation and the act of waiting for its result.
177 ///
178 /// Future is \e copiable and multiple SharedFuture objects may refer to the same shared state.
179 ///
180 /// Unlike std::future, this implementation has an extended API, allowing you to query the state of SharedFuture.
181 /// The internal implementation is lock-free; therefore, setting and polling states do not lead to blocking of threads and/or switching
182 /// of an execution context.
183 ///
184 /// \note Access to the same shared state from multiple threads is safe if each thread does it through its own copy of
185 /// a SharedFuture object.
186 ///
187 /// \see http://en.cppreference.com/w/cpp/thread/shared_future .
188 template <typename T>
190 {
191 public:
192  SharedFuture() ONIXS_BATS_BOE_NOEXCEPT
193  : FutureBase() {}
194 
195  /// Copy constructor.
196  SharedFuture(const SharedFuture<T> &other) ONIXS_BATS_BOE_NOEXCEPT
197  : FutureBase(other) {}
198 
199  /// Copy assignment.
200  SharedFuture<T> &operator=(const SharedFuture<T> &other) ONIXS_BATS_BOE_NOEXCEPT
201  {
202  FutureBase::operator=(other);
203  return *this;
204  }
205 
206 #ifdef ONIXS_BATS_BOE_CXX11
207 
208  SharedFuture(SharedFuture<T> &&other) ONIXS_BATS_BOE_NOEXCEPT
209  : FutureBase(std::move(other))
210  {}
211 
212  FutureBase &operator=(SharedFuture<T> &&other) ONIXS_BATS_BOE_NOEXCEPT
213  {
214  FutureBase::operator=(std::move(other));
215  return *this;
216  }
217 
218 #endif
219 
220  /// Returns the result. If the result is not ready, the method will block. When completes, it either returns a value or throws an exception.
221  ///
222  /// This method waits until the Future has a valid result and retrieves it. It effectively calls wait() in order to wait for the result.
223  ///
224  /// \exception If an exception was stored in the shared state referenced by this Future (e.g. via a call to Promise::set_exception()) then that exception will be thrown.
226  {
227  return *reinterpret_cast<const T *>(getValuePtr());
228  }
229 
230  /// swaps two SharedFuture objects
231  void swap(SharedFuture<T> &other) ONIXS_BATS_BOE_NOEXCEPT
232  {
233  FutureBase::swap(other);
234  }
235 
236 private:
237  /// Initializes the instance with shared state.
238  SharedFuture(const System::FutureSharedState *state)
239  : FutureBase(state)
240  {}
241 
242  /// Initializes the instance with shared state.
243  SharedFuture(const System::FutureSharedState *state, moving_init_t t) ONIXS_BATS_BOE_NOEXCEPT
244  : FutureBase(state, t) {}
245 
246  friend class Implementation::FutureHelper;
247 };
248 
249 template <>
250 inline void SharedFuture<void>::get() const
251 {
252  getVoid();
253 }
254 
255 }}}}}
the shared state did not become ready before specified timeout duration has passed.
Definition: Future.h:48
SharedFuture(const SharedFuture< T > &other) ONIXS_BATS_BOE_NOEXCEPT
Copy constructor.
Definition: Future.h:196
Base implementation of SharedFuture<T>.
Definition: Future.h:59
State of a SharedFuture object (similar to std::future_status,.
Definition: Future.h:41
SharedFuture< T > & operator=(const SharedFuture< T > &other) ONIXS_BATS_BOE_NOEXCEPT
Copy assignment.
Definition: Future.h:200
void swap(SharedFuture< T > &other) ONIXS_BATS_BOE_NOEXCEPT
swaps two SharedFuture objects
Definition: Future.h:231