diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
commit | 99aa8c60282c7b8072eb35eb9ac815702f5bf586 (patch) | |
tree | bda96bf8c3a4c2875a083d7b16720533c8ffeaf4 /ACE/ace/Future.h | |
parent | c4078c377d74290ebe4e66da0b4975da91732376 (diff) | |
download | ATCD-99aa8c60282c7b8072eb35eb9ac815702f5bf586.tar.gz |
undoing accidental deletion
Diffstat (limited to 'ACE/ace/Future.h')
-rw-r--r-- | ACE/ace/Future.h | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/ACE/ace/Future.h b/ACE/ace/Future.h new file mode 100644 index 00000000000..c172b0fd9ac --- /dev/null +++ b/ACE/ace/Future.h @@ -0,0 +1,387 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Future.h + * + * $Id$ + * + * @author Andres Kruse <Andres.Kruse@cern.ch> + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + * @author Per Andersson <Per.Andersson@hfera.ericsson.se> and + * @author John Tucker <johnny_tucker@yahoo.com> + */ +//============================================================================= + +#ifndef ACE_FUTURE_H +#define ACE_FUTURE_H + +#include /**/ "ace/pre.h" + +#include "ace/Unbounded_Set.h" +#include "ace/Strategies_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) + +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decl. +template <class T> class ACE_Future_Holder; +template <class T> class ACE_Future_Observer; +template <class T> class ACE_Future_Rep; +template <class T> class ACE_Future; + +/** + * @class ACE_Future_Holder + * + * @brief Implementation of object that holds an ACE_Future. + */ +template <class T> +class ACE_Future_Holder +{ +public: + ACE_Future_Holder (const ACE_Future<T> &future); + ~ACE_Future_Holder (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + ACE_Future<T> item_; + +protected: + ACE_Future_Holder (void); +}; + +/** + * @class ACE_Future_Observer + * + * @brief ACE_Future_Observer<T> + * + * An ACE_Future_Observer object implements an object that is + * subscribed with an ACE_Future object so that it may be notified + * when the value of the ACE_Future object is written to by a writer + * thread. It uses the Observer pattern. + */ +template <class T> +class ACE_Future_Observer +{ +public: + /// Destructor + virtual ~ACE_Future_Observer (void); + + /// Called by the ACE_Future in which we are subscribed to when + /// its value is written to. + virtual void update (const ACE_Future<T> &future) = 0; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +protected: + + /// Constructor + ACE_Future_Observer (void); +}; + +/** + * @class ACE_Future_Rep + * + * @internal + * + * @brief ACE_Future_Rep<T> + * + * An ACE_Future_Rep<T> object encapsules a pointer to an object + * of class T which is the result of an asynchronous method + * invocation. It is pointed to by ACE_Future<T> object[s] and + * only accessible through them. + */ +template <class T> +class ACE_Future_Rep +{ +private: + friend class ACE_Future<T>; + + /** + * Set the result value. The specified <caller> represents the + * future that invoked this <set> method, which is used to notify + * the list of future observers. Returns 0 for success, -1 on error. + * This function only has an effect the first time it is called for + * the object. Subsequent calls return 0 (success) but have no effect. + */ + int set (const T &r, + ACE_Future<T> &caller); + + /// Wait up to @a tv time to get the @a value. Note that @a tv must be + /// specified in absolute time rather than relative time. + int get (T &value, + ACE_Time_Value *tv) const; + + /** + * Attaches the specified observer to a subject (i.e., the ACE_Future_Rep). + * The update method of the specified subject will be invoked with a copy of + * the written-to ACE_Future as input when the result gets set. + * + * Returns 0 if the observer is successfully attached, 1 if the + * observer is already attached, and -1 if failures occur. + */ + int attach (ACE_Future_Observer<T> *observer, + ACE_Future<T> &caller); + + /** + * Detaches the specified observer from a subject (i.e., the ACE_Future_Rep). + * The update method of the specified subject will not be invoked when the + * ACE_Future_Reps result gets set. Returns 1 if the specified observer was + * actually attached to the subject prior to this call and 0 if was not. + * + * Returns 0 if the observer was successfully detached, and -1 if the + * observer was not attached in the first place. + */ + int detach (ACE_Future_Observer<T> *observer); + + /** + * Type conversion. will block forever until the result is + * available. Note that this method is going away in a subsequent + * release since it doesn't distinguish between failure results and + * success results (exceptions should be used, but they aren't + * portable...). The <get> method should be used instead since it + * separates the error value from the result, and also permits + * timeouts. + */ + operator T (); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = Encapsulate reference count and object lifetime of instances. + + // These methods must go after the others to work around a bug with + // Borland's C++ Builder... + + /// Allocate a new ACE_Future_Rep<T> instance, returning NULL if it + /// cannot be created. + static ACE_Future_Rep<T> *internal_create (void); + + /// Create a ACE_Future_Rep<T> and initialize the reference count. + static ACE_Future_Rep<T> *create (void); + + /** + * Increase the reference count and return argument. Uses the + * attribute "value_ready_mutex_" to synchronize reference count + * updating. + * + * Precondition (rep != 0). + */ + static ACE_Future_Rep<T> *attach (ACE_Future_Rep<T> *&rep); + + /** + * Decreases the reference count and deletes rep if there are no + * more references to rep. + * + * Precondition (rep != 0) + */ + static void detach (ACE_Future_Rep<T> *&rep); + + /** + * Decreases the rep's reference count and deletes rep if there + * are no more references to rep. Then assigns new_rep to rep. + * + * Precondition (rep != 0 && new_rep != 0) + */ + static void assign (ACE_Future_Rep<T> *&rep, ACE_Future_Rep<T> *new_rep); + + /// Is result available? + int ready (void) const; + + /// Pointer to the result. + T *value_; + + /// Reference count. + int ref_count_; + + typedef ACE_Future_Observer<T> OBSERVER; + + typedef ACE_Unbounded_Set<OBSERVER *> OBSERVER_COLLECTION; + + /// Keep a list of ACE_Future_Observers unread by client's reader thread. + OBSERVER_COLLECTION observer_collection_; + + // = Condition variable and mutex that protect the <value_>. + mutable ACE_Recursive_Thread_Mutex value_ready_mutex_; + mutable ACE_Condition_Recursive_Thread_Mutex value_ready_; + +private: + + ACE_Future_Rep (void); + +protected: + + ~ACE_Future_Rep (void); + +}; + +/** + * @class ACE_Future + * + * @brief This class implements a ``single write, multiple read'' + * pattern that can be used to return results from asynchronous + * method invocations. + */ +template <class T> +class ACE_Future +{ +public: + // = Initialization and termination methods. + /// Constructor. + ACE_Future (void); + + /// Copy constructor binds @a this and @a r to the same + /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary. + ACE_Future (const ACE_Future<T> &r); + + /// Constructor that initialises an ACE_Future to point to the + /// result @a r immediately. + ACE_Future (const T &r); + + /// Destructor. + ~ACE_Future (void); + + /// Assignment operator that binds @a this and @a r to the same + /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary. + void operator = (const ACE_Future<T> &r); + + /// Cancel an ACE_Future and assign the value @a r. It is used if a + /// client does not want to wait for the value to be produced. + int cancel (const T &r); + + /** + * Cancel an ACE_Future. Put the future into its initial + * state. Returns 0 on succes and -1 on failure. It is now possible + * to reuse the ACE_Future. But remember, the ACE_Future + * is now bound to a new ACE_Future_Rep. + */ + int cancel (void); + + /** + * Equality operator that returns @c true if both ACE_Future objects + * point to the same ACE_Future_Rep object. + * + * @note It also returns @c true if both objects have just been + * instantiated and not used yet. + */ + bool operator == (const ACE_Future<T> &r) const; + + /// Inequality operator, which is the opposite of equality. + bool operator != (const ACE_Future<T> &r) const; + + /** + * Make the result available. Is used by the server thread to give + * the result to all waiting clients. Returns 0 for success, -1 on failure. + * This function only has an effect the first time it is called for + * the object (actually, the first time the underlying ACE_Future_Rep has a + * value assigned to it). Subsequent calls return 0 (success) but have no + * effect. + */ + int set (const T &r); + + /** + * Wait to get the object's value. + * + * @param value Receives the value of this ACE_Future when it is set. + * @param tv Pointer to an ACE_Time_Value containing the absolute + * time to wait until for the value to be set. If @a tv + * is 0, the call waits indefinitely for the value to be + * set, unless an error occurs. + * + * @retval 0 Success; @a value contains the value of the ACE_Future. + * @retval -1 Error; check ACE_OS::last_error() for an error code. + */ + int get (T &value, + ACE_Time_Value *tv = 0) const; + + /** + * @deprecated Note that this method is going away in a subsequent + * release since it doesn't distinguish between failure + * results and success results (exceptions should be + * used, but they aren't portable...). + * Type conversion, which obtains the result of the asynchronous + * method invocation. Will block forever. The get() method should be + * used instead since it separates the error value from the result, + * and also permits timeouts. + */ + operator T (); + + /// Check if the result is available. + int ready (void) const; + + /** + * Attaches the specified observer to a subject (this ACE_Future). + * The update method of the specified subject will be invoked with a copy of + * the associated ACE_Future as input when the result gets set. If the + * result is already set when this method gets invoked, then the update + * method of the specified subject will be invoked immediately. + * + * @param observer The observer to attach to the subject. + * + * @retval 0 Success. + * @retval 1 The observer was already attached. + * @retval -1 Error; check ACE_OS::last_error() for an error code. + */ + int attach (ACE_Future_Observer<T> *observer); + + /** + * Detaches the specified observer from a subject (this ACE_Future). + * The update method of the specified subject will not be invoked when the + * ACE_Future_Rep result gets set. + * + * @param observer The observer to attach to the subject. + * + * @retval 0 The observer was successfully detached. + * @retval -1 Error, including the observer not attached prior + * to calling this method. + */ + int detach (ACE_Future_Observer<T> *observer); + + /// Dump the state of an object. + void dump (void) const; + + /** + * Get the underlying ACE_Future_Rep pointer. Note that this method should + * rarely, if ever, be used and that modifying the underlying + * ACE_Future_Rep should be done with extreme caution. + */ + ACE_Future_Rep<T> *get_rep (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + + // the ACE_Future_Rep + /// Protect operations on the <Future>. + typedef ACE_Future_Rep<T> FUTURE_REP; + FUTURE_REP *future_rep_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Future.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Future.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" + +#endif /* ACE_FUTURE_H */ |