Future.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Future.h
00006  *
00007  *  $Id: Future.h 80826 2008-03-04 14:51:23Z wotte $
00008  *
00009  *  @author Andres Kruse <Andres.Kruse@cern.ch>
00010  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00011  *  @author Per Andersson <Per.Andersson@hfera.ericsson.se> and
00012  *  @author John Tucker <johnny_tucker@yahoo.com>
00013  */
00014 //=============================================================================
00015 
00016 #ifndef ACE_FUTURE_H
00017 #define ACE_FUTURE_H
00018 
00019 #include /**/ "ace/pre.h"
00020 
00021 #include "ace/Unbounded_Set.h"
00022 #include "ace/Strategies_T.h"
00023 
00024 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00025 # pragma once
00026 #endif /* ACE_LACKS_PRAGMA_ONCE */
00027 
00028 #if defined (ACE_HAS_THREADS)
00029 
00030 #include "ace/Recursive_Thread_Mutex.h"
00031 #include "ace/Condition_Recursive_Thread_Mutex.h"
00032 
00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00034 
00035 // Forward decl.
00036 template <class T> class ACE_Future_Holder;
00037 template <class T> class ACE_Future_Observer;
00038 template <class T> class ACE_Future_Rep;
00039 template <class T> class ACE_Future;
00040 
00041 /**
00042  * @class ACE_Future_Holder
00043  *
00044  * @brief Implementation of object that holds an ACE_Future.
00045  */
00046 template <class T>
00047 class ACE_Future_Holder
00048 {
00049 public:
00050   ACE_Future_Holder (const ACE_Future<T> &future);
00051   ~ACE_Future_Holder (void);
00052 
00053   /// Declare the dynamic allocation hooks.
00054   ACE_ALLOC_HOOK_DECLARE;
00055 
00056   ACE_Future<T> item_;
00057 
00058 protected:
00059   ACE_Future_Holder (void);
00060 };
00061 
00062 /**
00063  * @class ACE_Future_Observer
00064  *
00065  * @brief ACE_Future_Observer<T>
00066  *
00067  * An ACE_Future_Observer object implements an object that is
00068  * subscribed with an ACE_Future object so that it may be notified
00069  * when the value of the ACE_Future object is written to by a writer
00070  * thread.  It uses the Observer pattern.
00071  */
00072 template <class T>
00073 class ACE_Future_Observer
00074 {
00075 public:
00076   /// Destructor
00077   virtual ~ACE_Future_Observer (void);
00078 
00079   /// Called by the ACE_Future in which we are subscribed to when
00080   /// its value is written to.
00081   virtual void update (const ACE_Future<T> &future) = 0;
00082 
00083   /// Declare the dynamic allocation hooks.
00084   ACE_ALLOC_HOOK_DECLARE;
00085 protected:
00086 
00087   /// Constructor
00088   ACE_Future_Observer (void);
00089 };
00090 
00091 /**
00092  * @class ACE_Future_Rep
00093  *
00094  * @internal
00095  *
00096  * @brief ACE_Future_Rep<T>
00097  *
00098  * An ACE_Future_Rep<T> object encapsules a pointer to an object
00099  * of class T which is the result of an asynchronous method
00100  * invocation. It is pointed to by ACE_Future<T> object[s] and
00101  * only accessible through them.
00102  */
00103 template <class T>
00104 class ACE_Future_Rep
00105 {
00106 private:
00107   friend class ACE_Future<T>;
00108 
00109   /**
00110    * Set the result value.  The specified <caller> represents the
00111    * future that invoked this <set> method, which is used to notify
00112    * the list of future observers. Returns 0 for success, -1 on error.
00113    * This function only has an effect the first time it is called for
00114    * the object. Subsequent calls return 0 (success) but have no effect.
00115    */
00116   int set (const T &r,
00117            ACE_Future<T> &caller);
00118 
00119   /// Wait up to @a tv time to get the @a value.  Note that @a tv must be
00120   /// specified in absolute time rather than relative time.
00121   int get (T &value,
00122            ACE_Time_Value *tv) const;
00123 
00124   /**
00125    * Attaches the specified observer to a subject (i.e., the ACE_Future_Rep).
00126    * The update method of the specified subject will be invoked with a copy of
00127    * the written-to ACE_Future as input when the result gets set.
00128    *
00129    * Returns 0 if the observer is successfully attached, 1 if the
00130    * observer is already attached, and -1 if failures occur.
00131    */
00132   int attach (ACE_Future_Observer<T> *observer,
00133                ACE_Future<T> &caller);
00134 
00135   /**
00136    * Detaches the specified observer from a subject (i.e., the ACE_Future_Rep).
00137    * The update method of the specified subject will not be invoked when the
00138    * ACE_Future_Reps result gets set.  Returns 1 if the specified observer was
00139    * actually attached to the subject prior to this call and 0 if was not.
00140    *
00141    * Returns 0 if the observer was successfully detached, and -1 if the
00142    * observer was not attached in the first place.
00143    */
00144   int detach (ACE_Future_Observer<T> *observer);
00145 
00146   /**
00147    * Type conversion. will block forever until the result is
00148    * available.  Note that this method is going away in a subsequent
00149    * release since it doesn't distinguish between failure results and
00150    * success results (exceptions should be used, but they aren't
00151    * portable...).  The <get> method should be used instead since it
00152    * separates the error value from the result, and also permits
00153    * timeouts.
00154    */
00155   operator T ();
00156 
00157   /// Dump the state of an object.
00158   void dump (void) const;
00159 
00160   /// Declare the dynamic allocation hooks.
00161   ACE_ALLOC_HOOK_DECLARE;
00162 
00163   // = Encapsulate reference count and object lifetime of instances.
00164 
00165   // These methods must go after the others to work around a bug with
00166   // Borland's C++ Builder...
00167 
00168   /// Allocate a new ACE_Future_Rep<T> instance, returning NULL if it
00169   /// cannot be created.
00170   static ACE_Future_Rep<T> *internal_create (void);
00171 
00172   /// Create a ACE_Future_Rep<T> and initialize the reference count.
00173   static ACE_Future_Rep<T> *create (void);
00174 
00175   /**
00176    * Increase the reference count and return argument. Uses the
00177    * attribute "value_ready_mutex_" to synchronize reference count
00178    * updating.
00179    *
00180    * Precondition (rep != 0).
00181    */
00182   static ACE_Future_Rep<T> *attach (ACE_Future_Rep<T> *&rep);
00183 
00184   /**
00185    * Decreases the reference count and deletes rep if there are no
00186    * more references to rep.
00187    *
00188    * Precondition (rep != 0)
00189    */
00190   static void detach (ACE_Future_Rep<T> *&rep);
00191 
00192   /**
00193    * Decreases the rep's reference count and deletes rep if there
00194    * are no more references to rep. Then assigns new_rep to rep.
00195    *
00196    * Precondition (rep != 0 && new_rep != 0)
00197    */
00198   static void assign (ACE_Future_Rep<T> *&rep, ACE_Future_Rep<T> *new_rep);
00199 
00200   /// Is result available?
00201   int ready (void) const;
00202 
00203   /// Pointer to the result.
00204   T *value_;
00205 
00206   /// Reference count.
00207   int ref_count_;
00208 
00209   typedef ACE_Future_Observer<T> OBSERVER;
00210 
00211   typedef ACE_Unbounded_Set<OBSERVER *> OBSERVER_COLLECTION;
00212 
00213   /// Keep a list of ACE_Future_Observers unread by client's reader thread.
00214   OBSERVER_COLLECTION observer_collection_;
00215 
00216   // = Condition variable and mutex that protect the <value_>.
00217   mutable ACE_Recursive_Thread_Mutex value_ready_mutex_;
00218   mutable ACE_Condition_Recursive_Thread_Mutex value_ready_;
00219 
00220 private:
00221 
00222   ACE_Future_Rep (void);
00223 
00224 protected:
00225 
00226   ~ACE_Future_Rep (void);
00227 
00228 };
00229 
00230 /**
00231  * @class ACE_Future
00232  *
00233  * @brief This class implements a ``single write, multiple read''
00234  * pattern that can be used to return results from asynchronous
00235  * method invocations.
00236  */
00237 template <class T>
00238 class ACE_Future
00239 {
00240 public:
00241   // = Initialization and termination methods.
00242   /// Constructor.
00243   ACE_Future (void);
00244 
00245   /// Copy constructor binds @a this and @a r to the same
00246   /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary.
00247   ACE_Future (const ACE_Future<T> &r);
00248 
00249   /// Constructor that initialises an ACE_Future to point to the
00250   /// result @a r immediately.
00251   ACE_Future (const T &r);
00252 
00253   /// Destructor.
00254   ~ACE_Future (void);
00255 
00256   /// Assignment operator that binds @a this and @a r to the same
00257   /// ACE_Future_Rep. An ACE_Future_Rep is created if necessary.
00258   void operator = (const ACE_Future<T> &r);
00259 
00260   /// Cancel an ACE_Future and assign the value @a r.  It is used if a
00261   /// client does not want to wait for the value to be produced.
00262   int cancel (const T &r);
00263 
00264   /**
00265    * Cancel an ACE_Future.  Put the future into its initial
00266    * state. Returns 0 on succes and -1 on failure. It is now possible
00267    * to reuse the ACE_Future. But remember, the ACE_Future
00268    * is now bound to a new ACE_Future_Rep.
00269    */
00270   int cancel (void);
00271 
00272   /**
00273    * Equality operator that returns @c true if both ACE_Future objects
00274    * point to the same ACE_Future_Rep object.
00275    *
00276    * @note It also returns @c true if both objects have just been
00277    *       instantiated and not used yet.
00278    */
00279   bool operator == (const ACE_Future<T> &r) const;
00280 
00281   /// Inequality operator, which is the opposite of equality.
00282   bool operator != (const ACE_Future<T> &r) const;
00283 
00284   /**
00285    * Make the result available. Is used by the server thread to give
00286    * the result to all waiting clients. Returns 0 for success, -1 on failure.
00287    * This function only has an effect the first time it is called for
00288    * the object (actually, the first time the underlying ACE_Future_Rep has a
00289    * value assigned to it). Subsequent calls return 0 (success) but have no
00290    * effect.
00291    */
00292   int set (const T &r);
00293 
00294   /**
00295    * Wait to get the object's value.
00296    *
00297    * @param value Receives the value of this ACE_Future when it is set.
00298    * @param tv    Pointer to an ACE_Time_Value containing the absolute
00299    *              time to wait until for the value to be set. If @a tv
00300    *              is 0, the call waits indefinitely for the value to be
00301    *              set, unless an error occurs.
00302    *
00303    * @retval  0   Success; @a value contains the value of the ACE_Future.
00304    * @retval -1   Error; check ACE_OS::last_error() for an error code.
00305    */
00306   int get (T &value,
00307            ACE_Time_Value *tv = 0) const;
00308 
00309   /**
00310    * @deprecated  Note that this method is going away in a subsequent
00311    *              release since it doesn't distinguish between failure
00312    *              results and success results (exceptions should be
00313    *              used, but they aren't portable...).
00314    * Type conversion, which obtains the result of the asynchronous
00315    * method invocation.  Will block forever. The get() method should be
00316    * used instead since it separates the error value from the result,
00317    * and also permits timeouts.
00318    */
00319   operator T ();
00320 
00321   /// Check if the result is available.
00322   int ready (void) const;
00323 
00324   /**
00325    * Attaches the specified observer to a subject (this ACE_Future).
00326    * The update method of the specified subject will be invoked with a copy of
00327    * the associated ACE_Future as input when the result gets set.  If the
00328    * result is already set when this method gets invoked, then the update
00329    * method of the specified subject will be invoked immediately.
00330    *
00331    * @param observer The observer to attach to the subject.
00332    *
00333    * @retval  0   Success.
00334    * @retval  1   The observer was already attached.
00335    * @retval -1   Error; check ACE_OS::last_error() for an error code.
00336    */
00337   int attach (ACE_Future_Observer<T> *observer);
00338 
00339   /**
00340    * Detaches the specified observer from a subject (this ACE_Future).
00341    * The update method of the specified subject will not be invoked when the
00342    * ACE_Future_Rep result gets set.
00343    *
00344    * @param observer The observer to attach to the subject.
00345    *
00346    * @retval  0   The observer was successfully detached.
00347    * @retval -1   Error, including the observer not attached prior
00348    *              to calling this method.
00349    */
00350   int detach (ACE_Future_Observer<T> *observer);
00351 
00352   /// Dump the state of an object.
00353   void dump (void) const;
00354 
00355   /**
00356    * Get the underlying ACE_Future_Rep pointer. Note that this method should
00357    * rarely, if ever, be used and that modifying the underlying
00358    * ACE_Future_Rep should be done with extreme caution.
00359    */
00360   ACE_Future_Rep<T> *get_rep (void);
00361 
00362   /// Declare the dynamic allocation hooks.
00363   ACE_ALLOC_HOOK_DECLARE;
00364 
00365 private:
00366 
00367   // the ACE_Future_Rep
00368   /// Protect operations on the <Future>.
00369   typedef ACE_Future_Rep<T> FUTURE_REP;
00370   FUTURE_REP *future_rep_;
00371 };
00372 
00373 ACE_END_VERSIONED_NAMESPACE_DECL
00374 
00375 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00376 #include "ace/Future.cpp"
00377 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00378 
00379 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00380 #pragma implementation ("Future.cpp")
00381 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00382 
00383 #endif /* ACE_HAS_THREADS */
00384 
00385 #include /**/ "ace/post.h"
00386 
00387 #endif /* ACE_FUTURE_H */

Generated on Tue Feb 2 17:18:39 2010 for ACE by  doxygen 1.4.7