OnixS C++ CME iLink 3 Binary Order Entry Handler  1.18.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 
20 #pragma once
21 
22 #include <OnixS/CME/iLink3/ABI.h>
23 
24 #if defined (ONIXS_ILINK3_CXX11)
25 # include <exception>
26 #endif
27 
28 namespace OnixS {
29 
30 namespace System {
31 class FutureSharedState;
32 }
33 
34 namespace CME {
35 namespace iLink3 {
36 namespace Threading {
37 
38 /// State of a \c SharedFuture object (similar to std::future_status, @see http://en.cppreference.com/w/cpp/thread/future_status ).
40 {
41  enum Enum
42  {
43  /// the shared state is ready.
45  /// the shared state did not become ready before specified timeout duration has passed.
47  /// the shared state contains a deferred function, so the result will be computed only when explicitly requested.
48  deferred
49  };
50 };
51 
52 namespace Implementation {
53 
54 class FutureHelper;
55 
56 /// Base implementation of SharedFuture<T>.
58 {
59 public:
60  /// Check if a future instance is associated with an asynchronous result.
61  ///
62  /// Returns \c true if the *this has an associated asynchronous result, false otherwise.
63  bool valid() const ONIXS_ILINK3_NOTHROW {
64  return state_ != ONIXS_ILINK3_NULLPTR;
65  }
66 
67  /// Returns \c true if the asynchronous result associated with this Future is ready
68  /// (has a value or exception stored in the shared state), \c false otherwise.
69  ///
70  /// There are often situations where a \c get() call on a Future may not be a blocking call,
71  /// or is only a blocking call under certain circumstances.
72  /// This method gives the ability to test for early completion and allows us to avoid
73  /// associating a continuation, which needs to be scheduled with some non-trivial overhead
74  /// and near-certain loss of cache efficiency.
75  ///
76  /// @throw std::logic_error if this instance does not refer to a shared state.
77  ONIXS_ILINK3_EXPORTED bool is_ready() const;
78 
79  /// Returns \c true if the asynchronous result associated with this Future has a stored value,
80  /// \c false otherwise.
81  ///
82  /// @throw std::logic_error if this instance does not refer to a shared state.
83  ONIXS_ILINK3_EXPORTED bool has_value() const;
84 
85  /// Returns \c true if the asynchronous result associated with this Future has a stored exception,
86  /// \c false otherwise.
87  ///
88  /// @throw std::logic_error if this instance does not refer to a shared state.
89  ONIXS_ILINK3_EXPORTED bool has_exception() const;
90 
91 #if defined (ONIXS_ILINK3_CXX11)
92 
93  /// Returns the stored exception.
94  ///
95  /// @throw std::logic_error if this instance does not refer to a shared state.
96  /// @throw std::logic_error if the operation has *not* finished with an error.
97  ONIXS_ILINK3_EXPORTED std::exception_ptr get_exception_ptr() const;
98 
99 #endif
100 
101  enum { InfiniteTimeout = -1 };
102 
103  /// Waits for the result to become available during the timeout.
104  ///
105  /// \note Calling \c wait on the same Future from multiple threads is \e not safe;
106  /// the intended use is for each thread that waits on the same shared state to have a \e copy of a Future.
107  ///
108  /// \throw std::logic_error if this instance does not refer to a shared state.
109  ONIXS_ILINK3_EXPORTED FutureStatus::Enum wait(int timeoutInMs) const;
110 
111 protected:
113  : state_() {}
114 
116 
118 
119 #if defined (ONIXS_ILINK3_CXX11)
120 
122 
124 
125 #endif
126 
127  struct moving_init_t {};
128 
129  /// Initializes the instance with shared state.
130  ONIXS_ILINK3_EXPORTED FutureBase(const System::FutureSharedState * state) ONIXS_ILINK3_NOTHROW;
131 
132  /// Initializes the instance with shared state.
133  ONIXS_ILINK3_EXPORTED FutureBase(const System::FutureSharedState * state, moving_init_t) ONIXS_ILINK3_NOTHROW;
134 
135  /// Destroys a future object.
136  ///
137  /// If this is the last reference to the asynchronous result associated with *this (if any), then destroy that asynchronous result.
139 
141 
142  ONIXS_ILINK3_EXPORTED const void * getValuePtr() const;
143 
144  ONIXS_ILINK3_EXPORTED void getVoid() const;
145 
146 private:
147  const System::FutureSharedState * state_;
148 
149  friend class FutureHelper;
150 };
151 
152 template<typename T>
154  typedef const T & Type;
155 };
156 
157 template<>
158 struct FutureGetReturn<void> {
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:
193  : FutureBase() {}
194 
195  /// Copy constructor.
197  : FutureBase(other) {}
198 
199  /// Copy assignment.
201  FutureBase::operator=(other);
202  return *this;
203  }
204 
205 #if defined (ONIXS_ILINK3_CXX11)
206 
208  : FutureBase(std::move(other)) {}
209 
211  FutureBase::operator=(std::move(other));
212  return *this;
213  }
214 
215 #endif
216 
217  /// Returns the result. If the result is not ready, the method will block. When completes, it either returns a value or throws an exception.
218  ///
219  /// This method waits until the Future has a valid result and retrieves it. It effectively calls wait() in order to wait for the result.
220  ///
221  /// \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.
223  return *reinterpret_cast<const T *>(getValuePtr());
224  }
225 
226  /// swaps two SharedFuture objects
228  FutureBase::swap(other);
229  }
230 
231 private:
232  /// Initializes the instance with shared state.
233  SharedFuture(const System::FutureSharedState * state)
234  : FutureBase(state) {}
235 
236  /// Initializes the instance with shared state.
237  SharedFuture(const System::FutureSharedState * state, moving_init_t t) ONIXS_ILINK3_NOTHROW
238  : FutureBase(state, t) {}
239 
240  friend class Implementation::FutureHelper;
241 };
242 
243 template<>
244 inline void SharedFuture<void>::get() const {
245  getVoid();
246 }
247 
248 }
249 }
250 }
251 }
#define ONIXS_ILINK3_NULLPTR
Definition: Compiler.h:182
FutureBase & operator=(SharedFuture< T > &&other) noexcept
Definition: Future.h:210
the shared state did not become ready before specified timeout duration has passed.
Definition: Future.h:46
STL namespace.
SharedFuture(SharedFuture< T > &&other) noexcept
Definition: Future.h:207
SharedFuture< T > & operator=(const SharedFuture< T > &other) noexcept
Copy assignment.
Definition: Future.h:200
Definition: Defines.h:40
void swap(SharedFuture< T > &other) noexcept
swaps two SharedFuture objects
Definition: Future.h:227
bool valid() const noexcept
Check if a future instance is associated with an asynchronous result.
Definition: Future.h:63
Represents a future result of an asynchronous operation - a result that will eventually appear in the...
Definition: Future.h:189
#define ONIXS_ILINK3_EXPORTED
Definition: Compiler.h:175
SharedFuture(const SharedFuture< T > &other) noexcept
Copy constructor.
Definition: Future.h:196
Base implementation of SharedFuture<T>.
Definition: Future.h:57
State of a SharedFuture object (similar to std::future_status,.
Definition: Future.h:39
#define ONIXS_ILINK3_NOTHROW
Definition: Compiler.h:176