ACE_Future_Rep< T > Class Template Reference

ACE_Future_Rep<T>. More...

#include <Future.h>

Collaboration diagram for ACE_Future_Rep< T >:

Collaboration graph
[legend]
List of all members.

Protected Member Functions

 ~ACE_Future_Rep (void)

Private Types

typedef ACE_Future_Observer<
T > 
OBSERVER
typedef ACE_Unbounded_Set<
OBSERVER * > 
OBSERVER_COLLECTION

Private Member Functions

int set (const T &r, ACE_Future< T > &caller)
int get (T &value, ACE_Time_Value *tv) const
int attach (ACE_Future_Observer< T > *observer, ACE_Future< T > &caller)
int detach (ACE_Future_Observer< T > *observer)
 operator T ()
void dump (void) const
 Dump the state of an object.

int ready (void) const
 Is result available?

 ACE_Future_Rep (void)

Static Private Member Functions

ACE_Future_Rep< T > * internal_create (void)
ACE_Future_Rep< T > * create (void)
 Create a ACE_Future_Rep<T> and initialize the reference count.

ACE_Future_Rep< T > * attach (ACE_Future_Rep< T > *&rep)
void detach (ACE_Future_Rep< T > *&rep)
void assign (ACE_Future_Rep< T > *&rep, ACE_Future_Rep< T > *new_rep)

Private Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

T * value_
 Pointer to the result.

int ref_count_
 Reference count.

OBSERVER_COLLECTION observer_collection_
 Keep a list of ACE_Future_Observers unread by client's reader thread.

ACE_Recursive_Thread_Mutex value_ready_mutex_
ACE_Condition_Recursive_Thread_Mutex value_ready_

Friends

class ACE_Future< T >

Detailed Description

template<class T>
class ACE_Future_Rep< T >

ACE_Future_Rep<T>.

For internal use only.

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.

Definition at line 104 of file Future.h.


Member Typedef Documentation

template<class T>
typedef ACE_Future_Observer<T> ACE_Future_Rep< T >::OBSERVER [private]
 

Definition at line 211 of file Future.h.

Referenced by ACE_Future_Rep< T >::set().

template<class T>
typedef ACE_Unbounded_Set<OBSERVER *> ACE_Future_Rep< T >::OBSERVER_COLLECTION [private]
 

Definition at line 214 of file Future.h.


Constructor & Destructor Documentation

template<class T>
ACE_Future_Rep< T >::ACE_Future_Rep void   )  [private]
 

Definition at line 146 of file Future.cpp.

00147   : value_ (0),
00148     ref_count_ (0),
00149     value_ready_ (this->value_ready_mutex_)
00150 {
00151 }

template<class T>
ACE_Future_Rep< T >::~ACE_Future_Rep void   )  [protected]
 

Definition at line 154 of file Future.cpp.

00155 {
00156   delete this->value_;
00157 }


Member Function Documentation

template<class T>
void ACE_Future_Rep< T >::assign ACE_Future_Rep< T > *&  rep,
ACE_Future_Rep< T > *  new_rep
[static, private]
 

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)

Definition at line 124 of file Future.cpp.

References ACE_ASSERT, ACE_GUARD, ACE_Future_Rep< T >::ref_count_, and ACE_Future_Rep< T >::value_ready_mutex_.

00125 {
00126   ACE_ASSERT (rep != 0);
00127   ACE_ASSERT (new_rep != 0);
00128   // Use value_ready_mutex_ for both condition and ref count management
00129   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_));
00130 
00131   ACE_Future_Rep<T>* old = rep;
00132   rep = new_rep;
00133 
00134   // detached old last for exception safety
00135   if (old->ref_count_-- == 0)
00136     {
00137       ACE_MT (r_mon.release ());
00138       // We do not need the lock when deleting the representation.
00139       // There should be no side effects from deleting rep and we don
00140       // not want to release a deleted mutex.
00141       delete old;
00142     }
00143 }

