// Future.cpp // $Id$ #define ACE_BUILD_DLL #ifndef ACE_FUTURE_SET_CPP #define ACE_FUTURE_SET_CPP #include /**/ "ace/Future_Set.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ ACE_RCSID (ace, Future_Set, "$Id$") #if defined (ACE_HAS_THREADS) template ACE_Future_Set::ACE_Future_Set (ACE_Message_Queue *new_queue) : delete_queue_ (0) { if (new_queue) this->future_notification_queue_ = new_queue; else { ACE_NEW (this->future_notification_queue_, ACE_Message_Queue); this->delete_queue_ = 1; } } template ACE_Future_Set::~ACE_Future_Set (void) { // Detach ourselves from all remaining futures, if any, in our map. ACE_TYPENAME FUTURE_HASH_MAP::iterator iterator = this->future_map_.begin (); ACE_TYPENAME FUTURE_HASH_MAP::iterator end = this->future_map_.end (); for (; iterator != end; ++iterator) { FUTURE_HOLDER *future_holder = (*iterator).int_id_; future_holder->item_.detach (this); delete future_holder; } if (this->delete_queue_ != 0) delete this->future_notification_queue_; } template int ACE_Future_Set::is_empty () const { return (((ACE_Future_Set*)this)->future_map_.current_size () == 0 ); } template int ACE_Future_Set::insert (ACE_Future &future) { FUTURE_HOLDER *future_holder; ACE_NEW_RETURN (future_holder, FUTURE_HOLDER (future), -1); FUTURE_REP *future_rep = future.get_rep (); int result = this->future_map_.bind (future_rep, future_holder); // If a new map entry was created, then attach to the future, // otherwise we were already attached to the future or some error // occurred so just delete the future holder. if ( result == 0 ) // Attach ourself to the ACE_Futures list of observer future.attach (this); else delete future_holder; return result; } template void ACE_Future_Set::update (const ACE_Future &future) { ACE_Message_Block *mb; FUTURE &local_future = ACE_const_cast (ACE_Future &, future); ACE_NEW (mb, ACE_Message_Block ((char *) local_future.get_rep (), 0)); // Enqueue in priority order. this->future_notification_queue_->enqueue (mb, 0); } template int ACE_Future_Set::next_readable (ACE_Future &future, ACE_Time_Value *tv) { if (this->is_empty ()) return 0; ACE_Message_Block *mb = 0; FUTURE_REP *future_rep = 0; // Wait for a "readable future" signal from the message queue. if (this->future_notification_queue_->dequeue_head (mb, tv) != -1) { // Extract future rep from the message block. future_rep = ACE_reinterpret_cast (FUTURE_REP *, mb->base ()); // Delete the message block. mb->release (); } else return 0; // Remove the hash map entry with the specified future rep from our map. FUTURE_HOLDER *future_holder; if ( this->future_map_.find (future_rep, future_holder) != -1 ) { future = future_holder->item_; this->future_map_.unbind (future_rep); delete future_holder; return 1; } return 0; } #endif /* ACE_HAS_THREADS */ #endif /* ACE_FUTURE_SET_CPP */