diff options
author | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-10-26 01:43:14 +0000 |
---|---|---|
committer | irfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-10-26 01:43:14 +0000 |
commit | 5d3b87a68444cfe7d9b29f149feb87a907b5dec1 (patch) | |
tree | 3c9c4134b97200d8a4a900715cdfac543ebd2159 /ace | |
parent | 532c705f54375a9cc089861966d3db61bc4d5644 (diff) | |
download | ATCD-5d3b87a68444cfe7d9b29f149feb87a907b5dec1.tar.gz |
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Event_Handler.cpp | 2 | ||||
-rw-r--r-- | ace/Filecache.cpp | 15 | ||||
-rw-r--r-- | ace/Hash_Map_Manager.cpp | 362 | ||||
-rw-r--r-- | ace/Hash_Map_Manager.h | 183 | ||||
-rw-r--r-- | ace/Map_Manager.cpp | 52 | ||||
-rw-r--r-- | ace/Map_Manager.h | 2 | ||||
-rw-r--r-- | ace/Strategies.cpp | 4 | ||||
-rw-r--r-- | ace/Strategies.h | 18 | ||||
-rw-r--r-- | ace/Strategies_T.cpp | 201 | ||||
-rw-r--r-- | ace/Strategies_T.h | 72 | ||||
-rw-r--r-- | ace/Svc_Handler.cpp | 45 | ||||
-rw-r--r-- | ace/Svc_Handler.h | 40 |
12 files changed, 727 insertions, 269 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__) |