summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1999-06-28 23:32:00 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1999-06-28 23:32:00 +0000
commit4091f79cfee193a77e2384a3a33dc38347ef6acb (patch)
treedbb1e00111aef87e5d662206ba1ec33f82724140
parent2011599cafe9775821ac246ace3a84709f87642f (diff)
downloadATCD-4091f79cfee193a77e2384a3a33dc38347ef6acb.tar.gz
.
-rw-r--r--ace/Active_Map_Manager_T.h4
-rw-r--r--ace/Active_Map_Manager_T.i4
-rw-r--r--ace/Cache_Map_Manager_T.h4
-rw-r--r--ace/Cache_Map_Manager_T.i4
-rw-r--r--ace/Future.cpp127
-rw-r--r--ace/Future.h82
-rw-r--r--ace/Future_Set.cpp96
-rw-r--r--ace/Future_Set.h49
-rw-r--r--ace/Hash_Map_Manager_T.h4
-rw-r--r--ace/Hash_Map_Manager_T.i4
-rw-r--r--ace/Map_Manager.h4
-rw-r--r--ace/Map_Manager.i10
-rw-r--r--ace/Map_T.h20
-rw-r--r--ace/Map_T.i56
-rw-r--r--ace/OS.i6
-rw-r--r--tests/Future_Set_Test.cpp651
-rw-r--r--tests/Future_Set_Test.dsp229
-rw-r--r--tests/Future_Set_Test.dsw29
-rw-r--r--tests/Makefile1
-rw-r--r--tests/icc.bat1
-rw-r--r--tests/run_tests.bat1
-rwxr-xr-xtests/run_tests.psosim3
-rwxr-xr-xtests/run_tests.sh3
-rw-r--r--tests/run_tests.vxworks4
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_;
}
-
-////////////////////////////////////////////////////////////////////////////////
diff --git a/ace/OS.i b/ace/OS.i
index 14eb6038487..9a5223e362e 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -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"