diff options
Diffstat (limited to 'ace/Future.cpp')
-rw-r--r-- | ace/Future.cpp | 425 |
1 files changed, 0 insertions, 425 deletions
diff --git a/ace/Future.cpp b/ace/Future.cpp deleted file mode 100644 index f70f8df83bb..00000000000 --- a/ace/Future.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// $Id$ - -#ifndef ACE_FUTURE_CPP -#define ACE_FUTURE_CPP - -#include "ace/Future.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -ACE_RCSID (ace, Future, "$Id$") - -#if defined (ACE_HAS_THREADS) - -template <class T> -ACE_Future_Holder<T>::ACE_Future_Holder (void) -{ -} - -template <class T> -ACE_Future_Holder<T>::ACE_Future_Holder (const ACE_Future<T> &item) - : item_ (item) -{ -} - -template <class T> -ACE_Future_Holder<T>::~ACE_Future_Holder (void) -{ -} - -template <class T> -ACE_Future_Observer<T>::ACE_Future_Observer (void) -{ -} - -template <class T> -ACE_Future_Observer<T>::~ACE_Future_Observer (void) -{ -} - -// Dump the state of an object. - -template <class T> void -ACE_Future_Rep<T>::dump (void) const -{ - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, - "ref_count_ = %d\n", - (int) this->ref_count_)); - ACE_DEBUG ((LM_INFO,"value_: \n")); - if (this->value_) - ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NON-NULL)\n"))); - else - ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NULL)\n"))); - - ACE_DEBUG ((LM_INFO,"value_ready_: \n")); - this->value_ready_.dump (); - ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n")); - this->value_ready_mutex_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -template <class T> ACE_Future_Rep<T> * -ACE_Future_Rep<T>::create (void) -{ - // Yes set ref count to zero. - return new ACE_Future_Rep<T> (); -} - -template <class T> ACE_Future_Rep<T> * -ACE_Future_Rep<T>::attach (ACE_Future_Rep<T>*& rep) -{ - ACE_ASSERT (rep != 0); - // Use value_ready_mutex_ for both condition and ref count management - ACE_MT (ACE_Guard<ACE_Thread_Mutex> r_mon (rep->value_ready_mutex_)); - ++rep->ref_count_; - return rep; -} - -template <class T> void -ACE_Future_Rep<T>::detach (ACE_Future_Rep<T>*& rep) -{ - ACE_ASSERT (rep != 0); - // Use value_ready_mutex_ for both condition and ref count management - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, rep->value_ready_mutex_)); - - if (rep->ref_count_-- == 0) - { - ACE_MT (r_mon.release ()); - // We do not need the lock when deleting the representation. - // There should be no side effects from deleting rep and we don - // not want to release a deleted mutex. - delete rep; - } -} - -template <class T> void -ACE_Future_Rep<T>::assign (ACE_Future_Rep<T>*& rep, ACE_Future_Rep<T>* new_rep) -{ - ACE_ASSERT (rep != 0); - ACE_ASSERT (new_rep != 0); - // Use value_ready_mutex_ for both condition and ref count management - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, rep->value_ready_mutex_)); - - ACE_Future_Rep<T>* old = rep; - rep = new_rep; - - // detached old last for exception safety - if (old->ref_count_-- == 0) - { - ACE_MT (r_mon.release ()); - // We do not need the lock when deleting the representation. - // There should be no side effects from deleting rep and we don - // not want to release a deleted mutex. - delete old; - } -} - -template <class T> -ACE_Future_Rep<T>::ACE_Future_Rep (void) - : value_ (0), - ref_count_ (0), - value_ready_ (this->value_ready_mutex_) -{ -} - -template <class T> -ACE_Future_Rep<T>::~ACE_Future_Rep (void) -{ - delete this->value_; -} - -template <class T> int -ACE_Future_Rep<T>::ready (void) -{ - return this->value_ != 0; -} - -template <class T> int -ACE_Future_Rep<T>::set (const T &r, - ACE_Future<T> &caller) -{ - // If the value is already produced, ignore it... - if (this->value_ == 0) - { - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); - // Otherwise, create a new result value. Note the use of the - // Double-checked locking pattern to avoid multiple allocations. - - if (this->value_ == 0) - ACE_NEW_RETURN (this->value_, - T (r), - -1); - - // Remove and notify all subscribed observers. - ACE_TYPENAME OBSERVER_COLLECTION::iterator iterator = - this->observer_collection_.begin (); - - ACE_TYPENAME OBSERVER_COLLECTION::iterator end = - this->observer_collection_.end (); - - for (; - iterator != end; - ++iterator) - { - OBSERVER *observer = *iterator; - observer->update (caller); - } - - // Signal all the waiting threads. - return this->value_ready_.broadcast (); - - // Destructor releases the lock. - } - return 0; -} - -template <class T> int -ACE_Future_Rep<T>::get (T &value, - ACE_Time_Value *tv) -{ - // If the value is already produced, return it. - if (this->value_ == 0) - { - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); - - // If the value is not yet defined we must block until the - // producer writes to it. - - while (this->value_ == 0) - // Perform a timed wait. - if (this->value_ready_.wait (tv) == -1) - return -1; - - // Destructor releases the lock. - } - - value = *this->value_; - return 0; -} - -template <class T> int -ACE_Future_Rep<T>::attach (ACE_Future_Observer<T> *observer, - ACE_Future<T> &caller) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); - - // Otherwise, create a new result value. Note the use of the - // Double-checked locking pattern to avoid corrupting the list. - - int result = 1; - - // If the value is already produced, then notify observer - if (this->value_ == 0) - { - result = this->observer_collection_.insert (observer); - } - else - observer->update (caller); - - return result; -} - -template <class T> int -ACE_Future_Rep<T>::detach (ACE_Future_Observer<T> *observer) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); - - // Remove all occurrences of the specified observer from this - // objects hash map. - return this->observer_collection_.remove (observer); -} - -template <class T> -ACE_Future_Rep<T>::operator T () -{ - // If the value is already produced, return it. - if (this->value_ == 0) - { - // Constructor of ace_mon acquires the mutex. - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0)); - - // If the value is not yet defined we must block until the - // producer writes to it. - - // Wait ``forever.'' - - while (this->value_ == 0) - if (this->value_ready_.wait () == -1) - // What to do in this case since we've got to indicate - // failure somehow? Exceptions would be nice, but they're - // not portable... - return 0; - - // Destructor releases the mutex - } - - return *this->value_; -} - -template <class T> -ACE_Future<T>::ACE_Future (void) - : future_rep_ (FUTURE_REP::create ()) -{ -} - -template <class T> -ACE_Future<T>::ACE_Future (const ACE_Future<T> &r) - : future_rep_ (FUTURE_REP::attach (((ACE_Future<T> &) r).future_rep_)) -{ -} - -template <class T> -ACE_Future<T>::ACE_Future (const T &r) - : future_rep_ (FUTURE_REP::create ()) -{ - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT (" (%t) funny constructor\n"))); - this->future_rep_->set (r, - *this); -} - -template <class T> -ACE_Future<T>::~ACE_Future (void) -{ - FUTURE_REP::detach (future_rep_); -} - -template <class T> int -ACE_Future<T>::operator== (const ACE_Future<T> &r) const -{ - return r.future_rep_ == this->future_rep_; -} - -template <class T> int -ACE_Future<T>::operator!= (const ACE_Future<T> &r) const -{ - return r.future_rep_ != this->future_rep_; -} - -template <class T> int -ACE_Future<T>::cancel (const T &r) -{ - this->cancel (); - return this->future_rep_->set (r, - *this); -} - -template <class T> int -ACE_Future<T>::cancel (void) -{ - // If this ACE_Future is already attached to a ACE_Future_Rep, - // detach it (maybe delete the ACE_Future_Rep). - FUTURE_REP::assign (this->future_rep_, - FUTURE_REP::create ()); - return 0; -} - -template <class T> int -ACE_Future<T>::set (const T &r) -{ - // Give the pointer to the result to the ACE_Future_Rep. - return this->future_rep_->set (r, - *this); -} - -template <class T> int -ACE_Future<T>::ready (void) -{ - // We're ready if the ACE_Future_rep is ready... - return this->future_rep_->ready (); -} - -template <class T> int -ACE_Future<T>::get (T &value, - ACE_Time_Value *tv) -{ - // We return the ACE_Future_rep. - return this->future_rep_->get (value, tv); -} - -template <class T> int -ACE_Future<T>::attach (ACE_Future_Observer<T> *observer) -{ - return this->future_rep_->attach (observer, *this); -} - -template <class T> int -ACE_Future<T>::detach (ACE_Future_Observer<T> *observer) -{ - return this->future_rep_->detach (observer); -} - -template <class T> -ACE_Future<T>::operator T () -{ - // note that this will fail (and COREDUMP!) - // if future_rep_ == 0 ! - // - // but... - // this is impossible unless somebody is so stupid to - // try something like this: - // - // Future<T> futT; - // T t; - // t = futT; - - // perform type conversion on Future_Rep. - return *future_rep_; -} - -template <class T> void -ACE_Future<T>::operator = (const ACE_Future<T> &rhs) -{ - // assignment: - // - // bind <this> to the same <ACE_Future_Rep> as <r>. - - // This will work if &r == this, by first increasing the ref count - ACE_Future<T> &r = (ACE_Future<T> &) rhs; - FUTURE_REP::assign (this->future_rep_, - FUTURE_REP::attach (r.future_rep_)); -} - -template <class T> void -ACE_Future<T>::dump (void) const -{ - ACE_DEBUG ((LM_DEBUG, - ACE_BEGIN_DUMP, this)); - - if (this->future_rep_) - this->future_rep_->dump (); - - ACE_DEBUG ((LM_DEBUG, - ACE_END_DUMP)); -} - -template <class T> ACE_Future_Rep<T> * -ACE_Future<T>::get_rep () -{ - return this->future_rep_; -} - -template <class T> void * -ACE_Future<T>::operator new (size_t) -{ - ACE_throw_bad_alloc; -#if defined (__HP_aCC) - return 0; -#endif /* 0 */ -} - -template <class T> void -ACE_Future<T>::operator delete (void *) -{ -} - -template <class T> void -ACE_Future<T>::operator & () -{ -} - -#endif /* ACE_HAS_THREADS */ -#endif /* ACE_FUTURE_CPP */ |