template<class T>
ACE_Future_Rep< T > * ACE_Future_Rep< T >::attach ACE_Future_Rep< T > *&  rep  )  [static, private]
 

Increase the reference count and return argument. Uses the attribute "value_ready_mutex_" to synchronize reference count updating.

Precondition (rep != 0).

Definition at line 97 of file Future.cpp.

References ACE_ASSERT, ACE_Future_Rep< T >::ref_count_, and ACE_Future_Rep< T >::value_ready_mutex_.

00098 {
00099   ACE_ASSERT (rep != 0);
00100   // Use value_ready_mutex_ for both condition and ref count management
00101   ACE_MT (ACE_Guard<ACE_Recursive_Thread_Mutex> r_mon (rep->value_ready_mutex_));
00102   ++rep->ref_count_;
00103   return rep;
00104 }

template<class T>
int ACE_Future_Rep< T >::attach ACE_Future_Observer< T > *  observer,
ACE_Future< T > &  caller
[private]
 

Attaches the specified observer to a subject (i.e., the ). 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.

Definition at line 232 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_Unbounded_Set< T >::insert(), ACE_Future_Rep< T >::observer_collection_, and ACE_Future_Observer< T >::update().

Referenced by ACE_Future< T >::attach().

00234 {
00235   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
00236 
00237   // Otherwise, create a new result value.  Note the use of the
00238   // Double-checked locking pattern to avoid corrupting the list.
00239 
00240   int result = 1;
00241 
00242   // If the value is already produced, then notify observer
00243   if (this->value_ == 0)
00244     result = this->observer_collection_.insert (observer);
00245   else
00246       observer->update (caller);
00247 
00248   return result;
00249 }

template<class T>
ACE_Future_Rep< T > * ACE_Future_Rep< T >::create void   )  [static, private]
 

Create a ACE_Future_Rep<T> and initialize the reference count.

Definition at line 82 of file Future.cpp.

References ACE_ASSERT, ACE_throw_bad_alloc, and ACE_Future_Rep< T >::internal_create().

00083 {
00084   // Yes set ref count to zero.
00085   ACE_Future_Rep<T> *temp = internal_create ();
00086 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
00087   if (temp == 0)
00088     ACE_throw_bad_alloc;
00089 #else
00090   ACE_ASSERT (temp != 0);
00091 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00092    return temp;
00093  }

template<class T>
void ACE_Future_Rep< T >::detach ACE_Future_Rep< T > *&  rep  )  [static, private]
 

Decreases the reference count and deletes rep if there are no more references to rep.

Precondition (rep != 0)

Definition at line 107 of file Future.cpp.

References ACE_ASSERT, ACE_GUARD, ACE_Future_Rep< T >::ref_count_, and ACE_Future_Rep< T >::value_ready_mutex_.

00108 {
00109   ACE_ASSERT (rep != 0);
00110   // Use value_ready_mutex_ for both condition and ref count management
00111   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_));
00112 
00113   if (rep->ref_count_-- == 0)
00114     {
00115       ACE_MT (r_mon.release ());
00116       // We do not need the lock when deleting the representation.
00117       // There should be no side effects from deleting rep and we don
00118       // not want to release a deleted mutex.
00119       delete rep;
00120     }
00121 }

template<class T>
int ACE_Future_Rep< T >::detach ACE_Future_Observer< T > *  observer  )  [private]
 

Detaches the specified observer from a subject (i.e., the ). The update method of the specified subject will not be invoked when the s 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.

Definition at line 252 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_Future_Rep< T >::observer_collection_, and ACE_Unbounded_Set< T >::remove().

Referenced by ACE_Future< T >::detach().

00253 {
00254   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
00255 
00256   // Remove all occurrences of the specified observer from this
00257   // objects hash map.
00258   return this->observer_collection_.remove (observer);
00259 }

