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 148 of file Future.cpp.

00149   : value_ (0),
00150     ref_count_ (0),
00151     value_ready_ (value_ready_mutex_)
00152 {
00153 }

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

Definition at line 156 of file Future.cpp.

00157 {
00158   delete this->value_;
00159 }


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 126 of file Future.cpp.

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

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

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 99 of file Future.cpp.

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

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

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 234 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().

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

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 84 of file Future.cpp.

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

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

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 109 of file Future.cpp.

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

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

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 254 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().

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

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_TEXT, 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_TEXT (" (NON-NULL)\n")));
00060   else
00061     //FUZZ: disable check_for_NULL
00062     ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NULL)\n")));
00063     //FUZZ: enable check_for_NULL
00064 
00065   ACE_DEBUG ((LM_INFO,"value_ready_: \n"));
00066   this->value_ready_.dump ();
00067   ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n"));
00068   this->value_ready_mutex_.dump ();
00069   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00070 #endif /* ACE_HAS_DUMP */
00071 }

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

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

Definition at line 209 of file Future.cpp.

References ACE_GUARD_RETURN, and ACE_Future_Rep< T >::value_ready_.

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

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

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 74 of file Future.cpp.

References ACE_NEW_RETURN.

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

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

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 264 of file Future.cpp.

References ACE_GUARD_RETURN, and ACE_Future_Rep< T >::value_ready_.

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

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

Is result available?

Definition at line 162 of file Future.cpp.

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

00163 {
00164   return this->value_ != 0;
00165 }

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 168 of file Future.cpp.

References ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_Unbounded_Set< T >::begin(), 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().

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


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 Sun Jan 27 12:54:50 2008 for ACE by doxygen 1.3.6