summaryrefslogtreecommitdiff
path: root/ace/Future.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Future.cpp')
-rw-r--r--ace/Future.cpp100
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));
}