template<class T>
void ACE_Future_Rep< T >::dump void   )  const [private]
 

Dump the state of an object.

Definition at line 50 of file Future.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_Recursive_Thread_Mutex::dump(), ACE_Condition< ACE_Recursive_Thread_Mutex >::dump(), LM_DEBUG, LM_INFO, ACE_Future_Rep< T >::value_ready_, and ACE_Future_Rep< T >::value_ready_mutex_.

Referenced by ACE_Future< T >::dump().

00051 {
00052 #if defined (ACE_HAS_DUMP)
00053   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00054   ACE_DEBUG ((LM_DEBUG,
00055               "ref_count_ = %d\n",
00056  (int) this->ref_count_));
00057   ACE_DEBUG ((LM_INFO,"value_: \n"));
00058   if (this->value_)
00059     ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" (NON-NULL)\n")));
00060   else
00061     ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" (NULL)\n")));
00062 
00063   ACE_DEBUG ((LM_INFO,"value_ready_: \n"));
00064   this->value_ready_.dump ();
00065   ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n"));
00066   this->value_ready_mutex_.dump ();
00067   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00068 #endif /* ACE_HAS_DUMP */
00069 }

template<class T>
int ACE_Future_Rep< T >::get T &  value,
ACE_Time_Value tv
const [private]
 

Wait up to time to get the . Note that must be specified in absolute time rather than relative time.

Definition at line 207 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_Future_Rep< T >::value_ready_, and ACE_Condition< ACE_Recursive_Thread_Mutex >::wait().

Referenced by ACE_Future< T >::get().

00209 {
00210   // If the value is already produced, return it.
00211   if (this->value_ == 0)
00212     {
00213       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00214                                 this->value_ready_mutex_,
00215                                 -1));
00216       // If the value is not yet defined we must block until the
00217       // producer writes to it.
00218 
00219       while (this->value_ == 0)
00220         // Perform a timed wait.
00221         if (this->value_ready_.wait (tv) == -1)
00222           return -1;
00223 
00224       // Destructor releases the lock.
00225     }
00226 
00227   value = *this->value_;
00228   return 0;
00229 }

template<class T>
ACE_Future_Rep< T > * ACE_Future_Rep< T >::internal_create void   )  [static, private]
 

Allocate a new ACE_Future_Rep<T> instance, returning NULL if it cannot be created.

Definition at line 72 of file Future.cpp.

References ACE_NEW_RETURN.

Referenced by ACE_Future_Rep< T >::create().

00073 {
00074   ACE_Future_Rep<T> *temp = 0;
00075   ACE_NEW_RETURN (temp,
00076                   ACE_Future_Rep<T> (),
00077                   0);
00078   return temp;
00079 }

template<class T>
ACE_Future_Rep< T >::operator T  )  [private]
 

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 method should be used instead since it separates the error value from the result, and also permits timeouts.

Definition at line 262 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_Future_Rep< T >::value_ready_, and ACE_Condition< ACE_Recursive_Thread_Mutex >::wait().

00263 {
00264   // If the value is already produced, return it.
00265   if (this->value_ == 0)
00266     {
00267       // Constructor of ace_mon acquires the mutex.
00268       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0));
00269 
00270       // If the value is not yet defined we must block until the
00271       // producer writes to it.
00272 
00273       // Wait ``forever.''
00274 
00275       while (this->value_ == 0)
00276         if (this->value_ready_.wait () == -1)
00277           // What to do in this case since we've got to indicate
00278           // failure somehow?  Exceptions would be nice, but they're
00279           // not portable...
00280           return 0;
00281 
00282       // Destructor releases the mutex
00283     }
00284 
00285   return *this->value_;
00286 }

template<class T>
int ACE_Future_Rep< T >::ready void   )  const [private]
 

Is result available?

Definition at line 160 of file Future.cpp.

Referenced by ACE_Future< T >::ready().

00161 {
00162   return this->value_ != 0;
00163 }

