#include <Future.h>
Collaboration diagram for ACE_Future_Rep< T >:
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 > |
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.
|
Definition at line 211 of file Future.h. Referenced by ACE_Future_Rep< T >::set(). |
|
|
|
Definition at line 148 of file Future.cpp.
00149 : value_ (0), 00150 ref_count_ (0), 00151 value_ready_ (value_ready_mutex_) 00152 { 00153 } |
|
Definition at line 156 of file Future.cpp.
00157 { 00158 delete this->value_; 00159 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Is result available?
Definition at line 162 of file Future.cpp. Referenced by ACE_Future< T >::ready().
00163 { 00164 return this->value_ != 0; 00165 } |
|
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 } |
|
|
|
Declare the dynamic allocation hooks.
|
|
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(). |
|
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(). |
|
Pointer to the result.
|
|
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(). |
|
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(). |