00001
00002
00003 #ifndef ACE_FUTURE_CPP
00004 #define ACE_FUTURE_CPP
00005
00006 #include "ace/Future.h"
00007
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif
00011
00012 ACE_RCSID (ace, Future, "$Id: Future.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00013
00014 #if defined (ACE_HAS_THREADS)
00015
00016 # include "ace/Guard_T.h"
00017 # include "ace/Recursive_Thread_Mutex.h"
00018
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020
00021 template <class T>
00022 ACE_Future_Holder<T>::ACE_Future_Holder (void)
00023 {
00024 }
00025
00026 template <class T>
00027 ACE_Future_Holder<T>::ACE_Future_Holder (const ACE_Future<T> &item)
00028 : item_ (item)
00029 {
00030 }
00031
00032 template <class T>
00033 ACE_Future_Holder<T>::~ACE_Future_Holder (void)
00034 {
00035 }
00036
00037 template <class T>
00038 ACE_Future_Observer<T>::ACE_Future_Observer (void)
00039 {
00040 }
00041
00042 template <class T>
00043 ACE_Future_Observer<T>::~ACE_Future_Observer (void)
00044 {
00045 }
00046
00047
00048
00049 template <class T> void
00050 ACE_Future_Rep<T>::dump (void) const
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
00062 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NULL)\n")));
00063
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
00071 }
00072
00073 template <class T> ACE_Future_Rep<T> *
00074 ACE_Future_Rep<T>::internal_create (void)
00075 {
00076 ACE_Future_Rep<T> *temp = 0;
00077 ACE_NEW_RETURN (temp,
00078 ACE_Future_Rep<T> (),
00079 0);
00080 return temp;
00081 }
00082
00083 template <class T> ACE_Future_Rep<T> *
00084 ACE_Future_Rep<T>::create (void)
00085 {
00086
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
00094 return temp;
00095 }
00096
00097
00098 template <class T> ACE_Future_Rep<T> *
00099 ACE_Future_Rep<T>::attach (ACE_Future_Rep<T>*& rep)
00100 {
00101 ACE_ASSERT (rep != 0);
00102
00103 ACE_MT (ACE_Guard<ACE_Recursive_Thread_Mutex> r_mon (rep->value_ready_mutex_));
00104 ++rep->ref_count_;
00105 return rep;
00106 }
00107
00108 template <class T> void
00109 ACE_Future_Rep<T>::detach (ACE_Future_Rep<T>*& rep)
00110 {
00111 ACE_ASSERT (rep != 0);
00112
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
00119
00120
00121 delete rep;
00122 }
00123 }
00124
00125 template <class T> void
00126 ACE_Future_Rep<T>::assign (ACE_Future_Rep<T>*& rep, ACE_Future_Rep<T>* new_rep)
00127 {
00128 ACE_ASSERT (rep != 0);
00129 ACE_ASSERT (new_rep != 0);
00130
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
00137 if (old->ref_count_-- == 0)
00138 {
00139 ACE_MT (r_mon.release ());
00140
00141
00142
00143 delete old;
00144 }
00145 }
00146
00147 template <class T>
00148 ACE_Future_Rep<T>::ACE_Future_Rep (void)
00149 : value_ (0),
00150 ref_count_ (0),
00151 value_ready_ (value_ready_mutex_)
00152 {
00153 }
00154
00155 template <class T>
00156 ACE_Future_Rep<T>::~ACE_Future_Rep (void)
00157 {
00158 delete this->value_;
00159 }
00160
00161 template <class T> int
00162 ACE_Future_Rep<T>::ready (void) const
00163 {
00164 return this->value_ != 0;
00165 }
00166
00167 template <class T> int
00168 ACE_Future_Rep<T>::set (const T &r,
00169 ACE_Future<T> &caller)
00170 {
00171
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
00179
00180
00181 if (this->value_ == 0)
00182 {
00183 ACE_NEW_RETURN (this->value_,
00184 T (r),
00185 -1);
00186
00187
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
00201 return this->value_ready_.broadcast ();
00202 }
00203
00204 }
00205 return 0;
00206 }
00207
00208 template <class T> int
00209 ACE_Future_Rep<T>::get (T &value,
00210 ACE_Time_Value *tv) const
00211 {
00212
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
00219
00220
00221 while (this->value_ == 0)
00222
00223 if (this->value_ready_.wait (tv) == -1)
00224 return -1;
00225
00226
00227 }
00228
00229 value = *this->value_;
00230 return 0;
00231 }
00232
00233 template <class T> int
00234 ACE_Future_Rep<T>::attach (ACE_Future_Observer<T> *observer,
00235 ACE_Future<T> &caller)
00236 {
00237 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
00238
00239
00240
00241
00242 int result = 1;
00243
00244
00245 if (this->value_ == 0)
00246 result = this->observer_collection_.insert (observer);
00247 else
00248 observer->update (caller);
00249
00250 return result;
00251 }
00252
00253 template <class T> int
00254 ACE_Future_Rep<T>::detach (ACE_Future_Observer<T> *observer)
00255 {
00256 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
00257
00258
00259
00260 return this->observer_collection_.remove (observer);
00261 }
00262
00263 template <class T>
00264 ACE_Future_Rep<T>::operator T ()
00265 {
00266
00267 if (this->value_ == 0)
00268 {
00269
00270 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0));
00271
00272
00273
00274
00275
00276
00277 while (this->value_ == 0)
00278 if (this->value_ready_.wait () == -1)
00279
00280
00281
00282 return 0;
00283
00284
00285 }
00286
00287 return *this->value_;
00288 }
00289
00290 template <class T>
00291 ACE_Future<T>::ACE_Future (void)
00292 : future_rep_ (FUTURE_REP::create ())
00293 {
00294 }
00295
00296 template <class T>
00297 ACE_Future<T>::ACE_Future (const ACE_Future<T> &r)
00298 : future_rep_ (FUTURE_REP::attach (((ACE_Future<T> &) r).future_rep_))
00299 {
00300 }
00301
00302 template <class T>
00303 ACE_Future<T>::ACE_Future (const T &r)
00304 : future_rep_ (FUTURE_REP::create ())
00305 {
00306 this->future_rep_->set (r, *this);
00307 }
00308
00309 template <class T>
00310 ACE_Future<T>::~ACE_Future (void)
00311 {
00312 FUTURE_REP::detach (future_rep_);
00313 }
00314
00315 template <class T> bool
00316 ACE_Future<T>::operator== (const ACE_Future<T> &r) const
00317 {
00318 return r.future_rep_ == this->future_rep_;
00319 }
00320
00321 template <class T> bool
00322 ACE_Future<T>::operator!= (const ACE_Future<T> &r) const
00323 {
00324 return r.future_rep_ != this->future_rep_;
00325 }
00326
00327 template <class T> int
00328 ACE_Future<T>::cancel (const T &r)
00329 {
00330 this->cancel ();
00331 return this->future_rep_->set (r,
00332 *this);
00333 }
00334
00335 template <class T> int
00336 ACE_Future<T>::cancel (void)
00337 {
00338
00339
00340 FUTURE_REP::assign (this->future_rep_,
00341 FUTURE_REP::create ());
00342 return 0;
00343 }
00344
00345 template <class T> int
00346 ACE_Future<T>::set (const T &r)
00347 {
00348
00349 return this->future_rep_->set (r,
00350 *this);
00351 }
00352
00353 template <class T> int
00354 ACE_Future<T>::ready (void) const
00355 {
00356
00357 return this->future_rep_->ready ();
00358 }
00359
00360 template <class T> int
00361 ACE_Future<T>::get (T &value,
00362 ACE_Time_Value *tv) const
00363 {
00364
00365 return this->future_rep_->get (value, tv);
00366 }
00367
00368 template <class T> int
00369 ACE_Future<T>::attach (ACE_Future_Observer<T> *observer)
00370 {
00371 return this->future_rep_->attach (observer, *this);
00372 }
00373
00374 template <class T> int
00375 ACE_Future<T>::detach (ACE_Future_Observer<T> *observer)
00376 {
00377 return this->future_rep_->detach (observer);
00378 }
00379
00380 template <class T>
00381 ACE_Future<T>::operator T ()
00382 {
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 return *future_rep_;
00396 }
00397
00398 template <class T> void
00399 ACE_Future<T>::operator = (const ACE_Future<T> &rhs)
00400 {
00401
00402
00403
00404
00405
00406 ACE_Future<T> &r = (ACE_Future<T> &) rhs;
00407 FUTURE_REP::assign (this->future_rep_,
00408 FUTURE_REP::attach (r.future_rep_));
00409 }
00410
00411 template <class T> void
00412 ACE_Future<T>::dump (void) const
00413 {
00414 #if defined (ACE_HAS_DUMP)
00415 ACE_DEBUG ((LM_DEBUG,
00416 ACE_BEGIN_DUMP, this));
00417
00418 if (this->future_rep_)
00419 this->future_rep_->dump ();
00420
00421 ACE_DEBUG ((LM_DEBUG,
00422 ACE_END_DUMP));
00423 #endif
00424 }
00425
00426 template <class T> ACE_Future_Rep<T> *
00427 ACE_Future<T>::get_rep ()
00428 {
00429 return this->future_rep_;
00430 }
00431
00432 ACE_END_VERSIONED_NAMESPACE_DECL
00433
00434 #endif
00435
00436 #endif