template<class T>
int ACE_Future_Rep< T >::set const T &  r,
ACE_Future< T > &  caller
[private]
 

Set the result value. The specified represents the future that invoked this 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.

Definition at line 166 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_Unbounded_Set< T >::begin(), ACE_Condition< ACE_Recursive_Thread_Mutex >::broadcast(), ACE_Unbounded_Set< T >::end(), ACE_Future_Rep< T >::OBSERVER, ACE_Future_Rep< T >::observer_collection_, ACE_Future_Observer< T >::update(), and ACE_Future_Rep< T >::value_ready_.

Referenced by ACE_Future< T >::ACE_Future(), ACE_Future< T >::cancel(), and ACE_Future< T >::set().

00168 {
00169   // If the value is already produced, ignore it...
00170   if (this->value_ == 0)
00171     {
00172       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00173                                 ace_mon,
00174                                 this->value_ready_mutex_,
00175                                 -1));
00176       // Otherwise, create a new result value.  Note the use of the
00177       // Double-checked locking pattern to avoid multiple allocations.
00178 
00179       if (this->value_ == 0)       // Still no value, so proceed
00180         {
00181           ACE_NEW_RETURN (this->value_,
00182                           T (r),
00183                           -1);
00184 
00185           // Remove and notify all subscribed observers.
00186           ACE_TYPENAME OBSERVER_COLLECTION::iterator iterator =
00187             this->observer_collection_.begin ();
00188 
00189           ACE_TYPENAME OBSERVER_COLLECTION::iterator end =
00190             this->observer_collection_.end ();
00191 
00192           while (iterator != end)
00193             {
00194               OBSERVER *observer = *iterator++;
00195               observer->update (caller);
00196             }
00197 
00198           // Signal all the waiting threads.
00199           return this->value_ready_.broadcast ();
00200         }
00201       // Destructor releases the lock.
00202     }
00203   return 0;
00204 }


Friends And Related Function Documentation

template<class T>
friend class ACE_Future< T > [friend]
 

Definition at line 107 of file Future.h.


Member Data Documentation

template<class T>
ACE_Future_Rep< T >::ACE_ALLOC_HOOK_DECLARE [private]
 

Declare the dynamic allocation hooks.

Definition at line 161 of file Future.h.

template<class T>
OBSERVER_COLLECTION ACE_Future_Rep< T >::observer_collection_ [private]
 

Keep a list of ACE_Future_Observers unread by client's reader thread.

Definition at line 217 of file Future.h.

Referenced by ACE_Future_Rep< T >::attach(), ACE_Future_Rep< T >::detach(), and ACE_Future_Rep< T >::set().

template<class T>
int ACE_Future_Rep< T >::ref_count_ [private]
 

Reference count.

Definition at line 208 of file Future.h.

Referenced by ACE_Future_Rep< T >::assign(), ACE_Future_Rep< T >::attach(), and ACE_Future_Rep< T >::detach().

template<class T>
T* ACE_Future_Rep< T >::value_ [private]
 

Pointer to the result.

Definition at line 205 of file Future.h.

template<class T>
ACE_Condition_Recursive_Thread_Mutex ACE_Future_Rep< T >::value_ready_ [mutable, private]
 

Definition at line 221 of file Future.h.

Referenced by ACE_Future_Rep< T >::dump(), ACE_Future_Rep< T >::get(), ACE_Future_Rep< T >::operator T(), and ACE_Future_Rep< T >::set().

template<class T>
ACE_Recursive_Thread_Mutex ACE_Future_Rep< T >::value_ready_mutex_ [mutable, private]
 

Definition at line 220 of file Future.h.

Referenced by ACE_Future_Rep< T >::assign(), ACE_Future_Rep< T >::attach(), ACE_Future_Rep< T >::detach(), and ACE_Future_Rep< T >::dump().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:22:33 2006 for ACE by doxygen 1.3.6