Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Future.h
blob453652426df6d87e13cae27c20170ca504242853
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Future.h
7 * @author Andres Kruse <Andres.Kruse@cern.ch>
8 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
9 * @author Per Andersson <Per.Andersson@hfera.ericsson.se> and
10 * @author John Tucker <johnny_tucker@yahoo.com>
12 //=============================================================================
14 #ifndef ACE_FUTURE_H
15 #define ACE_FUTURE_H
17 #include /**/ "ace/pre.h"
19 #include <atomic>
20 #include "ace/Unbounded_Set.h"
21 #include "ace/Strategies_T.h"
23 #if !defined (ACE_LACKS_PRAGMA_ONCE)
24 # pragma once
25 #endif /* ACE_LACKS_PRAGMA_ONCE */
27 #if defined (ACE_HAS_THREADS)
29 #include "ace/Synch_Traits.h"
30 #include "ace/Recursive_Thread_Mutex.h"
31 #include "ace/Condition_Recursive_Thread_Mutex.h"
33 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
35 // Forward decl.
36 template <class T> class ACE_Future_Holder;
37 template <class T> class ACE_Future_Observer;
38 template <class T> class ACE_Future_Rep;
39 template <class T> class ACE_Future;
41 /**
42 * @class ACE_Future_Holder
44 * @brief Implementation of object that holds an ACE_Future.
46 template <class T>
47 class ACE_Future_Holder
49 public:
50 ACE_Future_Holder (const ACE_Future<T> &future);
51 ~ACE_Future_Holder () = default;
52 ACE_Future_Holder () = delete;
54 /// Declare the dynamic allocation hooks.
55 ACE_ALLOC_HOOK_DECLARE;
57 ACE_Future<T> item_;
60 /**
61 * @class ACE_Future_Observer
63 * @brief ACE_Future_Observer<T>
65 * An ACE_Future_Observer object implements an object that is
66 * subscribed with an ACE_Future object so that it may be notified
67 * when the value of the ACE_Future object is written to by a writer
68 * thread. It uses the Observer pattern.
70 template <class T>
71 class ACE_Future_Observer
73 public:
74 /// Destructor
75 virtual ~ACE_Future_Observer () = default;
77 /// Called by the ACE_Future in which we are subscribed to when
78 /// its value is written to.
79 virtual void update (const ACE_Future<T> &future) = 0;
81 /// Declare the dynamic allocation hooks.
82 ACE_ALLOC_HOOK_DECLARE;
84 protected:
85 /// Constructor
86 ACE_Future_Observer () = default;
89 /**
90 * @class ACE_Future_Rep
92 * @internal
94 * @brief ACE_Future_Rep<T>
96 * An ACE_Future_Rep<T> object encapsulates a pointer to an object
97 * of class T which is the result of an asynchronous method
98 * invocation. It is pointed to by ACE_Future<T> object[s] and
99 * only accessible through them.
101 template <class T>
102 class ACE_Future_Rep
104 private:
105 friend class ACE_Future<T>;
108 * Set the result value. The specified @a caller represents the
109 * future that invoked this <set> method, which is used to notify
110 * the list of future observers. Returns 0 for success, -1 on error.
111 * This function only has an effect the first time it is called for
112 * the object. Subsequent calls return 0 (success) but have no effect.
114 int set (const T &r,
115 ACE_Future<T> &caller);
117 /// Wait up to @a tv time to get the @a value. Note that @a tv must be
118 /// specified in absolute time rather than relative time.
119 int get (T &value,
120 ACE_Time_Value *tv) const;
123 * Attaches the specified observer to a subject (i.e., the ACE_Future_Rep).
124 * The update method of the specified subject will be invoked with a copy of
125 * the written-to ACE_Future as input when the result gets set.
127 * Returns 0 if the observer is successfully attached, 1 if the
128 * observer is already attached, and -1 if failures occur.
130 int attach (ACE_Future_Observer<T> *observer,
131 ACE_Future<T> &caller);
134 * Detaches the specified observer from a subject (i.e., the ACE_Future_Rep).
135 * The update method of the specified subject will not be invoked when the
136 * ACE_Future_Reps result gets set. Returns 1 if the specified observer was
137 * actually attached to the subject prior to this call and 0 if was not.
139 * Returns 0 if the observer was successfully detached, and -1 if the
140 * observer was not attached in the first place.
142 int detach (ACE_Future_Observer<T> *observer);
145 * Type conversion. will block forever until the result is
146 * available. Note that this method is going away in a subsequent
147 * release since it doesn't distinguish between failure results and
148 * success results (exceptions should be used, but they aren't
149 * portable...). The <get> method should be used instead since it
150 * separates the error value from the result, and also permits
151 * timeouts.
153 operator T ();
155 /// Dump the state of an object.
156 void dump () const;
158 /// Declare the dynamic allocation hooks.
159 ACE_ALLOC_HOOK_DECLARE;
161 // = Encapsulate reference count and object lifetime of instances.
163 /// Allocate a new ACE_Future_Rep<T> instance, returning NULL if it
164 /// cannot be created.
165 static ACE_Future_Rep<T> *internal_create ();
167 /// Create a ACE_Future_Rep<T> and initialize the reference count.
168 static ACE_Future_Rep<T> *create ();
171 * Increase the reference count and return argument. Uses the
172 * attribute "value_ready_mutex_" to synchronize reference count
173 * updating.
175 * Precondition (rep != 0).
177 static ACE_Future_Rep<T> *attach (ACE_Future_Rep<T> *&rep);
180 * Decreases the reference count and deletes rep if there are no
181 * more references to rep.
183 * Precondition (rep != 0)
185 static void detach (ACE_Future_Rep<T> *&rep);
188 * Decreases the rep's reference count and deletes rep if there
189 * are no more references to rep. Then assigns new_rep to rep.
191 * Precondition (rep != 0 && new_rep != 0)
193 static void assign (ACE_Future_Rep<T> *&rep, ACE_Future_Rep<T> *new_rep);
195 /// Is result available?
196 int ready () const;
198 /// Pointer to the result.
199 std::atomic<T*> value_ {};
201 /// Reference count.
202 int ref_count_ {};
204 typedef ACE_Future_Observer<T> OBSERVER;
206 typedef ACE_Unbounded_Set<OBSERVER *> OBSERVER_COLLECTION;
208 /// Keep a list of ACE_Future_Observers unread by client's reader thread.
209 OBSERVER_COLLECTION observer_collection_;
211 // = Condition variable and mutex that protect the <value_>.
212 mutable ACE_SYNCH_RECURSIVE_MUTEX value_ready_mutex_;
213 mutable ACE_SYNCH_RECURSIVE_CONDITION value_ready_;
215 private:
216 ACE_Future_Rep ();
218 protected:
219 ~ACE_Future_Rep ();
223 * @class ACE_Future
225 * @brief This class implements a ``single write, multiple read''
226 * pattern that can be used to return results from asynchronous
227 * method invocations.
229 template <class T>
230 class ACE_Future
232 public:
233 /// Constructor.
234 ACE_Future ();
236 /// Copy constructor binds @a this and @a r to the same
237 /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary.
238 ACE_Future (const ACE_Future<T> &r);
240 /// Constructor that initialises an ACE_Future to point to the
241 /// result @a r immediately.
242 ACE_Future (const T &r);
244 /// Destructor.
245 ~ACE_Future ();
247 /// Assignment operator that binds @a this and @a r to the same
248 /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary.
249 void operator = (const ACE_Future<T> &r);
251 /// Cancel an ACE_Future and assign the value @a r. It is used if a
252 /// client does not want to wait for the value to be produced.
253 int cancel (const T &r);
256 * Cancel an ACE_Future. Put the future into its initial
257 * state. Returns 0 on succes and -1 on failure. It is now possible
258 * to reuse the ACE_Future. But remember, the ACE_Future
259 * is now bound to a new ACE_Future_Rep.
261 int cancel ();
264 * Equality operator that returns @c true if both ACE_Future objects
265 * point to the same ACE_Future_Rep object.
267 * @note It also returns @c true if both objects have just been
268 * instantiated and not used yet.
270 bool operator == (const ACE_Future<T> &r) const;
272 /// Inequality operator, which is the opposite of equality.
273 bool operator != (const ACE_Future<T> &r) const;
276 * Make the result available. Is used by the server thread to give
277 * the result to all waiting clients. Returns 0 for success, -1 on failure.
278 * This function only has an effect the first time it is called for
279 * the object (actually, the first time the underlying ACE_Future_Rep has a
280 * value assigned to it). Subsequent calls return 0 (success) but have no
281 * effect.
283 int set (const T &r);
286 * Wait to get the object's value.
288 * @param value Receives the value of this ACE_Future when it is set.
289 * @param tv Pointer to an ACE_Time_Value containing the absolute
290 * time to wait until for the value to be set. If @a tv
291 * is 0, the call waits indefinitely for the value to be
292 * set, unless an error occurs.
294 * @retval 0 Success; @a value contains the value of the ACE_Future.
295 * @retval -1 Error; check ACE_OS::last_error() for an error code.
297 int get (T &value, ACE_Time_Value *tv = 0) const;
300 * @deprecated Note that this method is going away in a subsequent
301 * release since it doesn't distinguish between failure
302 * results and success results (exceptions should be
303 * used, but they aren't portable...).
304 * Type conversion, which obtains the result of the asynchronous
305 * method invocation. Will block forever. The get() method should be
306 * used instead since it separates the error value from the result,
307 * and also permits timeouts.
309 operator T ();
311 /// Check if the result is available.
312 int ready () const;
315 * Attaches the specified observer to a subject (this ACE_Future).
316 * The update method of the specified subject will be invoked with a copy of
317 * the associated ACE_Future as input when the result gets set. If the
318 * result is already set when this method gets invoked, then the update
319 * method of the specified subject will be invoked immediately.
321 * @param observer The observer to attach to the subject.
323 * @retval 0 Success.
324 * @retval 1 The observer was already attached.
325 * @retval -1 Error; check ACE_OS::last_error() for an error code.
327 int attach (ACE_Future_Observer<T> *observer);
330 * Detaches the specified observer from a subject (this ACE_Future).
331 * The update method of the specified subject will not be invoked when the
332 * ACE_Future_Rep result gets set.
334 * @param observer The observer to attach to the subject.
336 * @retval 0 The observer was successfully detached.
337 * @retval -1 Error, including the observer not attached prior
338 * to calling this method.
340 int detach (ACE_Future_Observer<T> *observer);
342 /// Dump the state of an object.
343 void dump () const;
346 * Get the underlying ACE_Future_Rep pointer. Note that this method should
347 * rarely, if ever, be used and that modifying the underlying
348 * ACE_Future_Rep should be done with extreme caution.
350 ACE_Future_Rep<T> *get_rep ();
352 /// Declare the dynamic allocation hooks.
353 ACE_ALLOC_HOOK_DECLARE;
355 private:
356 /// The ACE_Future_Rep
357 /// Protect operations on the <Future>.
358 typedef ACE_Future_Rep<T> FUTURE_REP;
359 FUTURE_REP *future_rep_;
362 ACE_END_VERSIONED_NAMESPACE_DECL
364 #include "ace/Future.cpp"
366 #endif /* ACE_HAS_THREADS */
368 #include /**/ "ace/post.h"
370 #endif /* ACE_FUTURE_H */