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