[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Future.cpp
blobe3693bd29b61440d12acb4af82194a3b31478280
1 // $Id: Future.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #ifndef ACE_FUTURE_CPP
4 #define ACE_FUTURE_CPP
6 #include "ace/Future.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
9 # pragma once
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
12 ACE_RCSID (ace, Future, "$Id: Future.cpp 80826 2008-03-04 14:51:23Z wotte $")
14 #if defined (ACE_HAS_THREADS)
16 # include "ace/Guard_T.h"
17 # include "ace/Recursive_Thread_Mutex.h"
19 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
21 template <class T>
22 ACE_Future_Holder<T>::ACE_Future_Holder (void)
26 template <class T>
27 ACE_Future_Holder<T>::ACE_Future_Holder (const ACE_Future<T> &item)
28 : item_ (item)
32 template <class T>
33 ACE_Future_Holder<T>::~ACE_Future_Holder (void)
37 template <class T>
38 ACE_Future_Observer<T>::ACE_Future_Observer (void)
42 template <class T>
43 ACE_Future_Observer<T>::~ACE_Future_Observer (void)
47 // Dump the state of an object.
49 template <class T> void
50 ACE_Future_Rep<T>::dump (void) const
52 #if defined (ACE_HAS_DUMP)
53 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
54 ACE_DEBUG ((LM_DEBUG,
55 "ref_count_ = %d\n",
56 (int) this->ref_count_));
57 ACE_DEBUG ((LM_INFO,"value_: \n"));
58 if (this->value_)
59 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NON-NULL)\n")));
60 else
61 //FUZZ: disable check_for_NULL
62 ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (NULL)\n")));
63 //FUZZ: enable check_for_NULL
65 ACE_DEBUG ((LM_INFO,"value_ready_: \n"));
66 this->value_ready_.dump ();
67 ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n"));
68 this->value_ready_mutex_.dump ();
69 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
70 #endif /* ACE_HAS_DUMP */
73 template <class T> ACE_Future_Rep<T> *
74 ACE_Future_Rep<T>::internal_create (void)
76 ACE_Future_Rep<T> *temp = 0;
77 ACE_NEW_RETURN (temp,
78 ACE_Future_Rep<T> (),
79 0);
80 return temp;
83 template <class T> ACE_Future_Rep<T> *
84 ACE_Future_Rep<T>::create (void)
86 // Yes set ref count to zero.
87 ACE_Future_Rep<T> *temp = internal_create ();
88 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
89 if (temp == 0)
90 ACE_throw_bad_alloc;
91 #else
92 ACE_ASSERT (temp != 0);
93 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
94 return temp;
98 template <class T> ACE_Future_Rep<T> *
99 ACE_Future_Rep<T>::attach (ACE_Future_Rep<T>*& rep)
101 ACE_ASSERT (rep != 0);
102 // Use value_ready_mutex_ for both condition and ref count management
103 ACE_MT (ACE_Guard<ACE_Recursive_Thread_Mutex> r_mon (rep->value_ready_mutex_));
104 ++rep->ref_count_;
105 return rep;
108 template <class T> void
109 ACE_Future_Rep<T>::detach (ACE_Future_Rep<T>*& rep)
111 ACE_ASSERT (rep != 0);
112 // Use value_ready_mutex_ for both condition and ref count management
113 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_));
115 if (rep->ref_count_-- == 0)
117 ACE_MT (r_mon.release ());
118 // We do not need the lock when deleting the representation.
119 // There should be no side effects from deleting rep and we don
120 // not want to release a deleted mutex.
121 delete rep;
125 template <class T> void
126 ACE_Future_Rep<T>::assign (ACE_Future_Rep<T>*& rep, ACE_Future_Rep<T>* new_rep)
128 ACE_ASSERT (rep != 0);
129 ACE_ASSERT (new_rep != 0);
130 // Use value_ready_mutex_ for both condition and ref count management
131 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, r_mon, rep->value_ready_mutex_));
133 ACE_Future_Rep<T>* old = rep;
134 rep = new_rep;
136 // detached old last for exception safety
137 if (old->ref_count_-- == 0)
139 ACE_MT (r_mon.release ());
140 // We do not need the lock when deleting the representation.
141 // There should be no side effects from deleting rep and we don
142 // not want to release a deleted mutex.
143 delete old;
147 template <class T>
148 ACE_Future_Rep<T>::ACE_Future_Rep (void)
149 : value_ (0),
150 ref_count_ (0),
151 value_ready_ (value_ready_mutex_)
155 template <class T>
156 ACE_Future_Rep<T>::~ACE_Future_Rep (void)
158 delete this->value_;
161 template <class T> int
162 ACE_Future_Rep<T>::ready (void) const
164 return this->value_ != 0;
167 template <class T> int
168 ACE_Future_Rep<T>::set (const T &r,
169 ACE_Future<T> &caller)
171 // If the value is already produced, ignore it...
172 if (this->value_ == 0)
174 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
175 ace_mon,
176 this->value_ready_mutex_,
177 -1));
178 // Otherwise, create a new result value. Note the use of the
179 // Double-checked locking pattern to avoid multiple allocations.
181 if (this->value_ == 0) // Still no value, so proceed
183 ACE_NEW_RETURN (this->value_,
184 T (r),
185 -1);
187 // Remove and notify all subscribed observers.
188 typename OBSERVER_COLLECTION::iterator iterator =
189 this->observer_collection_.begin ();
191 typename OBSERVER_COLLECTION::iterator end =
192 this->observer_collection_.end ();
194 while (iterator != end)
196 OBSERVER *observer = *iterator++;
197 observer->update (caller);
200 // Signal all the waiting threads.
201 return this->value_ready_.broadcast ();
203 // Destructor releases the lock.
205 return 0;
208 template <class T> int
209 ACE_Future_Rep<T>::get (T &value,
210 ACE_Time_Value *tv) const
212 // If the value is already produced, return it.
213 if (this->value_ == 0)
215 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
216 this->value_ready_mutex_,
217 -1));
218 // If the value is not yet defined we must block until the
219 // producer writes to it.
221 while (this->value_ == 0)
222 // Perform a timed wait.
223 if (this->value_ready_.wait (tv) == -1)
224 return -1;
226 // Destructor releases the lock.
229 value = *this->value_;
230 return 0;
233 template <class T> int
234 ACE_Future_Rep<T>::attach (ACE_Future_Observer<T> *observer,
235 ACE_Future<T> &caller)
237 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
239 // Otherwise, create a new result value. Note the use of the
240 // Double-checked locking pattern to avoid corrupting the list.
242 int result = 1;
244 // If the value is already produced, then notify observer
245 if (this->value_ == 0)
246 result = this->observer_collection_.insert (observer);
247 else
248 observer->update (caller);
250 return result;
253 template <class T> int
254 ACE_Future_Rep<T>::detach (ACE_Future_Observer<T> *observer)
256 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1));
258 // Remove all occurrences of the specified observer from this
259 // objects hash map.
260 return this->observer_collection_.remove (observer);
263 template <class T>
264 ACE_Future_Rep<T>::operator T ()
266 // If the value is already produced, return it.
267 if (this->value_ == 0)
269 // Constructor of ace_mon acquires the mutex.
270 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0));
272 // If the value is not yet defined we must block until the
273 // producer writes to it.
275 // Wait ``forever.''
277 while (this->value_ == 0)
278 if (this->value_ready_.wait () == -1)
279 // What to do in this case since we've got to indicate
280 // failure somehow? Exceptions would be nice, but they're
281 // not portable...
282 return 0;
284 // Destructor releases the mutex
287 return *this->value_;
290 template <class T>
291 ACE_Future<T>::ACE_Future (void)
292 : future_rep_ (FUTURE_REP::create ())
296 template <class T>
297 ACE_Future<T>::ACE_Future (const ACE_Future<T> &r)
298 : future_rep_ (FUTURE_REP::attach (((ACE_Future<T> &) r).future_rep_))
302 template <class T>
303 ACE_Future<T>::ACE_Future (const T &r)
304 : future_rep_ (FUTURE_REP::create ())
306 this->future_rep_->set (r, *this);
309 template <class T>
310 ACE_Future<T>::~ACE_Future (void)
312 FUTURE_REP::detach (future_rep_);
315 template <class T> bool
316 ACE_Future<T>::operator== (const ACE_Future<T> &r) const
318 return r.future_rep_ == this->future_rep_;
321 template <class T> bool
322 ACE_Future<T>::operator!= (const ACE_Future<T> &r) const
324 return r.future_rep_ != this->future_rep_;
327 template <class T> int
328 ACE_Future<T>::cancel (const T &r)
330 this->cancel ();
331 return this->future_rep_->set (r,
332 *this);
335 template <class T> int
336 ACE_Future<T>::cancel (void)
338 // If this ACE_Future is already attached to a ACE_Future_Rep,
339 // detach it (maybe delete the ACE_Future_Rep).
340 FUTURE_REP::assign (this->future_rep_,
341 FUTURE_REP::create ());
342 return 0;
345 template <class T> int
346 ACE_Future<T>::set (const T &r)
348 // Give the pointer to the result to the ACE_Future_Rep.
349 return this->future_rep_->set (r,
350 *this);
353 template <class T> int
354 ACE_Future<T>::ready (void) const
356 // We're ready if the ACE_Future_rep is ready...
357 return this->future_rep_->ready ();
360 template <class T> int
361 ACE_Future<T>::get (T &value,
362 ACE_Time_Value *tv) const
364 // We return the ACE_Future_rep.
365 return this->future_rep_->get (value, tv);
368 template <class T> int
369 ACE_Future<T>::attach (ACE_Future_Observer<T> *observer)
371 return this->future_rep_->attach (observer, *this);
374 template <class T> int
375 ACE_Future<T>::detach (ACE_Future_Observer<T> *observer)
377 return this->future_rep_->detach (observer);
380 template <class T>
381 ACE_Future<T>::operator T ()
383 // note that this will fail (and COREDUMP!)
384 // if future_rep_ == 0 !
386 // but...
387 // this is impossible unless somebody is so stupid to
388 // try something like this:
390 // Future<T> futT;
391 // T t;
392 // t = futT;
394 // perform type conversion on Future_Rep.
395 return *future_rep_;
398 template <class T> void
399 ACE_Future<T>::operator = (const ACE_Future<T> &rhs)
401 // assignment:
403 // bind <this> to the same <ACE_Future_Rep> as <r>.
405 // This will work if &r == this, by first increasing the ref count
406 ACE_Future<T> &r = (ACE_Future<T> &) rhs;
407 FUTURE_REP::assign (this->future_rep_,
408 FUTURE_REP::attach (r.future_rep_));
411 template <class T> void
412 ACE_Future<T>::dump (void) const
414 #if defined (ACE_HAS_DUMP)
415 ACE_DEBUG ((LM_DEBUG,
416 ACE_BEGIN_DUMP, this));
418 if (this->future_rep_)
419 this->future_rep_->dump ();
421 ACE_DEBUG ((LM_DEBUG,
422 ACE_END_DUMP));
423 #endif /* ACE_HAS_DUMP */
426 template <class T> ACE_Future_Rep<T> *
427 ACE_Future<T>::get_rep ()
429 return this->future_rep_;
432 ACE_END_VERSIONED_NAMESPACE_DECL
434 #endif /* ACE_HAS_THREADS */
436 #endif /* ACE_FUTURE_CPP */