diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-05-27 12:52:06 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-05-27 12:52:06 +0000 |
commit | b4e3fef03d183a68232fbdbb82b6f921a22f9904 (patch) | |
tree | c036b0bef35ee43ca10cbbc17133b29d040d326f /ace/Future.cpp | |
parent | e5a421561aa1bd63cff5862d25138bc20dcf89c6 (diff) | |
download | ATCD-b4e3fef03d183a68232fbdbb82b6f921a22f9904.tar.gz |
*** empty log message ***
Diffstat (limited to 'ace/Future.cpp')
-rw-r--r-- | ace/Future.cpp | 100 |
1 files changed, 51 insertions, 49 deletions
diff --git a/ace/Future.cpp b/ace/Future.cpp index d240a9adc42..2e77d001ba4 100644 --- a/ace/Future.cpp +++ b/ace/Future.cpp @@ -17,8 +17,8 @@ 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_)); + "ref_count_ = %d\n", + (int) this->ref_count_)); ACE_DEBUG ((LM_INFO,"value_: \n")); if (this->value_) ACE_DEBUG ((LM_DEBUG," (NON-NULL)\n")); @@ -36,35 +36,58 @@ template <class T> ACE_Future_Rep<T> * ACE_Future_Rep<T>::create (void) { // Yes set ref count to zero. - ACE_NEW_RETURN (((ACE_Future<T> *) this)->future_rep_, ACE_Future_Rep<T>, 0); + return new ACE_Future_Rep<T>(); } template <class T> ACE_Future_Rep<T> * -ACE_Future_Rep<T>::attach (ACE_Future_Rep<T> *rep) +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, (ACE_Thread_Mutex &) rep->value_ready_mutex_)); + 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_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, (ACE_Thread_Mutex &) rep->value_ready_mutex_)); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, rep->value_ready_mutex_)); if (rep->ref_count_-- == 0) { r_mon.release (); // We do not need the lock when deleting the representation. - // There should be no side effects from deleting rep. + // 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) + { + 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), @@ -96,7 +119,7 @@ ACE_Future_Rep<T>::set (const T &r) // Double-checked locking pattern to avoid multiple allocations. if (this->value_ == 0) - ACE_NEW_RETURN (this->value_, T (r), -1); + ACE_NEW_RETURN (this->value_, T (r), -1); // Signal all the waiting threads. return this->value_ready_.broadcast (); @@ -108,7 +131,7 @@ ACE_Future_Rep<T>::set (const T &r) template <class T> int ACE_Future_Rep<T>::get (T &value, - ACE_Time_Value *tv) + ACE_Time_Value *tv) { // If the value is already produced, return it. if (this->value_ == 0) @@ -119,9 +142,9 @@ ACE_Future_Rep<T>::get (T &value, // producer writes to it. while (this->value_ == 0) - // Perform a timed wait. - if (this->value_ready_.wait (tv) == -1) - return -1; + // Perform a timed wait. + if (this->value_ready_.wait (tv) == -1) + return -1; // Destructor releases the lock. } @@ -145,11 +168,11 @@ ACE_Future_Rep<T>::operator T () // 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; + 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 } @@ -174,15 +197,13 @@ ACE_Future<T>::ACE_Future (const T &r) : future_rep_ (Future_Rep::create ()) { ACE_DEBUG ((LM_DEBUG," (%t) funny constructor\n")); - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); this->future_rep_->set (r); } template <class T> ACE_Future<T>::~ACE_Future (void) { - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); - Future_Rep::detach (future_rep_); + FUTURE_REP::detach (future_rep_); } template <class T> int @@ -204,17 +225,13 @@ ACE_Future<T>::cancel (const T &r) return this->future_rep_->set (r); } -template <class T> void +template <class T> int ACE_Future<T>::cancel (void) -{ - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->mutex_, -1)); - +{ // If this ACE_Future is already attached to a ACE_Future_Rep, // detach it (maybe delete the ACE_Future_Rep). - Future_Rep *new_rep (Future_Rep::create ()); - Future_Rep *old_rep (this->future_rep_); - this->future_rep_ = new_rep; - Future_Rep::detach (old_rep); + FUTURE_REP::assign (this->future_rep_, FUTURE_REP::create ()); + return 0; } template <class T> int @@ -233,8 +250,6 @@ ACE_Future<T>::ready (void) template <class T> int ACE_Future<T>::get (T &value, ACE_Time_Value *tv) { - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->mutex_, -1)); - // We return the ACE_Future_rep. return this->future_rep_->get (value, tv); } @@ -258,27 +273,16 @@ ACE_Future<T>::operator T () } template <class T> void -ACE_Future<T>::operator = (const ACE_Future<T> &r) +ACE_Future<T>::operator = (const ACE_Future<T> &rhs) { // assignment: // // bind <this> to the same <ACE_Future_Rep> as <r>. - Future_Rep *new_rep = 0; - { - // This will work if &r == this - // and if not it will keep the r.mutex_ locked for as little - // time as possible - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, r.mutex_)); - new_rep = Future_Rep::attach (r.future_rep_); - } - - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); - - Future_Rep *old_rep = this->future_rep_; - this->future_rep_ = new_rep; - // Setup the new rep before detaching old rep for exception safety. - Future_Rep::detach (old_rep); + // 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 @@ -288,8 +292,6 @@ ACE_Future<T>::dump (void) const if (this->future_rep_) this->future_rep_->dump (); - - this->mutex_.dump (); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } |