summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-26 01:43:14 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1997-10-26 01:43:14 +0000
commit1ffe60f64b8c13e9bd7f5b3d9a3cbc88b84b85b5 (patch)
tree3c9c4134b97200d8a4a900715cdfac543ebd2159
parent44067864df8e39840ea5df9252cb8317b1f47a9f (diff)
downloadATCD-1ffe60f64b8c13e9bd7f5b3d9a3cbc88b84b85b5.tar.gz
*** empty log message ***
-rw-r--r--ace/Event_Handler.cpp2
-rw-r--r--ace/Filecache.cpp15
-rw-r--r--ace/Hash_Map_Manager.cpp362
-rw-r--r--ace/Hash_Map_Manager.h183
-rw-r--r--ace/Map_Manager.cpp52
-rw-r--r--ace/Map_Manager.h2
-rw-r--r--ace/Strategies.cpp4
-rw-r--r--ace/Strategies.h18
-rw-r--r--ace/Strategies_T.cpp201
-rw-r--r--ace/Strategies_T.h72
-rw-r--r--ace/Svc_Handler.cpp45
-rw-r--r--ace/Svc_Handler.h40
-rw-r--r--tests/Conn_Test.h13
-rw-r--r--tests/Hash_Map_Manager_Test.cpp25
-rw-r--r--tests/Reactor_Exceptions_Test.cpp4
-rw-r--r--tests/tests.mak4
-rw-r--r--tests/tests.mdpbin2672 -> 18434 bytes
17 files changed, 755 insertions, 287 deletions
diff --git a/ace/Event_Handler.cpp b/ace/Event_Handler.cpp
index a090ccb36f1..338a8109e55 100644
--- a/ace/Event_Handler.cpp
+++ b/ace/Event_Handler.cpp
@@ -138,7 +138,7 @@ ACE_Event_Handler::reactor (ACE_Reactor *reactor)
ACE_Reactor *
ACE_Event_Handler::reactor (void) const
{
- ACE_TRACE ("ACE_Event_Handler::Reactor");
+ ACE_TRACE ("ACE_Event_Handler::reactor");
return this->reactor_;
}
diff --git a/ace/Filecache.cpp b/ace/Filecache.cpp
index 2ad009b1394..29e881d331c 100644
--- a/ace/Filecache.cpp
+++ b/ace/Filecache.cpp
@@ -124,13 +124,22 @@ ACE_Filecache_Handle::size (void) const
#define ACE_Filecache_Hash_Entry \
ACE_Hash_Map_Entry<const char *, ACE_Filecache_Object *>
-
ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (const char *const &ext_id,
ACE_Filecache_Object *const &int_id,
- ACE_Filecache_Hash_Entry *ptr)
+ ACE_Filecache_Hash_Entry *next,
+ ACE_Filecache_Hash_Entry *prev)
: ext_id_ (ext_id ? ACE_OS::strdup (ext_id) : ACE_OS::strdup ("")),
int_id_ (int_id),
- next_ (ptr)
+ next_ (next),
+ prev_ (prev)
+{
+}
+
+ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (ACE_Filecache_Hash_Entry *next,
+ ACE_Filecache_Hash_Entry *prev)
+ : ext_id_ (0),
+ next_ (next),
+ prev_ (prev)
{
}
diff --git a/ace/Hash_Map_Manager.cpp b/ace/Hash_Map_Manager.cpp
index 272f696dc00..f1ac801a00c 100644
--- a/ace/Hash_Map_Manager.cpp
+++ b/ace/Hash_Map_Manager.cpp
@@ -21,25 +21,22 @@
#include "ace/Malloc.h"
template <class EXT_ID, class INT_ID>
-ACE_Hash_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_Entry (void)
+ACE_Hash_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_Entry (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev)
+ : next_ (next),
+ prev_ (prev)
{
}
-template <class EXT_ID, class INT_ID> void
-ACE_Hash_Map_Entry<EXT_ID, INT_ID>::dump (void) const
-{
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
- ACE_DEBUG ((LM_DEBUG, "next_ = %d", this->next_));
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
template <class EXT_ID, class INT_ID>
ACE_Hash_Map_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_Entry (const EXT_ID &ext_id,
const INT_ID &int_id,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *ptr)
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev)
: ext_id_ (ext_id),
int_id_ (int_id),
- next_ (ptr)
+ next_ (next),
+ prev_ (prev)
{
}
@@ -48,6 +45,15 @@ ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry (void)
{
}
+template <class EXT_ID, class INT_ID> void
+ACE_Hash_Map_Entry<EXT_ID, INT_ID>::dump (void) const
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "next_ = %d", this->next_));
+ ACE_DEBUG ((LM_DEBUG, "prev_ = %d", this->prev_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
template <class EXT_ID, class INT_ID, class ACE_LOCK> void
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
{
@@ -60,22 +66,24 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
-ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::resize_i (size_t size)
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::create_buckets (size_t size)
{
- size_t bytes = size * sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *);
+ size_t bytes = size * sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>);
void *ptr;
ACE_ALLOCATOR_RETURN (ptr,
this->allocator_->malloc (bytes),
-1);
- this->table_ = (ACE_Hash_Map_Entry<EXT_ID, INT_ID> **) ptr;
+ this->table_ = (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *) ptr;
this->total_size_ = size;
- // Initialize the hash table to point to 0.
+ // Initialize the hash table by creating sentinals that point to
+ // themselves.
for (size_t i = 0; i < this->total_size_; i++)
- this->table_[i] = 0;
+ new (&this->table_[i]) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (&this->table_[i],
+ &this->table_[i]);
return 0;
}
@@ -97,11 +105,7 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::open (size_t size,
// to be ACE_DEFAULT_MAP_SIZE, but instead was defined to be 0.
ACE_ASSERT (size != 0);
- // If we need to grow buffer, then remove the existing buffer.
- if (this->total_size_ < size)
- return this->resize_i (size);
- else
- return 0;
+ return this->create_buckets (size);
}
template <class EXT_ID, class INT_ID, class ACE_LOCK>
@@ -134,8 +138,8 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::close_i (void)
// <ACE_Hash_Map_Entry>.
for (size_t i = 0; i < this->total_size_; i++)
{
- for (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp_ptr = this->table_[i];
- temp_ptr != 0;
+ for (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp_ptr = this->table_[i].next_;
+ temp_ptr != &this->table_[i];
)
{
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *hold_ptr = temp_ptr;
@@ -145,9 +149,13 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::close_i (void)
hold_ptr->ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry ();
this->allocator_->free (hold_ptr);
}
+ // Now deal with the sentinal
+ // Explicitly call the destructor.
+ this->table_[i].ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry ();
}
-
- this->allocator_->free (this->table_);
+
+ // Free table memory
+ this->allocator_->free (this->table_);
this->table_ = 0;
}
return 0;
@@ -187,19 +195,18 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::hash (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::equal (const EXT_ID &id1,
- const EXT_ID &id2)
+ const EXT_ID &id2)
{
return id1 == id2;
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
- const INT_ID &int_id)
+ const INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
{
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp;
-
u_long loc;
- int result = this->shared_find (ext_id, temp, loc);
+ int result = this->shared_find (ext_id, entry, loc);
if (result == -1)
{
@@ -208,9 +215,14 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
ACE_ALLOCATOR_RETURN (ptr,
this->allocator_->malloc (sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>)),
-1);
-
- this->table_[loc] =
- new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id, int_id, this->table_[loc]);
+
+ this->table_[loc].next_ = entry =
+ new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id,
+ int_id,
+ this->table_[loc].next_,
+ &this->table_[loc]);
+ entry->next_->prev_ = entry;
+ this->table_[loc].next_ = entry;
this->cur_size_++;
return 0;
@@ -220,8 +232,17 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id)
+{
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp;
+
+ return this->bind_i (ext_id, int_id, temp);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind (const EXT_ID &ext_id,
- const INT_ID &int_id)
+ const INT_ID &int_id)
{
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -229,13 +250,22 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind (const EXT_ID &ext_id,
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
-ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
{
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp;
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+ return this->bind_i (ext_id, int_id, entry);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
+ INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
u_long loc;
- int result = this->shared_find (ext_id, temp, loc);
+ int result = this->shared_find (ext_id, entry, loc);
if (result == -1)
{
@@ -245,52 +275,77 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
this->allocator_->malloc (sizeof (ACE_Hash_Map_Entry<EXT_ID, INT_ID>)),
-1);
- this->table_[loc] =
- new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id, int_id, this->table_[loc]);
+ this->table_[loc].next_ = entry =
+ new (ptr) ACE_Hash_Map_Entry<EXT_ID, INT_ID> (ext_id,
+ int_id,
+ this->table_[loc].next_,
+ &this->table_[loc]);
this->cur_size_++;
return 0;
}
else
{
- temp->int_id_ = int_id;
+ entry->int_id_ = int_id;
return 1;
}
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp;
+
+ return this->trybind_i (ext_id, int_id, temp);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
return this->trybind_i (ext_id, int_id);
}
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind (const EXT_ID &ext_id,
+ INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ return this->trybind_i (ext_id, int_id, entry);
+}
+
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp;
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev = 0;
u_long loc;
- int result = this->shared_find (ext_id, temp, prev, loc);
+ int result = this->shared_find (ext_id, temp, loc);
if (result == -1)
{
errno = ENOENT;
return -1;
}
- else if (prev == 0)
- this->table_[loc] = this->table_[loc]->next_;
- else
- prev->next_ = temp->next_;
+
+ return this->unbind_i (temp);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry)
+{
+ entry->next_->prev_ = entry->prev_;
+ entry->prev_->next_ = entry->next_;
- int_id = temp->int_id_;
// Explicitly call the destructor.
- temp->ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry ();
- this->allocator_->free (temp);
+ entry->ACE_Hash_Map_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_Entry ();
+ this->allocator_->free (entry);
this->cur_size_--;
return 0;
}
@@ -305,7 +360,7 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -320,22 +375,27 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind (const EXT_ID &ext_id)
return this->unbind_i (ext_id) == -1 ? -1 : 0;
}
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ return this->unbind_i (entry) == -1 ? -1 : 0;
+}
+
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&prev,
u_long &loc)
{
loc = this->hash (ext_id) % this->total_size_;
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc];
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *temp = this->table_[loc].next_;
- for (;
- temp != 0 && this->equal (temp->ext_id_, ext_id) == 0;
- temp = temp->next_)
- prev = temp;
+ while (temp != &this->table_[loc] && this->equal (temp->ext_id_, ext_id) == 0)
+ temp = temp->next_;
- if (temp == 0)
+ if (temp == &this->table_[loc])
{
errno = ENOENT;
return -1;
@@ -348,17 +408,8 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_i
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
-ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry,
- u_long &loc)
-{
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev;
- return this->shared_find (ext_id, entry, prev, loc);
-}
-
-template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry;
@@ -383,7 +434,7 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -399,37 +450,80 @@ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find (const EXT_ID &ext_id)
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
-ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
- const INT_ID &int_id,
- EXT_ID &old_ext_id,
- INT_ID &old_int_id)
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i (const EXT_ID &ext_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
{
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *node;
+ u_long dummy;
+ return this->shared_find (ext_id, entry, dummy);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find (const EXT_ID &ext_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
+ ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+ return this->find_i (ext_id, entry);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
u_long dummy;
- if (this->shared_find (ext_id, node, dummy) == -1)
+ if (this->shared_find (ext_id, entry, dummy) == -1)
return this->bind_i (ext_id, int_id);
else
{
- old_ext_id = node->ext_id_;
- old_int_id = node->int_id_;
- node->ext_id_ = ext_id;
- node->int_id_ = int_id;
+ old_ext_id = entry->ext_id_;
+ old_int_id = entry->int_id_;
+ entry->ext_id_ = ext_id;
+ entry->int_id_ = int_id;
return 1;
}
}
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id)
+{
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *node;
+
+ return this->rebind_i (ext_id,
+ int_id,
+ old_ext_id,
+ old_int_id,
+ node);
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind (const EXT_ID &ext_id,
- const INT_ID &int_id,
- EXT_ID &old_ext_id,
- INT_ID &old_int_id)
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id)
{
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
return this->rebind_i (ext_id, int_id, old_ext_id, old_int_id);
}
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ return this->rebind_i (ext_id, int_id, old_ext_id, old_int_id, entry);
+}
+
template <class EXT_ID, class INT_ID, class ACE_LOCK> void
ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
{
@@ -447,7 +541,7 @@ ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::ACE_Hash_Map_Iterator (ACE_Hash
{
if (this->map_man_.table_ != 0)
{
- this->next_ = this->map_man_.table_[0];
+ this->next_ = &this->map_man_.table_[this->index_];
this->advance ();
}
}
@@ -459,7 +553,7 @@ ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::next (ACE_Hash_Map_Entry<EXT_ID
if (this->map_man_.table_ != 0
&& this->index_ < this->map_man_.total_size_
- && this->next_ != 0)
+ && this->next_ != &this->map_man_.table_[this->index_])
{
entry = this->next_;
return 1;
@@ -475,7 +569,7 @@ ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::done (void) const
if (this->map_man_.table_ != 0
&& this->index_ < this->map_man_.total_size_
- && this->next_ != 0)
+ && this->next_ != &this->map_man_.table_[this->index_])
return 0;
else
return 1;
@@ -489,17 +583,97 @@ ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::advance (void)
if (this->map_man_.table_ == 0)
return -1;
- if (this->next_ != 0)
+ if (this->next_->next_ != &this->map_man_.table_[this->index_])
this->next_ = this->next_->next_;
else
while (++this->index_ < this->map_man_.total_size_)
- if (this->map_man_.table_[this->index_] != 0)
- {
- this->next_ = this->map_man_.table_[this->index_];
- break;
- }
+ {
+ this->next_ = &this->map_man_.table_[this->index_];
+ if (this->next_->next_ != &this->map_man_.table_[this->index_])
+ {
+ this->next_ = this->map_man_.table_[this->index_].next_;
+ break;
+ }
+ }
+
+ return this->index_ < this->map_man_.total_size_
+ && this->next_ != &this->map_man_.table_[this->index_];
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> void
+ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
+{
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "next_ = %d", this->next_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK>
+ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::ACE_Hash_Map_Reverse_Iterator (ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK> &mm)
+ : map_man_ (mm),
+ index_ (mm.total_size_ - 1),
+ next_ (0)
+{
+ if (this->map_man_.table_ != 0)
+ {
+ this->next_ = &this->map_man_.table_[this->index_];
+ this->advance ();
+ }
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::next (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry)
+{
+ ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->map_man_.lock_, -1);
- return this->index_ < this->map_man_.total_size_ && this->next_ != 0;
+ if (this->map_man_.table_ != 0
+ && this->index_ >= 0
+ && this->next_ != &this->map_man_.table_[this->index_])
+ {
+ entry = this->next_;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::done (void) const
+{
+ ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->map_man_.lock_, -1);
+
+ if (this->map_man_.table_ != 0
+ && this->index_ >= 0
+ && this->next_ != &this->map_man_.table_[this->index_])
+ return 0;
+ else
+ return 1;
+}
+
+template <class EXT_ID, class INT_ID, class ACE_LOCK> int
+ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::advance (void)
+{
+ ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->map_man_.lock_, -1);
+
+ if (this->map_man_.table_ == 0)
+ return -1;
+
+ if (this->next_->prev_ != &this->map_man_.table_[this->index_])
+ this->next_ = this->next_->prev_;
+ else
+ while (--this->index_ >= 0)
+ {
+ this->next_ = &this->map_man_.table_[this->index_];
+ if (this->next_->prev_ != &this->map_man_.table_[this->index_])
+ {
+ this->next_ = this->map_man_.table_[this->index_].prev_;
+ break;
+ }
+ }
+
+ return this->index_ >= 0
+ && this->next_ != &this->map_man_.table_[this->index_];
}
#endif /* ACE_HASH_MAP_MANAGER_C */
diff --git a/ace/Hash_Map_Manager.h b/ace/Hash_Map_Manager.h
index 8174f602242..feb1005b910 100644
--- a/ace/Hash_Map_Manager.h
+++ b/ace/Hash_Map_Manager.h
@@ -28,12 +28,14 @@ class ACE_Hash_Map_Entry
{
public:
// = Initialization and termination methods.
- ACE_Hash_Map_Entry (void);
- // Default constructor.
-
ACE_Hash_Map_Entry (const EXT_ID &ext_id,
const INT_ID &int_id,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *ptr = 0);
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next = 0,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev = 0);
+ // Constructor.
+
+ ACE_Hash_Map_Entry (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev);
// Constructor.
~ACE_Hash_Map_Entry (void);
@@ -48,6 +50,9 @@ public:
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next_;
// Pointer to the next item in the bucket of overflow nodes.
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *prev_;
+ // Pointer to the prev item in the bucket of overflow nodes.
+
void dump (void) const;
// Dump the state of an object.
};
@@ -56,6 +61,10 @@ public:
template <class EXT_ID, class INT_ID, class ACE_LOCK>
class ACE_Hash_Map_Iterator;
+// Forward decl.
+template <class EXT_ID, class INT_ID, class ACE_LOCK>
+class ACE_Hash_Map_Reverse_Iterator;
+
template <class EXT_ID, class INT_ID, class ACE_LOCK>
class ACE_Hash_Map_Manager
// = TITLE
@@ -72,9 +81,13 @@ class ACE_Hash_Map_Manager
// providing an ACE_Allocator with a persistable memory pool
{
friend class ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>;
+ friend class ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>;
public:
+ typedef EXT_ID KEY;
+ typedef INT_ID VALUE;
typedef ACE_Hash_Map_Entry<EXT_ID, INT_ID> ENTRY;
typedef ACE_Hash_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK> ITERATOR;
+ typedef ACE_Hash_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK> REVERSE_ITERATOR;
// = Initialization and termination methods.
@@ -96,6 +109,20 @@ public:
~ACE_Hash_Map_Manager (void);
// Initialize a <Hash_Map_Manager> with size <length>.
+ int bind (const EXT_ID &item,
+ const INT_ID &int_id);
+ // Associate <ext_id> with <int_id>. If <ext_id> is already in the
+ // map then the <ACE_Hash_Map_Entry> is not changed. Returns 0 if a
+ // new entry is bound successfully, returns 1 if an attempt is made
+ // to bind an existing entry, and returns -1 if failures occur.
+
+ int bind (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Same as a normal bind, except the map entry is also passed back
+ // to the caller. The entry in this case will either be the newly
+ // created entry, or the existing one.
+
int trybind (const EXT_ID &ext_id,
INT_ID &int_id);
// Associate <ext_id> with <int_id> if and only if <ext_id> is not
@@ -104,12 +131,12 @@ public:
// if a new entry is bound successfully, returns 1 if an attempt is
// made to bind an existing entry, and returns -1 if failures occur.
- int bind (const EXT_ID &item,
- const INT_ID &int_id);
- // Associate <ext_id> with <int_id>. If <ext_id> is already in the
- // map then the <ACE_Hash_Map_Entry> is not changed. Returns 0 if a
- // new entry is bound successfully, returns 1 if an attempt is made
- // to bind an existing entry, and returns -1 if failures occur.
+ int trybind (const EXT_ID &ext_id,
+ INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Same as a normal trybind, except the map entry is also passed
+ // back to the caller. The entry in this case will either be the
+ // newly created entry, or the existing one.
int rebind (const EXT_ID &ext_id,
const INT_ID &int_id,
@@ -124,7 +151,16 @@ public:
// bound successfully, returns 1 if an existing entry was rebound,
// and returns -1 if failures occur.
- int find (const EXT_ID &item,
+ int rebind (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Same as a normal rebind, except the map entry is also passed back
+ // to the caller. The entry in this case will either be the newly
+ // created entry, or the existing one.
+
+ int find (const EXT_ID &ext_id,
INT_ID &int_id);
// Locate <ext_id> and pass out parameter via <int_id>. If found,
// return 0, returns -1 if not found.
@@ -132,6 +168,11 @@ public:
int find (const EXT_ID &ext_id);
// Returns 0 if the <ext_id> is in the mapping, otherwise -1.
+ int find (const EXT_ID &ext_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Locate <ext_id> and pass out parameter via <entry>. If found,
+ // return 0, returns -1 if not found.
+
int unbind (const EXT_ID &ext_id);
// Unbind (remove) the <ext_id> from the map. Don't return the
// <int_id> to the caller (this is useful for collections where the
@@ -142,6 +183,9 @@ public:
// Break any association of <ext_id>. Returns the value of <int_id>
// in case the caller needs to deallocate memory.
+ int unbind (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry);
+ // Remove entry from map.
+
size_t current_size (void);
// Return the current size of the map.
@@ -164,16 +208,39 @@ protected:
// = These methods assume locks are held by private methods.
- int bind_i (const EXT_ID &ext_id, const INT_ID &int_id);
- // Performs the binding of <ext_id> to <int_id>. Must be
- // called with locks held.
-
- int rebind_i (const EXT_ID &ext_id, const INT_ID &int_id,
- EXT_ID &old_ext_id, INT_ID &old_int_id);
- // Performs a rebinding of <ext_it> to <int_id>. Must be called
- // with locks held.
-
- int find_i (const EXT_ID &ext_id, INT_ID &int_id);
+ int bind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id);
+ // Performs bind. Must be called with locks held.
+
+ int bind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Performs bind. Must be called with locks held.
+
+ int trybind_i (const EXT_ID &ext_id,
+ INT_ID &int_id);
+ // Performs trybind. Must be called with locks held.
+
+ int trybind_i (const EXT_ID &ext_id,
+ INT_ID &int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Performs trybind. Must be called with locks held.
+
+ int rebind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id);
+ // Performs rebind. Must be called with locks held.
+
+ int rebind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Performs rebind. Must be called with locks held.
+
+ int find_i (const EXT_ID &ext_id,
+ INT_ID &int_id);
// Performs a find of <int_id> using <ext_id> as the key. Must be
// called with locks held.
@@ -181,20 +248,25 @@ protected:
// Performs a find using <ext_id> as the key. Must be called with
// locks held.
- int unbind_i (const EXT_ID &ext_id, INT_ID &int_id);
- // Performs an unbind of <int_id> using <ext_id> as the key. Must
- // be called with locks held.
+ int find_i (const EXT_ID &ext_id,
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry);
+ // Performs a find using <ext_id> as the key. Must be called with
+ // locks held.
+
+ int unbind_i (const EXT_ID &ext_id,
+ INT_ID &int_id);
+ // Performs unbind. Must be called with locks held.
int unbind_i (const EXT_ID &ext_id);
- // Performs an unbind using <ext_id> as the key. Must be called
- // with locks held.
+ // Performs unbind. Must be called with locks held.
- int trybind_i (const EXT_ID &ext_id, INT_ID &int_id);
- // Performs a conditional bind of <int_id> using <ext_id> as the
- // key. Must be called with locks held.
+ int unbind_i (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *entry);
+ // Performs unbind. Must be called with locks held.
- int resize_i (size_t size);
- // Resize the map. Must be called with locks held.
+ int create_buckets (size_t size);
+ // Resize the map. Must be called with locks held. Note, that this
+ // method should never be called more than once or else all the
+ // hashing will get screwed up as the size will change.
int close_i (void);
// Close down a <Map_Manager>. Must be called with
@@ -210,14 +282,9 @@ private:
int shared_find (const EXT_ID &ext_id,
ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry,
u_long &loc);
- int shared_find (const EXT_ID &ext_id,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&entry,
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&prev,
- u_long &loc);
// Returns the <ACE_Hash_Map_Entry> that corresponds to <ext_id>.
- // prev points to the previous entry.
- ACE_Hash_Map_Entry<EXT_ID, INT_ID> **table_;
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *table_;
// Array of <ACE_Hash_Map_Entry> *s, each of which points to the
// beginning of a linked list of <EXT_ID>s that hash to that bucket.
@@ -270,6 +337,48 @@ private:
// table slot.
};
+template <class EXT_ID, class INT_ID, class ACE_LOCK>
+class ACE_Hash_Map_Reverse_Iterator
+ // = TITLE
+ // Iterator for the ACE_Hash_Map_Manager.
+ //
+ // = DESCRIPTION
+{
+public:
+ // = Initialization method.
+ ACE_Hash_Map_Reverse_Iterator (ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK> &mm);
+
+ // = Iteration methods.
+
+ int next (ACE_Hash_Map_Entry<EXT_ID, INT_ID> *&next_entry);
+ // Pass back the next <entry> that hasn't been seen in the Set.
+ // Returns 0 when all items have been seen, else 1.
+
+ int done (void) const;
+ // Returns 1 when all items have been seen, else 0.
+
+ int advance (void);
+ // Move forward by one element in the set. Returns 0 when all the
+ // items in the set have been seen, else 1.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Hash_Map_Manager<EXT_ID, INT_ID, ACE_LOCK> &map_man_;
+ // Map we are iterating over.
+
+ ssize_t index_;
+ // Keeps track of how far we've advanced in the table.
+
+ ACE_Hash_Map_Entry<EXT_ID, INT_ID> *next_;
+ // Keeps track of how far we've advanced in a linked list in each
+ // table slot.
+};
+
#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Hash_Map_Manager.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
diff --git a/ace/Map_Manager.cpp b/ace/Map_Manager.cpp
index 92b8c8ac105..a188659556b 100644
--- a/ace/Map_Manager.cpp
+++ b/ace/Map_Manager.cpp
@@ -16,7 +16,7 @@
ACE_ALLOC_HOOK_DEFINE(ACE_Map_Entry)
-template <class EXT_ID, class INT_ID>
+ template <class EXT_ID, class INT_ID>
ACE_Map_Entry<EXT_ID, INT_ID>::~ACE_Map_Entry (void)
{
// No-op just to keep some compilers happy...
@@ -34,7 +34,7 @@ ACE_Map_Entry<EXT_ID, INT_ID>::dump (void) const
ACE_ALLOC_HOOK_DEFINE(ACE_Map_Manager)
-template <class EXT_ID, class INT_ID, class ACE_LOCK> void
+ template <class EXT_ID, class INT_ID, class ACE_LOCK> void
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump");
@@ -49,7 +49,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
template <class EXT_ID, class INT_ID, class ACE_LOCK>
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::ACE_Map_Manager (size_t size,
- ACE_Allocator *alloc)
+ ACE_Allocator *alloc)
: search_structure_ (0),
allocator_ (0),
total_size_ (0),
@@ -159,7 +159,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::free_search_structure (void)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::open (size_t size,
- ACE_Allocator *alloc)
+ ACE_Allocator *alloc)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::open");
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -178,7 +178,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::open (size_t size,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
- int &first_free)
+ int &first_free)
{
// See if the entry is already there, keeping track of the first
// free slot.
@@ -202,7 +202,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::equal (const EXT_ID &id1,
- const EXT_ID &id2)
+ const EXT_ID &id2)
{
return id1 == id2;
}
@@ -231,8 +231,8 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_find (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_bind (const EXT_ID &ext_id,
- const INT_ID &int_id,
- int first_free)
+ const INT_ID &int_id,
+ int first_free)
{
if (first_free > -1)
{
@@ -268,7 +268,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_bind (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i");
int first_free = -1;
@@ -289,7 +289,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind_i (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::trybind");
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -322,7 +322,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i");
@@ -344,7 +344,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind_i (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
- const INT_ID &int_id)
+ const INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i");
@@ -378,9 +378,9 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind_i (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
- const INT_ID &int_id,
- EXT_ID &old_ext_id,
- INT_ID &old_int_id)
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i");
@@ -410,7 +410,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind_i (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find_i");
@@ -473,7 +473,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::shared_unbind (const EXT_ID &ext_id)
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::unbind");
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -483,7 +483,7 @@ 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> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind (const EXT_ID &ext_id,
- const INT_ID &int_id)
+ const INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind");
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -493,9 +493,9 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::bind (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind (const EXT_ID &ext_id,
- const INT_ID &int_id,
- EXT_ID &old_ext_id,
- INT_ID &old_int_id)
+ const INT_ID &int_id,
+ EXT_ID &old_ext_id,
+ INT_ID &old_int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind");
ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -505,7 +505,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::rebind (const EXT_ID &ext_id,
template <class EXT_ID, class INT_ID, class ACE_LOCK> int
ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find (const EXT_ID &ext_id,
- INT_ID &int_id)
+ INT_ID &int_id)
{
ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::find");
ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
@@ -550,7 +550,7 @@ ACE_Map_Manager<EXT_ID, INT_ID, ACE_LOCK>::total_size (void)
ACE_ALLOC_HOOK_DEFINE(ACE_Map_Iterator)
-template <class EXT_ID, class INT_ID, class ACE_LOCK> void
+ template <class EXT_ID, class INT_ID, class ACE_LOCK> void
ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
{
ACE_TRACE ("ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump");
@@ -606,7 +606,7 @@ ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::advance (void)
for (++this->next_;
size_t (this->next_) < this->map_man_.cur_size_
- && this->map_man_.search_structure_[this->next_].is_free_;
+ && this->map_man_.search_structure_[this->next_].is_free_;
this->next_++)
continue;
return size_t (this->next_) < this->map_man_.cur_size_;
@@ -614,7 +614,7 @@ ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>::advance (void)
ACE_ALLOC_HOOK_DEFINE(ACE_Map_Reverse_Iterator)
-template <class EXT_ID, class INT_ID, class ACE_LOCK> void
+ template <class EXT_ID, class INT_ID, class ACE_LOCK> void
ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump (void) const
{
ACE_TRACE ("ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::dump");
@@ -667,7 +667,7 @@ ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>::advance (void)
for (--this->next_;
this->next_ >= 0
- && this->map_man_.search_structure_[this->next_].is_free_;
+ && this->map_man_.search_structure_[this->next_].is_free_;
this->next_--)
continue;
return this->next_ >= 0;
diff --git a/ace/Map_Manager.h b/ace/Map_Manager.h
index 62eaf46bfa7..716bf84816d 100644
--- a/ace/Map_Manager.h
+++ b/ace/Map_Manager.h
@@ -77,6 +77,8 @@ friend class ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK>;
friend class ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK>;
public:
// = Traits.
+ typedef EXT_ID KEY;
+ typedef INT_ID VALUE;
typedef ACE_Map_Entry<EXT_ID, INT_ID> ENTRY;
typedef ACE_Map_Iterator<EXT_ID, INT_ID, ACE_LOCK> ITERATOR;
typedef ACE_Map_Reverse_Iterator<EXT_ID, INT_ID, ACE_LOCK> REVERSE_ITERATOR;
diff --git a/ace/Strategies.cpp b/ace/Strategies.cpp
index ec068c18c33..76e79064118 100644
--- a/ace/Strategies.cpp
+++ b/ace/Strategies.cpp
@@ -76,5 +76,9 @@ ACE_Reactor_Notification_Strategy::reactor (ACE_Reactor *r)
this->reactor_ = r;
}
+ACE_Connection_Recycling_Strategy::~ACE_Connection_Recycling_Strategy (void)
+{
+}
+
#endif /* ACE_STRATEGIES_C */
diff --git a/ace/Strategies.h b/ace/Strategies.h
index 07eb421db1d..10aa0252a37 100644
--- a/ace/Strategies.h
+++ b/ace/Strategies.h
@@ -79,6 +79,24 @@ protected:
ACE_Reactor *reactor_;
};
+class ACE_Export ACE_Connection_Recycling_Strategy
+ // = TITLE
+ //
+ // Defines the interface for a connection recycler.
+ //
+{
+public:
+
+ virtual ~ACE_Connection_Recycling_Strategy (void);
+ // Virtual Destructor
+
+ virtual int purge (const void *recycling_act) = 0;
+ // Remove from cache.
+
+ virtual int cache (const void *recycling_act) = 0;
+ // Add to cache.
+};
+
// This needs to come here to avoid circular dependencies.
#include "ace/Strategies_T.h"
diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp
index f755300e33b..90075cd0a23 100644
--- a/ace/Strategies_T.cpp
+++ b/ace/Strategies_T.cpp
@@ -709,63 +709,40 @@ ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::dump (void) const
ACE_Scheduling_Strategy<SVC_HANDLER>::dump ();
}
-// Return the address of <b> by default. This should typically be
-// specialized!
-
-template<class ADDR_T, class SVC_HANDLER> size_t
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::hash_i (const ADDR_T &b) const
-{
- size_t tmp;
- const void *a = (void *) &b;
- (void) ACE_OS::memcpy ((void *) &tmp, (void *) &a, sizeof tmp);
- return tmp;
-}
-
-// Default definition for type comparison operation (returns values
-// corresponding to those returned by <memcmp>/<strcmp>). This should
-// typically be specialized.
-
-template<class ADDR_T, class SVC_HANDLER> int
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::compare_i (const ADDR_T &b1,
- const ADDR_T &b2) const
-{
- if (&b1 == &b2)
- return 0;
- else
- return ACE_OS::memcmp (&b1, &b2, sizeof b1);
-}
-
-// Automatic conversion operators
-template<class ADDR_T, class SVC_HANDLER>
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::operator ADDR_T& (void)
+template<class ADDR_T> size_t
+ACE_Hash_Addr<ADDR_T>::hash_i (const ADDR_T &b) const
{
- return addr_;
+ ACE_UNUSED_ARG (b);
+ return 0;
}
-template<class ADDR_T, class SVC_HANDLER>
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::operator const ADDR_T& (void) const
+template<class ADDR_T>
+ACE_Hash_Addr<ADDR_T>::ACE_Hash_Addr (void)
+ : hash_value_ (0),
+ recyclable_ (0)
{
- return addr_;
}
-template<class ADDR_T, class SVC_HANDLER>
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::ACE_Hash_Addr (void)
+template<class ADDR_T>
+ACE_Hash_Addr<ADDR_T>::ACE_Hash_Addr (const ADDR_T &a)
: hash_value_ (0),
- svc_handler_ (0)
+ recyclable_ (0),
+ addr_ (a)
{
+ this->hash ();
}
-template<class ADDR_T, class SVC_HANDLER>
-ACE_Hash_Addr<ADDR_T, SVC_HANDLER>::ACE_Hash_Addr (const ADDR_T &a, SVC_HANDLER *sh)
+template<class ADDR_T>
+ACE_Hash_Addr<ADDR_T>::ACE_Hash_Addr (const ADDR_T &a, int recyclable)
: hash_value_ (0),
- svc_handler_ (sh),
+ recyclable_ (recyclable),
addr_ (a)
{
- (void) this->hash ();
+ this->hash ();
}
-template<class ADDR_T, class SVC_HANDLER> u_long
-ACE_Hash_Addr<ADDR_T,SVC_HANDLER>::hash (void) const
+template<class ADDR_T> u_long
+ACE_Hash_Addr<ADDR_T>::hash (void) const
{
// In doing the check below, we take chance of paying a performance
// price when the hash value is zero. But, that will (hopefully)
@@ -774,19 +751,30 @@ ACE_Hash_Addr<ADDR_T,SVC_HANDLER>::hash (void) const
// relative to the simple comparison.
if (this->hash_value_ == 0)
- ((ACE_Hash_Addr<ADDR_T, SVC_HANDLER> *) this)->hash_value_ = this->hash_i (addr_);
+ ((ACE_Hash_Addr<ADDR_T> *) this)->hash_value_ = this->hash_i (addr_);
return this->hash_value_;
}
-template<class ADDR_T, class SVC_HANDLER> int
-ACE_Hash_Addr<ADDR_T,SVC_HANDLER>::operator== (const ACE_Hash_Addr<ADDR_T, SVC_HANDLER> &rhs) const
+template<class ADDR_T> int
+ACE_Hash_Addr<ADDR_T>::operator== (const ACE_Hash_Addr<ADDR_T> &rhs) const
{
- if (svc_handler_ == 0)
- return this->compare_i (addr_, rhs.addr_) == 0;
- else
- return svc_handler_->in_use () == 0
- && this->compare_i (addr_, rhs.addr_) == 0;
+ if (!this->recyclable ())
+ return 0;
+ else
+ return this->addr_ == rhs.addr_;
+}
+
+template<class ADDR_T> int
+ACE_Hash_Addr<ADDR_T>::recyclable (void) const
+{
+ return this->recyclable_;
+}
+
+template<class ADDR_T> void
+ACE_Hash_Addr<ADDR_T>::recyclable (int new_value)
+{
+ this->recyclable_ = new_value;
}
template <class SVC_HANDLER> int
@@ -806,42 +794,111 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_s
int flags,
int perms)
{
- ACE_Hash_Addr<ACE_PEER_CONNECTOR_ADDR, SVC_HANDLER> search_addr (remote_addr);
-
- // Synchronization is required here as the setting of the in_use bit
- // in the service handler must be done atomically with the finding
- // and binding of the service handler in the cache.
+ // Synchronization is required here as the setting of the recyclable
+ // bit must be done atomically with the finding and binding of the
+ // service handler in the cache.
ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1);
- // Try to find the addres in the cache. Only if we don't find it do
- // we create a new <SVC_HANDLER> and connect it with the server.
- if (this->connection_cache_.find (search_addr, sh) == -1)
+ // Try to find the address in the cache. Only if we don't find it
+ // do we create a new <SVC_HANDLER> and connect it with the server.
+
+ ADDRESS search_addr (remote_addr);
+ CONNECTION_MAP_ENTRY *entry = 0;
+
+ if (this->connection_cache_.find (search_addr, entry) == -1)
{
ACE_NEW_RETURN (sh, SVC_HANDLER, -1);
// Actively establish the connection. This is a timed blocking
// connect.
- if (ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_svc_handler
- (sh,
- remote_addr,
- timeout,
- local_addr,
- reuse_addr,
- flags,
- perms) == -1)
- return -1;
+ if (CONNECT_STRATEGY::connect_svc_handler (sh,
+ remote_addr,
+ timeout,
+ local_addr,
+ reuse_addr,
+ flags,
+ perms) == -1)
+ {
+ // If connect() failed because of timeouts, we have to
+ // reject the connection entirely. This is necessary since
+ // currently there is no way for the non-blocking connects
+ // to complete and for the <Connector> to notify the cache
+ // of the completion of connect().
+ if (errno == EWOULDBLOCK)
+ errno = ENOTSUP;
+ return -1;
+ }
// Insert the new SVC_HANDLER instance into the cache.
else
- {
- ACE_Hash_Addr<ACE_PEER_CONNECTOR_ADDR, SVC_HANDLER> server_addr (remote_addr,
- sh);
- if (this->connection_cache_.bind (server_addr, sh) == -1)
+ {
+ ADDRESS server_addr (remote_addr);
+ if (this->connection_cache_.bind (server_addr,
+ sh,
+ entry) == -1)
return -1;
+
+ // Set the recycler and the recycling act
+ sh->recycler (this, entry);
}
}
+ else
+ // We found a cached svc_handler.
+ {
+ // Get the cached <svc_handler>
+ sh = entry->int_id_;
+
+ // Tell the <svc_handler> that it should prepare itself for being
+ // recycled.
+ sh->recycle ();
+ }
+
+ // Mark the <svc_handler> in the cache as being <in_use>.
+ // Therefore recyclable is 0.
+ entry->ext_id_.recyclable (0);
+
+ return 0;
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX>
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::~ACE_Cached_Connect_Strategy (void)
+{
+ // Close down all cached service handlers.
+ CONNECTION_MAP_ENTRY *entry;
+ for (CONNECTION_MAP_ITERATOR iterator (connection_cache_);
+ iterator.next (entry);
+ iterator.advance ())
+ entry->int_id_->close ();
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache (const void *recycling_act)
+{
+ // Synchronization is required here as the setting of the recyclable
+ // bit must be done atomically with respect to other threads that
+ // are querying the cache.
+ ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1);
- sh->in_use (1);
+ // The wonders and perils of ACT
+ CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
+
+ // Mark the <svc_handler> in the cache as not being <in_use>.
+ // Therefore recyclable is 1.
+ entry->ext_id_.recyclable (1);
+
return 0;
}
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge (const void *recycling_act)
+{
+ // Excluded other threads from changing cache while we take this
+ // entry out.
+ ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1);
+
+ // The wonders and perils of ACT
+ CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
+
+ return this->connection_cache_.unbind (entry);
+}
+
#endif /* ACE_STRATEGIES_T_C */
diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h
index e3a492de8d8..8f265fa42b9 100644
--- a/ace/Strategies_T.h
+++ b/ace/Strategies_T.h
@@ -509,70 +509,60 @@ public:
// This is a no-op.
};
-template <class ADDR_T, class SVC_HANDLER>
+template <class ADDR_T>
class ACE_Hash_Addr
// = TITLE
// Internal class to compute hash values on addresses in
// <ACE_Cached_Connect_Strategy>.
//
// = DESCRIPTION
- // Intended to be used as a key to an <ACE_Hash_Map_Manager>. The
- // <SVC_HANDLER> class is expected to implement the following
- // methods:
- // = BEGIN<INDENT>
- // = BEGIN<CODE>
- // int in_use() const;
- // void in_use(int is_used);
- // = END<CODE>
- // = END<INDENT>
- // Likewise, the <ADDR_T> parameter/subclass is typically
- // <ACE_INET_Addr>. It is expected to implement operator==().
+ //
+ // Intended to be used as a key to an <ACE_Hash_Map_Manager>.
+ // <ADDR_T> parameter/subclass is typically <ACE_INET_Addr>. It
+ // is expected to implement operator==().
{
public:
// = Initialization methods.
ACE_Hash_Addr (void);
// Default constructor.
- ACE_Hash_Addr (const ADDR_T &a,
- SVC_HANDLER *sh = 0);
+ ACE_Hash_Addr (const ADDR_T &a);
// Pre-compute hash value.
-
+
+ ACE_Hash_Addr (const ADDR_T &a, int recyclable);
+ // Pre-compute hash value.
+
u_long hash (void) const;
// Computes and returns hash value. This "caches" the hash value to
// improve performance.
- int operator== (const ACE_Hash_Addr<ADDR_T, SVC_HANDLER> &rhs) const;
+ int operator== (const ACE_Hash_Addr<ADDR_T> &rhs) const;
// Compares two hash values.
- operator ADDR_T& (void);
- operator const ADDR_T& (void) const;
- // Conversion operators allowing <ACE_Hash_Addr> to be used in place
- // of an <{ADDR_T}>.
+ // = Set/Get the recyclable bit
+ int recyclable (void) const;
+ void recyclable (int new_value);
private:
size_t hash_i (const ADDR_T &) const;
// This is the method that actually performs the non-cached hash
// computation. It should typically be specialized.
- int compare_i (const ADDR_T &b1, const ADDR_T &bs) const;
- // Compares two hash values. This is the method that actually
- // performs the non-cached hash computation. It should typically be
- // specialized.
-
u_long hash_value_;
// Pre-computed hash-value.
- SVC_HANDLER *svc_handler_;
- // Pointer to associated <SVC_HANDLER> which is used to detect
- // "in-use" <SVC_HANDLER>s so we can ignore them. See <DESCRIPTION>
- // for details on methods required on <SVC_HANDLER>.
+ int recyclable_;
+ // We need to know if the <SVC_HANDLER> is "in-use". If it is, we
+ // can operator==() can skip the comparison.
ADDR_T addr_;
// The underlying address.
};
template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX>
-class ACE_Cached_Connect_Strategy : public ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+class ACE_Cached_Connect_Strategy
+ : public ACE_Connection_Recycling_Strategy,
+ public ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
// = TITLE
// A connection strategy which caches connections to peers
// (represented by <SVC_HANDLER> instances), thereby allowing
@@ -603,6 +593,10 @@ class ACE_Cached_Connect_Strategy : public ACE_Connect_Strategy<SVC_HANDLER, ACE
// <ACE_Hash_Addr>.
{
public:
+
+ virtual ~ACE_Cached_Connect_Strategy (void);
+ // Destructor
+
virtual int connect_svc_handler (SVC_HANDLER *&sh,
const ACE_PEER_CONNECTOR_ADDR &remote_addr,
ACE_Time_Value *timeout,
@@ -623,8 +617,24 @@ public:
// to consider enhancing the interface at some point so that this also
// controls re-use of the cache.}>
+ virtual int purge (const void *recycling_act);
+ // Remove from cache.
+
+ virtual int cache (const void *recycling_act);
+ // Add to cache.
+
private:
- ACE_Hash_Map_Manager <ACE_Hash_Addr <ACE_PEER_CONNECTOR_ADDR,SVC_HANDLER>, SVC_HANDLER*, ACE_Null_Mutex> connection_cache_;
+
+ // = Super class
+ typedef ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> CONNECT_STRATEGY;
+
+ // = Typedefs for managing the map
+ typedef ACE_Hash_Addr<ACE_PEER_CONNECTOR_ADDR> ADDRESS;
+ typedef ACE_Hash_Map_Manager <ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> CONNECTION_MAP;
+ typedef ACE_Hash_Map_Iterator <ADDRESS, SVC_HANDLER *, ACE_Null_Mutex> CONNECTION_MAP_ITERATOR;
+ typedef ACE_Hash_Map_Entry<ADDRESS, SVC_HANDLER *> CONNECTION_MAP_ENTRY;
+
+ CONNECTION_MAP connection_cache_;
// Table that maintains the cache of connected <SVC_HANDLER>s.
MUTEX lock_;
diff --git a/ace/Svc_Handler.cpp b/ace/Svc_Handler.cpp
index fc0075c9ccb..ec78f430c5a 100644
--- a/ace/Svc_Handler.cpp
+++ b/ace/Svc_Handler.cpp
@@ -8,6 +8,7 @@
#include "ace/Svc_Handler.h"
#include "ace/Dynamic.h"
#include "ace/Object_Manager.h"
+#include "ace/Strategies.h"
#if !defined (__ACE_INLINE__)
#include "ace/Svc_Handler.i"
@@ -111,7 +112,10 @@ template <PR_ST_1, ACE_SYNCH_1>
ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler (ACE_Thread_Manager *tm,
ACE_Message_Queue<ACE_SYNCH_2> *mq,
ACE_Reactor *reactor)
- : ACE_Task<ACE_SYNCH_2> (tm, mq)
+ : ACE_Task<ACE_SYNCH_2> (tm, mq),
+ closing_ (0),
+ recycler_ (0),
+ recycling_act_ (0)
{
ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler");
@@ -128,7 +132,6 @@ ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler (ACE_Thread_Manager *tm,
if (this->dynamic_)
// Make sure to reset the flag
ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2>::instance()->reset ();
- this->closing_ = 0;
}
// Default behavior for a ACE_Svc_Handler object is to be registered with
@@ -180,6 +183,10 @@ ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::shutdown (void)
this->reactor ()->remove_handler (this, mask);
}
+ // Remove self from the recycler.
+ if (this->recycler ())
+ this->recycler ()->purge (this->recycling_act_);
+
this->peer ().close ();
}
@@ -275,6 +282,40 @@ ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::info (char **, size_t) const
ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::info");
return -1;
}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::idle (u_long flags)
+{
+ if (this->recycler ())
+ return this->recycler ()->cache (this->recycling_act_);
+ else
+ return this->close (flags);
+}
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycler (ACE_Connection_Recycling_Strategy *recycler,
+ const void *recycling_act)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycler");
+ this->recycler_ = recycler;
+ this->recycling_act_ = recycling_act;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> ACE_Connection_Recycling_Strategy *
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycler (void) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycler");
+ return this->recycler_;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycle (void *)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::recycle");
+ // By default, the object is ready and willing to be recycled.
+ return 0;
+}
+
#undef PR_ST_1
#undef PR_ST_2
#endif /* ACE_SVC_HANDLER_C */
diff --git a/ace/Svc_Handler.h b/ace/Svc_Handler.h
index 8e9289dcc3f..8e84b702298 100644
--- a/ace/Svc_Handler.h
+++ b/ace/Svc_Handler.h
@@ -17,14 +17,15 @@
#if !defined (ACE_SVC_HANDLER_H)
#define ACE_SVC_HANDLER_H
+// Forward decls.
+class ACE_Dynamic;
+class ACE_Connection_Recycling_Strategy;
+
#include "ace/Synch_Options.h"
#include "ace/Task.h"
#include "ace/Service_Config.h"
#include "ace/Synch_T.h"
-// Forward decls.
-class ACE_Dynamic;
-
template <ACE_PEER_STREAM_1, ACE_SYNCH_1>
class ACE_Svc_Handler : public ACE_Task<ACE_SYNCH_2>
// = TITLE
@@ -57,6 +58,11 @@ public:
virtual int close (u_long flags = 0);
// Object termination hook.
+ virtual int idle (u_long flags = 0);
+ // Call this method if you want to recycling the <Svc_Handler>
+ // instead of closing it. If the object does not have a recycler,
+ // it will be closed.
+
// = Dynamic linking hooks.
virtual int init (int argc, char *argv[]);
// Default version does no work and returns -1. Must be overloaded
@@ -121,6 +127,28 @@ public:
// destroy(). Unfortunately, the C++ standard doesn't allow there
// to be a public new and a private delete.
+public:
+
+ // Note: The following methods are not suppose to be public. But
+ // because friendship is *not* inherited in C++, these methods have
+ // to be public.
+
+ // = Accessors to set/get the connection recycler.
+
+ virtual void recycler (ACE_Connection_Recycling_Strategy *recycler,
+ const void *recycling_act);
+ // Set the recycler and the <recycling_act> that is used during
+ // purging and caching.
+
+ virtual ACE_Connection_Recycling_Strategy *recycler (void) const;
+ // Get the recycler.
+
+ virtual int recycle (void * = 0);
+ // Upcall made by the recycler when it is about to recycle the
+ // connection. This gives the object a chance to prepare itself for
+ // recycling. Return 0 if the object is ready for recycling, -1 on
+ // failures.
+
private:
ACE_PEER_STREAM peer_;
// Maintain connection with client.
@@ -137,6 +165,12 @@ private:
char closing_;
// Keeps track of whether we are in the process of closing (required
// to avoid circular calls to <handle_close>).
+
+ ACE_Connection_Recycling_Strategy *recycler_;
+ // Pointer to the connection recycler.
+
+ const void *recycling_act_;
+ // ACT to be used to when talking to the recycler.
};
#if defined (__ACE_INLINE__)
diff --git a/tests/Conn_Test.h b/tests/Conn_Test.h
index db0828b9758..d3efc912733 100644
--- a/tests/Conn_Test.h
+++ b/tests/Conn_Test.h
@@ -27,17 +27,4 @@ public:
int close (u_long = 0);
// Shutdown the <Svc_Handler>.
-
- void in_use (int);
- // Set the use flag (i.e., 1 means "in use", 0 means "not in use").
-
- int in_use (void);
- // Returns the current use flag.
-
- int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
- ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
-
-private:
- int in_use_;
- // Are we currently in use?
};
diff --git a/tests/Hash_Map_Manager_Test.cpp b/tests/Hash_Map_Manager_Test.cpp
index 2d5635498ae..4d9f3541a9b 100644
--- a/tests/Hash_Map_Manager_Test.cpp
+++ b/tests/Hash_Map_Manager_Test.cpp
@@ -34,19 +34,34 @@
HASH_STRING_ENTRY::ACE_Hash_Map_Entry (char *const &ext_id,
char *const &int_id,
- HASH_STRING_ENTRY *ptr)
+ HASH_STRING_ENTRY *next,
+ HASH_STRING_ENTRY *prev)
: ext_id_ (ACE_OS::strdup (ext_id)),
int_id_ (ACE_OS::strdup (int_id)),
- next_ (ptr)
+ next_ (next),
+ prev_ (prev)
{
ACE_DEBUG ((LM_DEBUG, "Creating `%s' and `%s'\n", ext_id_, int_id_));
}
+HASH_STRING_ENTRY::ACE_Hash_Map_Entry (HASH_STRING_ENTRY *next,
+ HASH_STRING_ENTRY *prev)
+ : ext_id_ (0),
+ int_id_ (0),
+ next_ (next),
+ prev_ (prev)
+{
+}
+
HASH_STRING_ENTRY::~ACE_Hash_Map_Entry (void)
{
- ACE_DEBUG ((LM_DEBUG, "Freeing `%s' and `%s'\n", ext_id_, int_id_));
- ACE_OS::free (ext_id_);
- ACE_OS::free (int_id_);
+ char *key = ext_id_;
+ char *value = int_id_;
+
+ if (key != 0 && value != 0)
+ ACE_DEBUG ((LM_DEBUG, "Freeing `%s' and `%s'\n", key, value));
+ ACE_OS::free (key);
+ ACE_OS::free (value);
}
// We need this template specialization since KEY is defined as a
diff --git a/tests/Reactor_Exceptions_Test.cpp b/tests/Reactor_Exceptions_Test.cpp
index 40685abf8f7..a64d66049c5 100644
--- a/tests/Reactor_Exceptions_Test.cpp
+++ b/tests/Reactor_Exceptions_Test.cpp
@@ -90,6 +90,10 @@ public:
}
return ret;
}
+ virtual int handle_events (ACE_Time_Value &max_wait_time)
+ {
+ return this->handle_events (&max_wait_time);
+ }
};
static int
diff --git a/tests/tests.mak b/tests/tests.mak
index ebb14c03574..a507c12764a 100644
--- a/tests/tests.mak
+++ b/tests/tests.mak
@@ -6856,6 +6856,7 @@ DEP_CPP_MESSAGE=\
{$(INCLUDE)}"\ace\OS.h"\
{$(INCLUDE)}"\ace\OS.i"\
{$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
{$(INCLUDE)}"\ace\Reactor_Impl.h"\
{$(INCLUDE)}"\ace\Service_Config.h"\
{$(INCLUDE)}"\ace\Service_Config.i"\
@@ -6897,6 +6898,9 @@ DEP_CPP_MESSAGE=\
{$(INCLUDE)}"\ace\Thread_Manager.h"\
{$(INCLUDE)}"\ace\Thread_Manager.i"\
{$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue_T.cpp"\
+ {$(INCLUDE)}"\ace\Timer_Queue_T.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue_T.i"\
{$(INCLUDE)}"\ace\Trace.h"\
{$(INCLUDE)}"\ace\Version.h"\
{$(INCLUDE)}"\ace\WFMO_Reactor.h"\
diff --git a/tests/tests.mdp b/tests/tests.mdp
index e72dfa07651..0badc0fb686 100644
--- a/tests/tests.mdp
+++ b/tests/tests.mdp
Binary files differ