diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1999-06-28 23:32:00 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1999-06-28 23:32:00 +0000 |
commit | 4091f79cfee193a77e2384a3a33dc38347ef6acb (patch) | |
tree | dbb1e00111aef87e5d662206ba1ec33f82724140 | |
parent | 2011599cafe9775821ac246ace3a84709f87642f (diff) | |
download | ATCD-4091f79cfee193a77e2384a3a33dc38347ef6acb.tar.gz |
.
-rw-r--r-- | ace/Active_Map_Manager_T.h | 4 | ||||
-rw-r--r-- | ace/Active_Map_Manager_T.i | 4 | ||||
-rw-r--r-- | ace/Cache_Map_Manager_T.h | 4 | ||||
-rw-r--r-- | ace/Cache_Map_Manager_T.i | 4 | ||||
-rw-r--r-- | ace/Future.cpp | 127 | ||||
-rw-r--r-- | ace/Future.h | 82 | ||||
-rw-r--r-- | ace/Future_Set.cpp | 96 | ||||
-rw-r--r-- | ace/Future_Set.h | 49 | ||||
-rw-r--r-- | ace/Hash_Map_Manager_T.h | 4 | ||||
-rw-r--r-- | ace/Hash_Map_Manager_T.i | 4 | ||||
-rw-r--r-- | ace/Map_Manager.h | 4 | ||||
-rw-r--r-- | ace/Map_Manager.i | 10 | ||||
-rw-r--r-- | ace/Map_T.h | 20 | ||||
-rw-r--r-- | ace/Map_T.i | 56 | ||||
-rw-r--r-- | ace/OS.i | 6 | ||||
-rw-r--r-- | tests/Future_Set_Test.cpp | 651 | ||||
-rw-r--r-- | tests/Future_Set_Test.dsp | 229 | ||||
-rw-r--r-- | tests/Future_Set_Test.dsw | 29 | ||||
-rw-r--r-- | tests/Makefile | 1 | ||||
-rw-r--r-- | tests/icc.bat | 1 | ||||
-rw-r--r-- | tests/run_tests.bat | 1 | ||||
-rwxr-xr-x | tests/run_tests.psosim | 3 | ||||
-rwxr-xr-x | tests/run_tests.sh | 3 | ||||
-rw-r--r-- | tests/run_tests.vxworks | 4 |
24 files changed, 1180 insertions, 216 deletions
diff --git a/ace/Active_Map_Manager_T.h b/ace/Active_Map_Manager_T.h index e0cb4f4fa8c..eda8383dc2c 100644 --- a/ace/Active_Map_Manager_T.h +++ b/ace/Active_Map_Manager_T.h @@ -142,10 +142,10 @@ public: // the map resizes or when this slot is reused. Therefore, the user // should use the pointer immediately and not hold on to it. - size_t current_size (void); + size_t current_size (void) const; // Return the current size of the map. - size_t total_size (void); + size_t total_size (void) const; // Return the total size of the map. static const ACE_Active_Map_Manager_Key npos (void); diff --git a/ace/Active_Map_Manager_T.i b/ace/Active_Map_Manager_T.i index 54388cd354d..29197057d0c 100644 --- a/ace/Active_Map_Manager_T.i +++ b/ace/Active_Map_Manager_T.i @@ -238,13 +238,13 @@ ACE_Active_Map_Manager<T>::close (void) } template <class T> ACE_INLINE size_t -ACE_Active_Map_Manager<T>::current_size (void) +ACE_Active_Map_Manager<T>::current_size (void) const { return ACE_AMM_BASE::current_size (); } template <class T> ACE_INLINE size_t -ACE_Active_Map_Manager<T>::total_size (void) +ACE_Active_Map_Manager<T>::total_size (void) const { return ACE_AMM_BASE::total_size (); } diff --git a/ace/Cache_Map_Manager_T.h b/ace/Cache_Map_Manager_T.h index 4cdde22e16d..ffa805ab9f8 100644 --- a/ace/Cache_Map_Manager_T.h +++ b/ace/Cache_Map_Manager_T.h @@ -165,10 +165,10 @@ public: int purge (void); // Remove entries from the cache depending upon the strategy. - size_t current_size (void); + size_t current_size (void) const; // Return the current size of the cache. - size_t total_size (void); + size_t total_size (void) const; // Return the total size of the cache. void dump (void) const; diff --git a/ace/Cache_Map_Manager_T.i b/ace/Cache_Map_Manager_T.i index d40ae9dd448..56813799419 100644 --- a/ace/Cache_Map_Manager_T.i +++ b/ace/Cache_Map_Manager_T.i @@ -11,13 +11,13 @@ ACE_Cache_Map_Manager<T_2>::purge (void) } template <T_1> ACE_INLINE size_t -ACE_Cache_Map_Manager<T_2>::current_size (void) +ACE_Cache_Map_Manager<T_2>::current_size (void) const { return this->map_.current_size (); } template <T_1> ACE_INLINE size_t -ACE_Cache_Map_Manager<T_2>::total_size (void) +ACE_Cache_Map_Manager<T_2>::total_size (void) const { return this->map_.total_size (); } diff --git a/ace/Future.cpp b/ace/Future.cpp index 84bed2825b9..51f00f74010 100644 --- a/ace/Future.cpp +++ b/ace/Future.cpp @@ -11,11 +11,27 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -ACE_RCSID(ace, Future, "$Id$") +ACE_RCSID (ace, Future, "$Id$") #if defined (ACE_HAS_THREADS) template <class T> +ACE_Future_Holder<T>::ACE_Future_Holder (void) +{ +} + +template <class T> +ACE_Future_Holder<T>::ACE_Future_Holder (const ACE_Future<T> &item) + : item_ (item) +{ +} + +template <class T> +ACE_Future_Holder<T>::~ACE_Future_Holder (void) +{ +} + +template <class T> ACE_Future_Observer<T>::ACE_Future_Observer (void) { } @@ -35,10 +51,10 @@ ACE_Future_Rep<T>::dump (void) const "ref_count_ = %d\n", (int) this->ref_count_)); ACE_DEBUG ((LM_INFO,"value_: \n")); - if(this->value_) + if (this->value_) ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (NON-NULL)\n"))); else - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (NULL)\n"))); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (NULL)\n"))); ACE_DEBUG ((LM_INFO,"value_ready_: \n")); this->value_ready_.dump (); @@ -51,7 +67,7 @@ template <class T> ACE_Future_Rep<T> * ACE_Future_Rep<T>::create (void) { // Yes set ref count to zero. - return new ACE_Future_Rep<T>(); + return new ACE_Future_Rep<T> (); } template <class T> ACE_Future_Rep<T> * @@ -59,7 +75,7 @@ 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(rep->value_ready_mutex_)); + ACE_MT (ACE_Guard<ACE_Thread_Mutex> r_mon (rep->value_ready_mutex_)); ++rep->ref_count_; return rep; } @@ -67,11 +83,11 @@ ACE_Future_Rep<T>::attach (ACE_Future_Rep<T>*& rep) template <class T> void ACE_Future_Rep<T>::detach (ACE_Future_Rep<T>*& rep) { - ACE_ASSERT(rep != 0); + ACE_ASSERT (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_)); - if(rep->ref_count_-- == 0) + if (rep->ref_count_-- == 0) { ACE_MT (r_mon.release ()); // We do not need the lock when deleting the representation. @@ -84,8 +100,8 @@ ACE_Future_Rep<T>::detach (ACE_Future_Rep<T>*& 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); + 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_)); @@ -93,7 +109,7 @@ ACE_Future_Rep<T>::assign (ACE_Future_Rep<T>*& rep, ACE_Future_Rep<T>* new_rep) rep = new_rep; // detached old last for exception safety - if(old->ref_count_-- == 0) + if (old->ref_count_-- == 0) { ACE_MT (r_mon.release ()); // We do not need the lock when deleting the representation. @@ -128,28 +144,31 @@ ACE_Future_Rep<T>::set (const T &r, ACE_Future<T> &caller) { // If the value is already produced, ignore it... - if(this->value_ == 0) + if (this->value_ == 0) { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); // Otherwise, create a new result value. Note the use of the // Double-checked locking pattern to avoid multiple allocations. - if(this->value_ == 0) + if (this->value_ == 0) ACE_NEW_RETURN (this->value_, T (r), -1); + OBSERVER_HASH_ENTRY *map_entry = 0; + // Remove and notify all subscribed observers. - for (OBSERVER_NODE *node = this->observer_list_.delete_head(); - node; - node = this->observer_list_.delete_head()) + + for (OBSERVER_HASH_ITERATOR map_iterator (this->observer_hash_); + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) { - OBSERVER *observer = ACE_reinterpret_cast (OBSERVER *, - node->item_); - delete node; + OBSERVER *observer = map_entry->int_id_; observer->update (caller); } + this->observer_hash_.close (); + // Signal all the waiting threads. return this->value_ready_.broadcast (); @@ -172,7 +191,7 @@ ACE_Future_Rep<T>::get (T &value, while (this->value_ == 0) // Perform a timed wait. - if(this->value_ready_.wait (tv) == -1) + if (this->value_ready_.wait (tv) == -1) return -1; // Destructor releases the lock. @@ -182,64 +201,46 @@ ACE_Future_Rep<T>::get (T &value, return 0; } -template <class T> void -ACE_Future_Rep<T>::attach(ACE_Future_Observer<T> *observer, +template <class T> int +ACE_Future_Rep<T>::attach (ACE_Future_Observer<T> *observer, ACE_Future<T> &caller) { - ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, this->value_ready_mutex_));; + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); // Otherwise, create a new result value. Note the use of the // Double-checked locking pattern to avoid corrupting the list. + int result = 1; + // If the value is already produced, then notify observer if (this->value_ == 0) { - OBSERVER_NODE *node; - ACE_NEW (node, - OBSERVER_NODE ((void *&) observer)); - - this->observer_list_.insert_tail (node); + OBSERVER_HASH_ADDR observer_hash_addr (observer); + result = this->observer_hash_.bind (observer_hash_addr, observer); } else - observer->update(caller); + observer->update (caller); + + return result; } template <class T> int -ACE_Future_Rep<T>::detach(ACE_Future_Observer<T> *observer) +ACE_Future_Rep<T>::detach (ACE_Future_Observer<T> *observer) { - ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0)); - - int result = 0; + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); // Remove all occurrences of the specified observer from this - // objects list. Note the use of the Double-checked locking pattern - // to avoid corrupting the list. - - OBSERVER_NODE *node = 0; - for (OBSERVER_LIST::ITERATOR iter (this->observer_list_); - (node = iter.next ()) != 0; - iter.advance ()) - { - OBSERVER *curr_observer = - ACE_reinterpret_cast (OBSERVER *, - node->item_); - - if (curr_observer == observer) - { - this->observer_list_.remove (node); - delete node; - result = 1; - } - } + // objects hash map. + OBSERVER_HASH_ADDR observer_hash_addr (observer); - return result; + return this->observer_hash_.unbind (observer_hash_addr); } template <class T> ACE_Future_Rep<T>::operator T () { // If the value is already produced, return it. - if(this->value_ == 0) + if (this->value_ == 0) { // Constructor of ace_mon acquires the mutex. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0)); @@ -264,13 +265,13 @@ ACE_Future_Rep<T>::operator T () template <class T> ACE_Future<T>::ACE_Future (void) -: future_rep_ (FUTURE_REP::create ()) + : future_rep_ (FUTURE_REP::create ()) { } template <class T> ACE_Future<T>::ACE_Future (const ACE_Future<T> &r) -: future_rep_ (FUTURE_REP::attach (((ACE_Future<T> &) r).future_rep_)) + : future_rep_ (FUTURE_REP::attach (( (ACE_Future<T> &) r).future_rep_)) { } @@ -343,14 +344,14 @@ ACE_Future<T>::get (T &value, return this->future_rep_->get (value, tv); } -template <class T> void -ACE_Future<T>::attach(ACE_Future_Observer<T> *observer) +template <class T> int +ACE_Future<T>::attach (ACE_Future_Observer<T> *observer) { - this->future_rep_->attach (observer, *this); + return this->future_rep_->attach (observer, *this); } template <class T> int -ACE_Future<T>::detach(ACE_Future_Observer<T> *observer) +ACE_Future<T>::detach (ACE_Future_Observer<T> *observer) { return this->future_rep_->detach (observer); } @@ -399,6 +400,12 @@ ACE_Future<T>::dump (void) const ACE_END_DUMP)); } +template <class T> ACE_Future_Rep<T> * +ACE_Future<T>::get_rep () +{ + return this->future_rep_; +} + template <class T> void * ACE_Future<T>::operator new (size_t) { @@ -411,7 +418,7 @@ ACE_Future<T>::operator delete (void *) } template <class T> void -ACE_Future<T>::operator &() +ACE_Future<T>::operator & () { } diff --git a/ace/Future.h b/ace/Future.h index 0a0cce0ba5f..95bfac25398 100644 --- a/ace/Future.h +++ b/ace/Future.h @@ -21,7 +21,8 @@ #define ACE_FUTURE_H #include "ace/Synch.h" -#include "ace/Containers_T.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/Strategies_T.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -30,8 +31,29 @@ #if defined (ACE_HAS_THREADS) // Forward decl. -template <class T> class ACE_Future; +template <class T> class ACE_Future_Holder; template <class T> class ACE_Future_Observer; +template <class T> class ACE_Future_Rep; +template <class T> class ACE_Future; + +template <class T> +class ACE_Export ACE_Future_Holder +{ + // = TITLE + // Implementation of object which has holds ACE_Future. + +public: + ACE_Future_Holder (const ACE_Future<T> &future); + ~ACE_Future_Holder (void); + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + ACE_Future<T> item_; + +protected: + ACE_Future_Holder (void); +}; template <class T> class ACE_Future_Observer @@ -76,13 +98,9 @@ class ACE_Future_Rep private: friend class ACE_Future<T>; -#if defined (__BORLANDC__) && (__BORLANDC__ == 0x540) - static void unimplemented_method_inserted_to_get_around_bcb_4_bug(); -#endif /* (__BORLANDC__) && (__BORLANDC__ == 0x540) */ - - // <create>, <attach>, <detach>, and <assign> encapsulates the - // reference count handling and the object lifetime of - // ACE_Future_Rep<T> instances. + // Create, attach, detach and assign encapsulates the reference + // count handling and the object lifetime of ACE_Future_Rep<T> + // instances. static ACE_Future_Rep<T> *create (void); // Create a ACE_Future_Rep<T> and initialize the reference count. @@ -91,20 +109,20 @@ private: // Increase the reference count and return argument. Uses the // attribute "value_ready_mutex_" to synchronize reference count // updating. - // + // // Precondition(rep != 0). static void detach (ACE_Future_Rep<T> *&rep); // Decreases the reference count and and deletes rep if there are no // more references to rep. - // + // // Precondition(rep != 0) static void assign (ACE_Future_Rep<T> *&rep, ACE_Future_Rep<T> *new_rep); // Decreases the rep's reference count and and deletes rep if there // are no more references to rep. Then assigns new_rep to rep. - // + // // Precondition(rep != 0 && new_rep != 0) int set (const T &r, @@ -118,12 +136,15 @@ private: // Wait up to <tv> time to get the <value>. Note that <tv> must be // specified in absolute time rather than relative time. - void attach (ACE_Future_Observer<T> *observer, + int attach (ACE_Future_Observer<T> *observer, ACE_Future<T> &caller); // Attaches the specified observer to a subject (i.e. the // ACE_Future_Rep). The update method of the specified subject will // be invoked with a copy of the written-to ACE_Future as input when // the result gets set. + // + // Returns 0 if the observer is successfully attached, 1 if the + // observer is already attached, and -1 if failures occur. int detach (ACE_Future_Observer<T> *observer); // Detaches the specified observer from a subject (i.e. the @@ -131,6 +152,9 @@ private: // not be invoked when the ACE_Future_Reps result gets set. Returns // 1 if the specified observer was actually attached to the subject // prior to this call and 0 if was not. + // + // Returns 0 if the observer was successfully detached, and -1 if the observer was + // not attached in the first place. operator T (); // Type conversion. will block forever until the result is @@ -160,11 +184,22 @@ private: int ref_count_; // Reference count. - typedef ACE_Future_Observer<T> OBSERVER; - typedef ACE_DLList_Node OBSERVER_NODE; - typedef ACE_Double_Linked_List<OBSERVER_NODE> OBSERVER_LIST; + typedef ACE_Future_Observer<T> + OBSERVER; - OBSERVER_LIST observer_list_; + typedef ACE_Hash_Addr<OBSERVER*> + OBSERVER_HASH_ADDR; + + typedef ACE_Hash_Map_Manager<OBSERVER_HASH_ADDR, OBSERVER *, ACE_Null_Mutex> + OBSERVER_HASH; + + typedef ACE_Hash_Map_Iterator<OBSERVER_HASH_ADDR, OBSERVER *, ACE_Null_Mutex> + OBSERVER_HASH_ITERATOR; + + typedef ACE_Hash_Map_Entry<OBSERVER_HASH_ADDR, OBSERVER *> + OBSERVER_HASH_ENTRY; + + OBSERVER_HASH observer_hash_; // Keep a list of ACE_Future_Observers unread by client's reader thread. // = Condition variable and mutex that protect the <value_>. @@ -239,13 +274,16 @@ public: int ready (void); // Check if the result is available. - void attach (ACE_Future_Observer<T> *observer); + int attach (ACE_Future_Observer<T> *observer); // Attaches the specified observer to a subject (i.e. the // ACE_Future). The update method of the specified subject will be // invoked with a copy of the associated ACE_Future as input when // the result gets set. If the result is already set when this // method gets invoked, then the update method of the specified // subject will be invoked immediately. + // + // Returns 0 if the observer is successfully attached, 1 if the + // observer is already attached, and -1 if failures occur. int detach (ACE_Future_Observer<T> *observer); // Detaches the specified observer from a subject (i.e. the @@ -253,10 +291,18 @@ public: // not be invoked when the ACE_Future_Reps result gets set. Returns // 1 if the specified observer was actually attached to the subject // prior to this call and 0 if was not. + // + // Returns 0 if the observer was successfully detached, and -1 if the observer was + // not attached in the first place. void dump (void) const; // Dump the state of an object. + ACE_Future_Rep<T> *get_rep(); + // Get the underlying ACE_Future_Rep<T>*. Note that this method should + // rarely, if ever, be used and that modifying the undlerlying ACE_Future_Rep<T>* + // should be done with extreme caution. + ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. diff --git a/ace/Future_Set.cpp b/ace/Future_Set.cpp index 58a7ec6fba6..f2d7281eb41 100644 --- a/ace/Future_Set.cpp +++ b/ace/Future_Set.cpp @@ -17,7 +17,7 @@ ACE_RCSID(ace, Future_Set, "$Id$") #if defined (ACE_HAS_THREADS) template <class T> -ACE_Future_Set<T>::ACE_Future_Set(ACE_Message_Queue<ACE_SYNCH> *new_queue) +ACE_Future_Set<T>::ACE_Future_Set (ACE_Message_Queue<ACE_SYNCH> *new_queue) : delete_queue_ (0) { if (new_queue) @@ -31,21 +31,25 @@ ACE_Future_Set<T>::ACE_Future_Set(ACE_Message_Queue<ACE_SYNCH> *new_queue) } template <class T> -ACE_Future_Set<T>::ACE_Future_Set(const ACE_Future_Set<T> &r) +ACE_Future_Set<T>::ACE_Future_Set (const ACE_Future_Set<T> &r) { } template <class T> -ACE_Future_Set<T>::~ACE_Future_Set(void) +ACE_Future_Set<T>::~ACE_Future_Set (void) { + FUTURE_HASH_ENTRY *map_entry = 0 + // Detach ourselves from all remaining futures, if any, - // in our list. - for (FUTURE_NODE *node = this->future_list_.delete_head (); - node != 0; - node = this->future_list_.delete_head ()) + // in our map. + + for (FUTURE_HASH_ITERATOR map_iterator (this->future_map_); + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) { - node->item_.detach (this); - delete node; + FUTURE_HOLDER *future_holder = map_entry->int_id_; + future_holder->item_.detach (this); + delete future_holder; } if (this->delete_queue_ != 0) @@ -53,29 +57,42 @@ ACE_Future_Set<T>::~ACE_Future_Set(void) } template <class T> int -ACE_Future_Set<T>::is_empty() const +ACE_Future_Set<T>::is_empty () const { - return this->future_list_.is_empty (); + return this->future_map_.current_size () == 0; } -template <class T> void +template <class T> int ACE_Future_Set<T>::insert (ACE_Future<T> &future) { - FUTURE_NODE *node; - ACE_NEW (node, - FUTURE_NODE (future)); - this->future_list_.insert_tail (node); + FUTURE_HOLDER *future_holder; + ACE_NEW_RETURN (future_holder, + FUTURE_HOLDER (future), + -1); + + FUTURE_REP_HASH_ADDR future_rep_hash_addr (future.get_rep ()); + int result = this->future_map_.bind (future_rep_hash_addr, + 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; - // Attach ourself to the ACE_Futures list of observer - future.attach (this); + return result; } template <class T> void ACE_Future_Set<T>::update (const ACE_Future<T> &future) { ACE_Message_Block *mb; + FUTURE localFuture = future; ACE_NEW (mb, - ACE_Message_Block ((char *) 0, 0)); + ACE_Message_Block ((char *) localFuture.get_rep (), 0)); // Enqueue in priority order. this->future_notification_queue_->enqueue (mb, 0); @@ -89,36 +106,34 @@ ACE_Future_Set<T>::next_readable (ACE_Future<T> &future, return 0; ACE_Message_Block *mb; + FUTURE_REP *future_rep; // Wait for a "readable future" signal from the message queue. if (this->future_notification_queue_->dequeue_head (mb, tv) != -1) - // Delete the message block. - mb->release (); + { + // 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 all nodes containing the specified future from our list. - int count = 0; - FUTURE_NODE *node = 0; + // Remove the hash map entry with the specified future rep from our map. + FUTURE_REP_HASH_ADDR future_rep_hash_addr (future_rep); + FUTURE_HOLDER *future_holder; - for (FUTURE_LIST::ITERATOR iter (this->future_list_); - (node = iter.next ()) != 0; - iter.advance ()) + if (this->future_map_.find (future_rep_hash_addr, + future_holder) != -1) { - ++count; - if (node->item_.ready ()) - { - future = node->item_; - this->future_list_.remove (node); - delete node; - - // NOTE: if the user inserted the same future into the list - // more than once, then maybe I should loop through the - // remaining futures in the list and remove all of those - // futures which are equal to the one we are returning. - return 1; - } + future = future_holder->item_; + this->future_map_.unbind (future_rep_hash_addr); + delete future_holder; + return 1; } return 0; @@ -126,4 +141,3 @@ ACE_Future_Set<T>::next_readable (ACE_Future<T> &future, #endif /* ACE_HAS_THREADS */ #endif /* ACE_FUTURE_SET_CPP */ - diff --git a/ace/Future_Set.h b/ace/Future_Set.h index 5318781995e..a73bd961107 100644 --- a/ace/Future_Set.h +++ b/ace/Future_Set.h @@ -17,10 +17,10 @@ #ifndef ACE_FUTURE_SET_H #define ACE_FUTURE_SET_H +#include "ace/Hash_Map_Manager.h" +#include "ace/Strategies_T.h" #include "ace/Thread.h" -#include "ace/Containers_T.h" #include "ace/Message_Queue.h" - #include "ace/Future.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) @@ -41,7 +41,7 @@ class ACE_Future_Set : public ACE_Future_Observer<T> // reader threads as they become available. public: // = Initialization and termination methods. - + ACE_Future_Set (ACE_Message_Queue<ACE_SYNCH> *future_notification_queue_ = 0); // Constructor. @@ -52,9 +52,12 @@ public: // Return 1 if their are no ACE_Future objects left on its queue and // 0 otherwise - void insert (ACE_Future<T> &future); - // Enqueus the given ACE_Future into this objects queue when it is + int insert (ACE_Future<T> &future); + // Enqueues the given ACE_Future into this objects queue when it is // readable. + // + // Returns 0 if the future is successfully inserted, 1 if the + // future is already inserted, and -1 if failures occur. int next_readable (ACE_Future<T> &result, ACE_Time_Value *tv = 0); @@ -78,19 +81,35 @@ private: ACE_Future_Set (const ACE_Future_Set &r); // Copy constructor binds <this> and <r> to the same // <ACE_Future_Set>. An <ACE_Future_Set> is created if necessary. - - typedef ACE_DLList_Future_Node<T> - FUTURE_NODE; - typedef ACE_Double_Linked_List<FUTURE_NODE> - FUTURE_LIST; - - FUTURE_LIST future_list_; - // List of ACE_Futures, subjects, which have not been written to by + + typedef ACE_Future<T> + FUTURE; + + typedef ACE_Future_Rep<T> + FUTURE_REP; + + typedef ACE_Future_Holder<T> + FUTURE_HOLDER; + + typedef ACE_Hash_Addr<FUTURE_REP*> + FUTURE_REP_HASH_ADDR; + + typedef ACE_Hash_Map_Manager<FUTURE_REP_HASH_ADDR, FUTURE_HOLDER *, ACE_Null_Mutex> + FUTURE_HASH_MAP; + + typedef ACE_Hash_Map_Iterator<FUTURE_REP_HASH_ADDR, FUTURE_HOLDER *, ACE_Null_Mutex> + FUTURE_HASH_ITERATOR; + + typedef ACE_Hash_Map_Entry<FUTURE_REP_HASH_ADDR, FUTURE_HOLDER *> + FUTURE_HASH_ENTRY; + + FUTURE_HASH_MAP future_map_; + // Map of ACE_Futures, subjects, which have not been written to by // client's writer thread. ACE_Message_Queue<ACE_SYNCH> *future_notification_queue_; - // Message queue for notifying reader thread of ACE_Futures written - // to by client's writer thread. + // Message queue for notifying the reader thread of ACE_Futures which + // have been written to by client's writer thread. int delete_queue_; // Keeps track of whether we need to delete the message queue. diff --git a/ace/Hash_Map_Manager_T.h b/ace/Hash_Map_Manager_T.h index 718f218944e..4752511f2d5 100644 --- a/ace/Hash_Map_Manager_T.h +++ b/ace/Hash_Map_Manager_T.h @@ -245,10 +245,10 @@ public: int unbind (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry); // Remove entry from map. - size_t current_size (void); + size_t current_size (void) const; // Return the current size of the map. - size_t total_size (void); + size_t total_size (void) const; // Return the total size of the map. ACE_LOCK &mutex (void); diff --git a/ace/Hash_Map_Manager_T.i b/ace/Hash_Map_Manager_T.i index 1f5f8e015f2..f4e86244358 100644 --- a/ace/Hash_Map_Manager_T.i +++ b/ace/Hash_Map_Manager_T.i @@ -40,13 +40,13 @@ ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::~ACE_ } template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE size_t -ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::current_size (void) +ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::current_size (void) const { return this->cur_size_; } template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE size_t -ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::total_size (void) +ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::total_size (void) const { return this->total_size_; } diff --git a/ace/Map_Manager.h b/ace/Map_Manager.h index c982fc3a113..0925d3c6dd7 100644 --- a/ace/Map_Manager.h +++ b/ace/Map_Manager.h @@ -200,10 +200,10 @@ public: // in case the caller needs to deallocate memory. Returns 0 if // successful, else -1. - size_t current_size (void); + size_t current_size (void) const; // Return the current size of the map. - size_t total_size (void); + size_t total_size (void) const; // Return the total size of the map. ACE_LOCK &mutex (void); diff --git a/ace/Map_Manager.i b/ace/Map_Manager.i index d837cbd06b1..34d3fe254c8 100644 --- a/ace/Map_Manager.i +++ b/ace/Map_Manager.i @@ -173,18 +173,16 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind (const EXT_ID &ext_id) } template <class EXT_ID, class INT_ID, class ACE_LOCK> ACE_INLINE size_t -ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::current_size (void) +ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::current_size (void) const { - ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, - ACE_static_cast(size_t, -1)); + ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, ACE_const_cast (ACE_LOCK &, this->lock_), ACE_static_cast (size_t, -1)); return this->cur_size_; } template <class EXT_ID, class INT_ID, class ACE_LOCK> ACE_INLINE size_t -ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::total_size (void) +ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::total_size (void) const { - ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, - ACE_static_cast (size_t, -1)); + ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, ACE_const_cast (ACE_LOCK &, this->lock_), ACE_static_cast (size_t, -1)); return this->total_size_; } diff --git a/ace/Map_T.h b/ace/Map_T.h index 17a21dbccc1..2b9e2594a72 100644 --- a/ace/Map_T.h +++ b/ace/Map_T.h @@ -362,10 +362,10 @@ public: // Remove <key> from the map, and return the <value> associated with // <key>. - virtual size_t current_size (void) = 0; + virtual size_t current_size (void) const = 0; // Return the current size of the map. - virtual size_t total_size (void) = 0; + virtual size_t total_size (void) const = 0; // Return the total size of the map. virtual void dump (void) const = 0; @@ -616,10 +616,10 @@ public: // Remove <key> from the map, and return the <value> associated with // <key>. - virtual size_t current_size (void); + virtual size_t current_size (void) const; // Return the current size of the map. - virtual size_t total_size (void); + virtual size_t total_size (void) const; // Return the total size of the map. virtual void dump (void) const; @@ -866,10 +866,10 @@ public: // Remove <key> from the map, and return the <value> associated with // <key>. - virtual size_t current_size (void); + virtual size_t current_size (void) const; // Return the current size of the map. - virtual size_t total_size (void); + virtual size_t total_size (void) const; // Return the total size of the map. virtual void dump (void) const; @@ -1128,10 +1128,10 @@ public: // Remove <key> from the map, and return the <value> associated with // <key>. - virtual size_t current_size (void); + virtual size_t current_size (void) const; // Return the current size of the map. - virtual size_t total_size (void); + virtual size_t total_size (void) const; // Return the total size of the map. virtual void dump (void) const; @@ -1382,10 +1382,10 @@ public: // Remove <key> from the map, and return the <value> associated with // <key>. - virtual size_t current_size (void); + virtual size_t current_size (void) const; // Return the current size of the map. - virtual size_t total_size (void); + virtual size_t total_size (void) const; // Return the total size of the map. virtual void dump (void) const; diff --git a/ace/Map_T.i b/ace/Map_T.i index ed64cf6d6a7..08899ad7a63 100644 --- a/ace/Map_T.i +++ b/ace/Map_T.i @@ -1,15 +1,11 @@ // $Id$ -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE int ACE_Noop_Key_Generator<T>::operator() (T &) { return -1; } -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE ACE_Incremental_Key_Generator<T>::ACE_Incremental_Key_Generator (void) : t_ (0) @@ -29,22 +25,16 @@ ACE_Incremental_Key_Generator<T>::current_value (void) return this->t_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE ACE_Iterator_Impl<T>::~ACE_Iterator_Impl (void) { } -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE ACE_Reverse_Iterator_Impl<T>::~ACE_Reverse_Iterator_Impl (void) { } -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE ACE_Iterator<T>::ACE_Iterator (ACE_Iterator_Impl<T> *impl) : implementation_ (impl) @@ -125,8 +115,6 @@ ACE_Iterator<T>::impl (void) return *this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T> ACE_INLINE ACE_Reverse_Iterator<T>::ACE_Reverse_Iterator (ACE_Reverse_Iterator_Impl<T> *impl) : implementation_ (impl) @@ -207,8 +195,6 @@ ACE_Reverse_Iterator<T>::impl (void) return *this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class KEY, class VALUE> ACE_INLINE ACE_Map<KEY, VALUE>::ACE_Map (void) { @@ -243,8 +229,6 @@ ACE_Map<KEY, VALUE>::rend (void) return reverse_iterator (this->rend_impl ()); } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class IMPLEMENTATION, class ENTRY> ACE_INLINE ACE_Map_Impl_Iterator_Adapter<T, IMPLEMENTATION, ENTRY>::ACE_Map_Impl_Iterator_Adapter (const IMPLEMENTATION &impl) : implementation_ (impl) @@ -298,8 +282,6 @@ ACE_Map_Impl_Iterator_Adapter<T, IMPLEMENTATION, ENTRY>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class IMPLEMENTATION, class ENTRY> ACE_INLINE ACE_Map_Impl_Reverse_Iterator_Adapter<T, IMPLEMENTATION, ENTRY>::ACE_Map_Impl_Reverse_Iterator_Adapter (const IMPLEMENTATION &impl) : implementation_ (impl) @@ -353,8 +335,6 @@ ACE_Map_Impl_Reverse_Iterator_Adapter<T, IMPLEMENTATION, ENTRY>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class KEY, class VALUE, class IMPLEMENTATION, class ITERATOR, class REVERSE_ITERATOR, class ENTRY> ACE_INLINE ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::ACE_Map_Impl (ACE_Allocator *alloc) : implementation_ (alloc) @@ -493,13 +473,13 @@ ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::unb } template <class KEY, class VALUE, class IMPLEMENTATION, class ITERATOR, class REVERSE_ITERATOR, class ENTRY> ACE_INLINE size_t -ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::current_size (void) +ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::current_size (void) const { return this->implementation_.current_size (); } template <class KEY, class VALUE, class IMPLEMENTATION, class ITERATOR, class REVERSE_ITERATOR, class ENTRY> ACE_INLINE size_t -ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::total_size (void) +ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::total_size (void) const { return this->implementation_.total_size (); } @@ -540,8 +520,6 @@ ACE_Map_Impl<KEY, VALUE, IMPLEMENTATION, ITERATOR, REVERSE_ITERATOR, ENTRY>::imp return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class VALUE> ACE_INLINE ACE_Active_Map_Manager_Iterator_Adapter<T, VALUE>::ACE_Active_Map_Manager_Iterator_Adapter (const ACE_Map_Iterator<ACE_Active_Map_Manager_Key, VALUE, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -596,8 +574,6 @@ ACE_Active_Map_Manager_Iterator_Adapter<T, VALUE>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class VALUE> ACE_INLINE ACE_Active_Map_Manager_Reverse_Iterator_Adapter<T, VALUE>::ACE_Active_Map_Manager_Reverse_Iterator_Adapter (const ACE_Map_Reverse_Iterator<ACE_Active_Map_Manager_Key, VALUE, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -652,8 +628,6 @@ ACE_Active_Map_Manager_Reverse_Iterator_Adapter<T, VALUE>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class KEY, class VALUE, class KEY_ADAPTER> ACE_INLINE ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::ACE_Active_Map_Manager_Adapter (ACE_Allocator *alloc) : implementation_ (alloc) @@ -953,13 +927,13 @@ ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::unbind (const KEY &key, } template <class KEY, class VALUE, class KEY_ADAPTER> ACE_INLINE size_t -ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::current_size (void) +ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::current_size (void) const { return this->implementation_.current_size (); } template <class KEY, class VALUE, class KEY_ADAPTER> ACE_INLINE size_t -ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::total_size (void) +ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::total_size (void) const { return this->implementation_.total_size (); } @@ -1006,8 +980,6 @@ ACE_Active_Map_Manager_Adapter<KEY, VALUE, KEY_ADAPTER>::key_adapter (void) return this->key_adapter_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class KEY, class VALUE, class HASH_KEY, class COMPARE_KEYS> ACE_INLINE ACE_Hash_Map_Manager_Ex_Iterator_Adapter<T, KEY, VALUE, HASH_KEY, COMPARE_KEYS>::ACE_Hash_Map_Manager_Ex_Iterator_Adapter (const ACE_Hash_Map_Iterator_Ex<KEY, VALUE, HASH_KEY, COMPARE_KEYS, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -1062,8 +1034,6 @@ ACE_Hash_Map_Manager_Ex_Iterator_Adapter<T, KEY, VALUE, HASH_KEY, COMPARE_KEYS>: return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class KEY, class VALUE, class HASH_KEY, class COMPARE_KEYS> ACE_INLINE ACE_Hash_Map_Manager_Ex_Reverse_Iterator_Adapter<T, KEY, VALUE, HASH_KEY, COMPARE_KEYS>::ACE_Hash_Map_Manager_Ex_Reverse_Iterator_Adapter (const ACE_Hash_Map_Reverse_Iterator_Ex<KEY, VALUE, HASH_KEY, COMPARE_KEYS, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -1118,8 +1088,6 @@ ACE_Hash_Map_Manager_Ex_Reverse_Iterator_Adapter<T, KEY, VALUE, HASH_KEY, COMPAR return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class KEY, class VALUE, class HASH_KEY, class COMPARE_KEYS, class KEY_GENERATOR> ACE_INLINE ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATOR>::ACE_Hash_Map_Manager_Ex_Adapter (ACE_Allocator *alloc) : implementation_ (alloc) @@ -1269,13 +1237,13 @@ ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATO } template <class KEY, class VALUE, class HASH_KEY, class COMPARE_KEYS, class KEY_GENERATOR> ACE_INLINE size_t -ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATOR>::current_size (void) +ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATOR>::current_size (void) const { return this->implementation_.current_size (); } template <class KEY, class VALUE, class HASH_KEY, class COMPARE_KEYS, class KEY_GENERATOR> ACE_INLINE size_t -ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATOR>::total_size (void) +ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATOR>::total_size (void) const { return this->implementation_.total_size (); } @@ -1322,8 +1290,6 @@ ACE_Hash_Map_Manager_Ex_Adapter<KEY, VALUE, HASH_KEY, COMPARE_KEYS, KEY_GENERATO return this->key_generator_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class KEY, class VALUE> ACE_INLINE ACE_Map_Manager_Iterator_Adapter<T, KEY, VALUE>::ACE_Map_Manager_Iterator_Adapter (const ACE_Map_Iterator<KEY, VALUE, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -1378,8 +1344,6 @@ ACE_Map_Manager_Iterator_Adapter<T, KEY, VALUE>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class T, class KEY, class VALUE> ACE_INLINE ACE_Map_Manager_Reverse_Iterator_Adapter<T, KEY, VALUE>::ACE_Map_Manager_Reverse_Iterator_Adapter (const ACE_Map_Reverse_Iterator<KEY, VALUE, ACE_Null_Mutex> &impl) : implementation_ (impl) @@ -1434,8 +1398,6 @@ ACE_Map_Manager_Reverse_Iterator_Adapter<T, KEY, VALUE>::impl (void) return this->implementation_; } -//////////////////////////////////////////////////////////////////////////////// - template <class KEY, class VALUE, class KEY_GENERATOR> ACE_INLINE ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::ACE_Map_Manager_Adapter (ACE_Allocator *alloc) : implementation_ (alloc) @@ -1585,13 +1547,13 @@ ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::unbind (const KEY &key, } template <class KEY, class VALUE, class KEY_GENERATOR> ACE_INLINE size_t -ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::current_size (void) +ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::current_size (void) const { return this->implementation_.current_size (); } template <class KEY, class VALUE, class KEY_GENERATOR> ACE_INLINE size_t -ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::total_size (void) +ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::total_size (void) const { return this->implementation_.total_size (); } @@ -1637,5 +1599,3 @@ ACE_Map_Manager_Adapter<KEY, VALUE, KEY_GENERATOR>::key_generator (void) { return this->key_generator_; } - -//////////////////////////////////////////////////////////////////////////////// @@ -1601,8 +1601,8 @@ ACE_OS::strncasecmp (const char *s, #if !defined (ACE_WIN32) || defined (ACE_HAS_WINCE) ACE_TRACE ("ACE_OS::strcasecmp"); # if defined (ACE_LACKS_STRCASECMP) - const wchar_t *scan1 = s; - const wchar_t *scan2 = t + const char *scan1 = s; + const char *scan2 = t; ssize_t count = ssize_t (n); while (--count >= 0 @@ -10444,7 +10444,7 @@ ACE_OS::strncasecmp (const wchar_t *s, # if !defined (ACE_WIN32) const wchar_t *scan1 = s; - const wchar_t *scan2 = t + const wchar_t *scan2 = t; ssize_t count = ssize_t (n); while (--count >= 0 diff --git a/tests/Future_Set_Test.cpp b/tests/Future_Set_Test.cpp new file mode 100644 index 00000000000..2d71b5e4662 --- /dev/null +++ b/tests/Future_Set_Test.cpp @@ -0,0 +1,651 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Future_Set_Test.cpp +// +// = DESCRIPTION +// This example tests the ACE Future Set and illustrates an +// implementation of the Active Object pattern, which is available +// at <http://www.cs.wustl.edu/~schmidt/Act-Obj.ps.gz>. The +// Active Object itself is very simple -- it determines if numbers +// are prime. +// +// = AUTHOR +// Andres Kruse <Andres.Kruse@cern.ch>, +// Douglas C. Schmidt <schmidt@cs.wustl.edu>, +// John Tucker <jtucker@infoglide.com>, +// and Per Andersson <pera@ipso.se> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/ACE.h" +#include "ace/Task.h" +#include "ace/Synch.h" +#include "ace/Message_Queue.h" +#include "ace/Future.h" +#include "ace/Future_Set.h" +#include "ace/Method_Request.h" +#include "ace/Activation_Queue.h" +#include "ace/Auto_Ptr.h" + +ACE_RCSID(tests, Future_Set_Test, "$Id$") + +#if defined(__BORLANDC__) && __BORLANDC__ >= 0x0530 +USELIB("..\ace\aced.lib"); +//--------------------------------------------------------------------------- +#endif /* defined (__BORLANDC__) && __BORLANDC__ >= 0x0530 */ + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Atomic_Op<ACE_Thread_Mutex, int> ATOMIC_INT; + +// A counter for the tasks.. +static ATOMIC_INT task_count (0); + +// A counter for the futures.. +static ATOMIC_INT future_count (0); + +// A counter for the capsules.. +static ATOMIC_INT capsule_count (0); + +// A counter for the method requests... +static ATOMIC_INT method_request_count (0); + +class Prime_Scheduler : public ACE_Task_Base +{ + // = TITLE + // Prime number scheduler for the Active Object. + // + // = DESCRIPTION + // This class also plays the role of the Proxy and the Servant + // in the Active Object pattern. Naturally, these roles could + // be split apart from the Prime_Scheduler. + + friend class Method_Request_work; + friend class Method_Request_name; + friend class Method_Request_end; +public: + // = Initialization and termination methods. + Prime_Scheduler (const ASYS_TCHAR *, + Prime_Scheduler * = 0); + // Constructor. + + virtual int open (void *args = 0); + // Initializer. + + virtual int close (u_long flags = 0); + // Terminator. + + virtual ~Prime_Scheduler (void); + // Destructor. + + // = These methods are part of the Active Object Proxy interface. + ACE_Future<u_long> work (u_long param, int count = 1); + ACE_Future<const ASYS_TCHAR*> name (void); + void end (void); + +protected: + virtual int svc (void); + // Runs the Prime_Scheduler's event loop, which dequeues + // <Method_Requests> and dispatches them. + + // = These are the Servant methods that do the actual work. + u_long work_i (u_long, int); + const ASYS_TCHAR *name_i (void); + +private: + // = These are the <Prime_Scheduler> implementation details. + ASYS_TCHAR *name_; + ACE_Activation_Queue activation_queue_; + Prime_Scheduler *scheduler_; +}; + +class Method_Request_work : public ACE_Method_Request +{ + // = TITLE + // Reification of the <work> method. +public: + Method_Request_work (Prime_Scheduler *, + u_long, + int, + ACE_Future<u_long> &); + virtual ~Method_Request_work (void); + + virtual int call (void); + // This is the entry point into the Active Object method. + +private: + Prime_Scheduler *scheduler_; + + u_long param_; + // Parameter to the method that's used to determine if a number if + // prime. + + int count_; + // Unused. + + ACE_Future<u_long> future_result_; + // Store the result of the Future. +}; + +Method_Request_work::Method_Request_work (Prime_Scheduler *new_Prime_Scheduler, + u_long new_param, + int new_count, + ACE_Future<u_long> &new_result) + : scheduler_ (new_Prime_Scheduler), + param_ (new_param), + count_ (new_count), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Method_Request_work created\n"))); +} + +Method_Request_work::~Method_Request_work (void) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Method_Request_work will be deleted.\n"))); +} + +int +Method_Request_work::call (void) +{ + // Dispatch the Servant's operation and store the result into the + // Future. + return this->future_result_.set (this->scheduler_->work_i + (this->param_, + this->count_)); +} + +class Method_Request_name : public ACE_Method_Request +{ + // = TITLE + // Reification of the <name> method. +public: + Method_Request_name (Prime_Scheduler *, + ACE_Future<const ASYS_TCHAR*> &); + virtual ~Method_Request_name (void); + + virtual int call (void); + // This is the entry point into the Active Object method. + +private: + Prime_Scheduler *scheduler_; + ACE_Future<const ASYS_TCHAR*> future_result_; +}; + +Method_Request_name::Method_Request_name (Prime_Scheduler *new_scheduler, + ACE_Future<const ASYS_TCHAR*> &new_result) + : scheduler_ (new_scheduler), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Method_Request_name created\n"))); +} + +Method_Request_name::~Method_Request_name (void) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Method_Request_name will be deleted.\n"))); +} + +int +Method_Request_name::call (void) +{ + // Dispatch the Servant's operation and store the result into the + // Future. + return future_result_.set (scheduler_->name_i ()); +} + +class Method_Request_end : public ACE_Method_Request +{ + // = TITLE + // Reification of the <end> method. +public: + Method_Request_end (Prime_Scheduler *new_Prime_Scheduler); + virtual ~Method_Request_end (void); + virtual int call (void); + +private: + Prime_Scheduler *scheduler_; +}; + +Method_Request_end::Method_Request_end (Prime_Scheduler *scheduler) + : scheduler_ (scheduler) +{ +} + +Method_Request_end::~Method_Request_end (void) +{ +} + +int +Method_Request_end::call (void) +{ + // Shut down the scheduler. + this->scheduler_->close (); + return -1; +} + +// Constructor +Prime_Scheduler::Prime_Scheduler (const ASYS_TCHAR *newname, + Prime_Scheduler *new_scheduler) + : scheduler_ (new_scheduler) +{ + ACE_NEW (this->name_, + ASYS_TCHAR[ACE_OS::strlen (newname) + 1]); + ACE_OS::strcpy ((ASYS_TCHAR *) this->name_, + newname); + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Prime_Scheduler %s created\n"), + this->name_)); +} + +// Destructor + +Prime_Scheduler::~Prime_Scheduler (void) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Prime_Scheduler %s will be destroyed\n"), + this->name_)); + delete [] this->name_; +} + +// open + +int +Prime_Scheduler::open (void *) +{ + task_count++; + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Prime_Scheduler %s open\n"), + this->name_)); + // Become an Active Object. + return this->activate (THR_BOUND | THR_DETACHED); +} + +// close + +int +Prime_Scheduler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) Prime_Scheduler %s close\n"), + this->name_)); + task_count--; + return 0; +} + +// Service.. + +int +Prime_Scheduler::svc (void) +{ + for (;;) + { + // Dequeue the next method request (we use an auto pointer in + // case an exception is thrown in the <call>). + auto_ptr<ACE_Method_Request> mo (this->activation_queue_.dequeue ()); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) calling method request\n"))); + // Call it. + if (mo->call () == -1) + break; + // Destructor automatically deletes it. + } + + /* NOTREACHED */ + return 0; +} + +void +Prime_Scheduler::end (void) +{ + this->activation_queue_.enqueue (new Method_Request_end (this)); +} + +// Here's where the Work takes place. We compute if the parameter is +// a prime number. + +u_long +Prime_Scheduler::work_i (u_long param, + int count) +{ + ACE_UNUSED_ARG (count); + + return ACE::is_prime (param, 2, param / 2); +} + +const ASYS_TCHAR * +Prime_Scheduler::name_i (void) +{ + return this->name_; +} + +ACE_Future<const ASYS_TCHAR *> +Prime_Scheduler::name (void) +{ + if (this->scheduler_) + // Delegate to the Prime_Scheduler. + return this->scheduler_->name (); + else + { + ACE_Future<const ASYS_TCHAR*> new_future; + + // @@ What happens if new fails here? + this->activation_queue_.enqueue + (new Method_Request_name (this, + new_future)); + return new_future; + } +} + +ACE_Future<u_long> +Prime_Scheduler::work (u_long newparam, + int newcount) +{ + if (this->scheduler_) { + return this->scheduler_->work (newparam, newcount); + } + else { + ACE_Future<u_long> new_future; + + this->activation_queue_.enqueue + (new Method_Request_work (this, + newparam, + newcount, + new_future)); + return new_future; + } +} + +// @@ These values should be set by the command line options! + +// Total number of loops. +static int n_loops = 100; + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Atomic_Op<ACE_Thread_Mutex, int>; + +template class ACE_Future_Holder<const ASYS_TCHAR *>; +template class ACE_Future_Holder<int>; +template class ACE_Future_Holder<u_long>; + +template class ACE_Future_Observer<const ASYS_TCHAR *>; +template class ACE_Future_Observer<int>; +template class ACE_Future_Observer<u_long>; + +template class ACE_Future<const ASYS_TCHAR *>; +template class ACE_Future<int>; +template class ACE_Future<u_long>; + +template class ACE_Future_Rep<ASYS_TCHAR const *>; +template class ACE_Future_Rep<int>; +template class ACE_Future_Rep<u_long>; + +template class ACE_Future_Set<const ASYS_TCHAR *>; +template class ACE_Future_Set<int>; +template class ACE_Future_Set<u_long>; + +template class auto_ptr<ACE_Method_Request>; +template class ACE_Auto_Basic_Ptr<ACE_Method_Request>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Atomic_Op<ACE_Thread_Mutex, int> + +#pragma instantiate ACE_Future_Holder<const ASYS_TCHAR *>; +#pragma instantiate ACE_Future_Holder<int>; +#pragma instantiate ACE_Future_Holder<u_long>; + +#pragma instantiate ACE_Future_Observer<const ASYS_TCHAR *>; +#pragma instantiate ACE_Future_Observer<int>; +#pragma instantiate ACE_Future_Observer<u_long>; + +#pragma instantiate ACE_Future<const ASYS_TCHAR *>; +#pragma instantiate ACE_Future<int>; +#pragma instantiate ACE_Future<u_long>; + +#pragma instantiate ACE_Future_Rep<ASYS_TCHAR const *>; +#pragma instantiate ACE_Future_Rep<int>; +#pragma instantiate ACE_Future_Rep<u_long>; + +#pragma instantiate ACE_Future_Set<const ASYS_TCHAR *>; +#pragma instantiate ACE_Future_Set<int>; +#pragma instantiate ACE_Future_Set<u_long>; + +#pragma instantiate ACE_Future<const ASYS_TCHAR *> +#pragma instantiate ACE_Future<int> +#pragma instantiate ACE_Future<u_long> + +#pragma instantiate ACE_Future_Rep<ASYS_TCHAR const *> +#pragma instantiate ACE_Future_Rep<int> +#pragma instantiate ACE_Future_Rep<u_long> + +#pragma instantiate auto_ptr<ACE_Method_Request> +#pragma instantiate ACE_Auto_Basic_Ptr<ACE_Method_Request> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +#endif /* ACE_HAS_THREADS */ + +int +main (int, ASYS_TCHAR *[]) +{ + ACE_START_TEST (ASYS_TEXT ("Future_Set_Test")); + +#if defined (ACE_HAS_THREADS) + // @@ Should make these be <auto_ptr>s... + Prime_Scheduler *andres, *peter, *helmut, *matias; + + // Create active objects.. + ACE_NEW_RETURN (andres, + Prime_Scheduler (ASYS_TEXT ("andres")), + -1); + ACE_ASSERT (andres->open () != -1); + ACE_NEW_RETURN (peter, + Prime_Scheduler (ASYS_TEXT ("peter")), + -1); + ACE_ASSERT (peter->open () != -1); + ACE_NEW_RETURN (helmut, + Prime_Scheduler (ASYS_TEXT ("helmut")), + -1); + ACE_ASSERT (helmut->open () != -1); + + // Matias passes all asynchronous method calls on to Andres... + ACE_NEW_RETURN (matias, + Prime_Scheduler (ASYS_TEXT ("matias"), + andres), + -1); + ACE_ASSERT (matias->open () != -1); + + ACE_Future<u_long> fresulta; + ACE_Future<u_long> fresultb; + ACE_Future<u_long> fresultc; + ACE_Future<u_long> fresultd; + ACE_Future<u_long> fresulte; + ACE_Future<const ASYS_TCHAR *> fname; + + ACE_Future_Set<u_long> fseta; + ACE_Future_Set<u_long> fsetb; + ACE_Future_Set<u_long> fsetc; + ACE_Future_Set<u_long> fsetd; + ACE_Future_Set<u_long> fsete; + ACE_Future_Set<const ASYS_TCHAR *> fsetname; + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) initializing future sets with non-blocking call\n"))); + + for (int i = 0; i < n_loops; i++) + { + // Spawn off the methods, which run in a separate thread as + // active object invocations. + fseta.insert (andres->work (9013)); + fsetb.insert (peter->work (9013)); + fsetc.insert (helmut->work (9013)); + fsetd.insert (matias->work (9013)); + fsetname.insert (andres->name ()); + } + + // See if the result is available... + + if (! fseta.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set a is not empty.....\n"))); + + if (! fsetb.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set b is not empty.....\n"))); + + if (! fsetc.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set c is not empty.....\n"))); + + if (! fsetd.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set d is not empty.....\n"))); + + if (! fsetname.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set name is not empty.....\n"))); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) non-blocking calls done... now blocking...\n"))); + + // Save the result of fresulta. + + u_long resulta = 0; + u_long resultb = 0; + u_long resultc = 0; + u_long resultd = 0; + + u_int count; + + for (count = 0; + fseta.next_readable (fresulta); + ) + { + fresulta.get (resulta); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) result (%u) a %u\n"), + count, + (u_int) resulta)); + } + + for (count = 0; + fsetb.next_readable (fresultb); + ) + { + fresultb.get (resultb); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) result (%u) b %u\n"), + count, + (u_int) resultb)); + } + + for (count = 0; + fsetc.next_readable (fresultc); + ) + { + fresultc.get (resultc); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) result (%u) c %u\n"), + count, + (u_int) resultc)); + } + + for (count = 0; + fsetd.next_readable (fresultd); + ) + { + fresultd.get (resultd); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) result (%u) d %u\n"), + count, + (u_int) resultd)); + } + + const ASYS_TCHAR *name; + + for (count = 0; + fsetname.next_readable (fname); + ) + { + fname.get (name); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) result (%u) name %u\n"), + count, + (u_int) name)); + } + + if (fseta.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set a is empty.....\n"))); + + if (fsetb.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set b is empty.....\n"))); + + if (fsetc.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set c is empty.....\n"))); + + if (fsetd.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set d is empty.....\n"))); + + if (fsetname.is_empty ()) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) wow.. set name is empty.....\n"))); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) task_count %d future_count %d ") + ASYS_TEXT ("capsule_count %d method_request_count %d\n"), + task_count.value (), + future_count.value (), + capsule_count.value (), + method_request_count.value ())); + + // Close things down. + andres->end (); + peter->end (); + helmut->end (); + matias->end (); + + ACE_OS::sleep (2); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT (" (%t) task_count %d future_count %d ") + ASYS_TEXT ("capsule_count %d method_request_count %d\n"), + task_count.value (), + future_count.value (), + capsule_count.value (), + method_request_count.value ())); + + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("No it did not crash the program.\n"))); + + ACE_OS::sleep (5); + + delete andres; + delete peter; + delete helmut; + delete matias; + +#else + ACE_ERROR ((LM_INFO, + ASYS_TEXT ("threads not supported on this platform\n"))); +#endif /* ACE_HAS_THREADS */ + ACE_END_TEST; + return 0; +} diff --git a/tests/Future_Set_Test.dsp b/tests/Future_Set_Test.dsp new file mode 100644 index 00000000000..3eb1dc76cf0 --- /dev/null +++ b/tests/Future_Set_Test.dsp @@ -0,0 +1,229 @@ +# Microsoft Developer Studio Project File - Name="Future_Set_Test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 +# TARGTYPE "Win32 (ALPHA) Console Application" 0x0603 + +CFG=Future_Set_Test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Future_Set_Test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Future_Set_Test.mak" CFG="Future_Set_Test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Future_Set_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Future_Set_Test - Win32 Alpha Debug" (based on\ + "Win32 (ALPHA) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "Future_Set_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Future_Set_Test\Debug" +# PROP BASE Intermediate_Dir ".\Future_Set_Test\Debug" +# PROP BASE Target_Dir ".\Future_Set_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir ".\DLL\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir ".\Future_Set_Test" +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\ace" + +!ELSEIF "$(CFG)" == "Future_Set_Test - Win32 Alpha Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Future_Set_Test\Alpha Debug" +# PROP BASE Intermediate_Dir "Future_Set_Test\Alpha Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "Future_Set_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "Future_Set_Test" +CPP=cl.exe +# ADD BASE CPP /nologo /Gt0 /W3 /GX /Zi /Od /I "..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /MTd /c +# ADD CPP /nologo /Gt0 /W3 /GX /Zi /Od /I "..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /MDd /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 aced.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:ALPHA /libpath:"..\ace" +# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:ALPHA /libpath:"..\ace" + +!ENDIF + +# Begin Target + +# Name "Future_Set_Test - Win32 Debug" +# Name "Future_Set_Test - Win32 Alpha Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\Future_Set_Test.cpp + +!IF "$(CFG)" == "Future_Set_Test - Win32 Debug" + +!ELSEIF "$(CFG)" == "Future_Set_Test - Win32 Alpha Debug" + +DEP_CPP_FUTUR=\ + "..\ace\ACE.h"\ + "..\ace\ACE.i"\ + "..\ace\Activation_Queue.h"\ + "..\ace\Atomic_Op.i"\ + "..\ace\Auto_Ptr.cpp"\ + "..\ace\Auto_Ptr.h"\ + "..\ace\Auto_Ptr.i"\ + "..\ace\config-win32-common.h"\ + "..\ace\config-win32.h"\ + "..\ace\config.h"\ + "..\ace\Containers.cpp"\ + "..\ace\Containers.h"\ + "..\ace\Containers.i"\ + "..\ace\Event_Handler.h"\ + "..\ace\Event_Handler.i"\ + "..\ace\Free_List.cpp"\ + "..\ace\Free_List.h"\ + "..\ace\Free_List.i"\ + "..\ace\Future.cpp"\ + "..\ace\Future.h"\ + "..\ace\Handle_Set.h"\ + "..\ace\Handle_Set.i"\ + "..\ace\Hash_Map_Manager.cpp"\ + "..\ace\Hash_Map_Manager.h"\ + "..\ace\IO_Cntl_Msg.h"\ + "..\ace\Log_Msg.h"\ + "..\ace\Log_Priority.h"\ + "..\ace\Log_Record.h"\ + "..\ace\Log_Record.i"\ + "..\ace\Malloc.h"\ + "..\ace\Malloc.i"\ + "..\ace\Malloc_T.cpp"\ + "..\ace\Malloc_T.h"\ + "..\ace\Malloc_T.i"\ + "..\ace\Managed_Object.cpp"\ + "..\ace\Managed_Object.h"\ + "..\ace\Managed_Object.i"\ + "..\ace\Mem_Map.h"\ + "..\ace\Mem_Map.i"\ + "..\ace\Memory_Pool.h"\ + "..\ace\Memory_Pool.i"\ + "..\ace\Message_Block.h"\ + "..\ace\Message_Block.i"\ + "..\ace\Message_Queue.cpp"\ + "..\ace\Message_Queue.h"\ + "..\ace\Message_Queue.i"\ + "..\ace\Method_Request.h"\ + "..\ace\Module.cpp"\ + "..\ace\Module.h"\ + "..\ace\Module.i"\ + "..\ace\Object_Manager.h"\ + "..\ace\Object_Manager.i"\ + "..\ace\OS.h"\ + "..\ace\OS.i"\ + "..\ace\Reactor.h"\ + "..\ace\Reactor.i"\ + "..\ace\Reactor_Impl.h"\ + "..\ace\Service_Config.h"\ + "..\ace\Service_Config.i"\ + "..\ace\Service_Object.h"\ + "..\ace\Service_Object.i"\ + "..\ace\Service_Types.h"\ + "..\ace\Service_Types.i"\ + "..\ace\Shared_Object.h"\ + "..\ace\Shared_Object.i"\ + "..\ace\Signal.h"\ + "..\ace\Signal.i"\ + "..\ace\SString.h"\ + "..\ace\SString.i"\ + "..\ace\stdcpp.h"\ + "..\ace\Strategies.h"\ + "..\ace\Strategies_T.cpp"\ + "..\ace\Strategies_T.h"\ + "..\ace\Stream_Modules.cpp"\ + "..\ace\Stream_Modules.h"\ + "..\ace\Stream_Modules.i"\ + "..\ace\SV_Semaphore_Complex.h"\ + "..\ace\SV_Semaphore_Complex.i"\ + "..\ace\SV_Semaphore_Simple.h"\ + "..\ace\SV_Semaphore_Simple.i"\ + "..\ace\Svc_Conf_Tokens.h"\ + "..\ace\Synch.h"\ + "..\ace\Synch.i"\ + "..\ace\Synch_Options.h"\ + "..\ace\Synch_T.cpp"\ + "..\ace\Synch_T.h"\ + "..\ace\Synch_T.i"\ + "..\ace\Task.h"\ + "..\ace\Task.i"\ + "..\ace\Task_T.cpp"\ + "..\ace\Task_T.h"\ + "..\ace\Task_T.i"\ + "..\ace\Thread.h"\ + "..\ace\Thread.i"\ + "..\ace\Thread_Manager.h"\ + "..\ace\Thread_Manager.i"\ + "..\ace\Timer_Queue.h"\ + "..\ace\Timer_Queue_T.cpp"\ + "..\ace\Timer_Queue_T.h"\ + "..\ace\Timer_Queue_T.i"\ + "..\ace\Trace.h"\ + "..\ace\Version.h"\ + "..\ace\WFMO_Reactor.h"\ + "..\ace\WFMO_Reactor.i"\ + "..\ace\ws2tcpip.h"\ + ".\test_config.h"\ + + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\test_config.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tests/Future_Set_Test.dsw b/tests/Future_Set_Test.dsw new file mode 100644 index 00000000000..40bc44978b6 --- /dev/null +++ b/tests/Future_Set_Test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Future_Set_Test"=.\Future_Set_Test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/tests/Makefile b/tests/Makefile index dd40966d071..e219b787ca5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -23,6 +23,7 @@ BIN = Aio_Platform_Test \ Enum_Interfaces_Test \ Env_Value_Test \ Future_Test \ + Future_Set_Test \ Handle_Set_Test \ High_Res_Timer_Test \ OrdMultiSet_Test \ diff --git a/tests/icc.bat b/tests/icc.bat index 512864dac96..a54461b85ea 100644 --- a/tests/icc.bat +++ b/tests/icc.bat @@ -12,6 +12,7 @@ vacbld -SEV=E Dynamic_Priority_Test.icc vacbld -SEV=E Enum_Interfaces_Test.icc vacbld -SEV=E Env_Value_Test.icc vacbld -SEV=E Future_Test.icc +vacbld -SEV=E Future_Set_Test.icc vacbld -SEV=E Handle_Set_Test.icc vacbld -SEV=E Hash_Map_Manager_Test.icc vacbld -SEV=E High_Res_Timer_Test.icc diff --git a/tests/run_tests.bat b/tests/run_tests.bat index 3b92193e210..e6ba0830677 100644 --- a/tests/run_tests.bat +++ b/tests/run_tests.bat @@ -74,6 +74,7 @@ call %run_cmd% %dopure% %platform% DLList_Test call %run_cmd% %dopure% %platform% Enum_Interfaces_Test call %run_cmd% %dopure% %platform% Env_Value_Test call %run_cmd% %dopure% %platform% Future_Test +call %run_cmd% %dopure% %platform% Future_Set_Test call %run_cmd% %dopure% %platform% Handle_Set_Test call %run_cmd% %dopure% %platform% Hash_Map_Manager_Test call %run_cmd% %dopure% %platform% High_Res_Timer_Test diff --git a/tests/run_tests.psosim b/tests/run_tests.psosim index 9d1a7846302..0d810f84ede 100755 --- a/tests/run_tests.psosim +++ b/tests/run_tests.psosim @@ -81,6 +81,9 @@ run SOCK_Connector_Test # uses SOCK_Connector #Future_Test: threads not supported on this platform #run Future_Test # uses Thread_Manager, Task +#Future_Set_Test: threads not supported on this platform +#run Future_Set_Test # uses Thread_Manager, Task + #Reactors_Test: threads not supported on this platform #run Reactors_Test # uses Task, Mutex, Reactor diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 44d0021d4cf..32c2fbc1ab8 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -153,7 +153,8 @@ run Task_Test # tests ACE_Thread_Manager, ACE_Task # Thread_Manager_Test: UNICOS fails due to no pthread_kill nor pthread_cancel test $Unicos || run Thread_Manager_Test # tests ACE_Thread_Manager, ACE_Task run Thread_Pool_Test # tests ACE_Thread_Manager, ACE_Task -run Future_Test # tests ACE_Thread_Manager, ACE_Task +run Future_Test # tests ACE_Thread_Manager, ACE_Task, ACE_Future +run Future_Set_Test # tests ACE_Thread_Manager, ACE_Task, ACE_Future_Set run RB_Tree_Test # tests ACE_RB_Tree, ACE_RB_Tree_Iterator run Reactors_Test # tests ACE_Task, ACE_Mutex, ACE_Reactor run Reactor_Exceptions_Test # tests ACE_Reactor and C++ exceptions diff --git a/tests/run_tests.vxworks b/tests/run_tests.vxworks index 8d0257cdabf..913ef45513d 100644 --- a/tests/run_tests.vxworks +++ b/tests/run_tests.vxworks @@ -135,6 +135,10 @@ ld < Future_Test write 2, "Future_Test ", 12 ace_main; unld "Future_Test" +ld < Future_Set_Test +write 2, "Future_Set_Test ", 12 +ace_main; unld "Future_Set_Test" + ld < Reactors_Test write 2, "Reactors_Test ", 14 ace_main; unld "Reactors_Test" |