From 1ffe60f64b8c13e9bd7f5b3d9a3cbc88b84b85b5 Mon Sep 17 00:00:00 2001 From: irfan Date: Sun, 26 Oct 1997 01:43:14 +0000 Subject: *** empty log message *** --- ace/Event_Handler.cpp | 2 +- ace/Filecache.cpp | 15 +- ace/Hash_Map_Manager.cpp | 362 ++++++++++++++++++++++++++++---------- ace/Hash_Map_Manager.h | 183 +++++++++++++++---- ace/Map_Manager.cpp | 52 +++--- ace/Map_Manager.h | 2 + ace/Strategies.cpp | 4 + ace/Strategies.h | 18 ++ ace/Strategies_T.cpp | 201 +++++++++++++-------- ace/Strategies_T.h | 72 ++++---- ace/Svc_Handler.cpp | 45 ++++- ace/Svc_Handler.h | 40 ++++- tests/Conn_Test.h | 13 -- tests/Hash_Map_Manager_Test.cpp | 25 ++- tests/Reactor_Exceptions_Test.cpp | 4 + tests/tests.mak | 4 + tests/tests.mdp | Bin 2672 -> 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 - 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 -ACE_Hash_Map_Entry::ACE_Hash_Map_Entry (void) +ACE_Hash_Map_Entry::ACE_Hash_Map_Entry (ACE_Hash_Map_Entry *next, + ACE_Hash_Map_Entry *prev) + : next_ (next), + prev_ (prev) { } -template void -ACE_Hash_Map_Entry::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 ACE_Hash_Map_Entry::ACE_Hash_Map_Entry (const EXT_ID &ext_id, const INT_ID &int_id, - ACE_Hash_Map_Entry *ptr) + ACE_Hash_Map_Entry *next, + ACE_Hash_Map_Entry *prev) : ext_id_ (ext_id), int_id_ (int_id), - next_ (ptr) + next_ (next), + prev_ (prev) { } @@ -48,6 +45,15 @@ ACE_Hash_Map_Entry::~ACE_Hash_Map_Entry (void) { } +template void +ACE_Hash_Map_Entry::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 void ACE_Hash_Map_Manager::dump (void) const { @@ -60,22 +66,24 @@ ACE_Hash_Map_Manager::dump (void) const } template int -ACE_Hash_Map_Manager::resize_i (size_t size) +ACE_Hash_Map_Manager::create_buckets (size_t size) { - size_t bytes = size * sizeof (ACE_Hash_Map_Entry *); + size_t bytes = size * sizeof (ACE_Hash_Map_Entry); void *ptr; ACE_ALLOCATOR_RETURN (ptr, this->allocator_->malloc (bytes), -1); - this->table_ = (ACE_Hash_Map_Entry **) ptr; + this->table_ = (ACE_Hash_Map_Entry *) 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 (&this->table_[i], + &this->table_[i]); return 0; } @@ -97,11 +105,7 @@ ACE_Hash_Map_Manager::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 @@ -134,8 +138,8 @@ ACE_Hash_Map_Manager::close_i (void) // . for (size_t i = 0; i < this->total_size_; i++) { - for (ACE_Hash_Map_Entry *temp_ptr = this->table_[i]; - temp_ptr != 0; + for (ACE_Hash_Map_Entry *temp_ptr = this->table_[i].next_; + temp_ptr != &this->table_[i]; ) { ACE_Hash_Map_Entry *hold_ptr = temp_ptr; @@ -145,9 +149,13 @@ ACE_Hash_Map_Manager::close_i (void) hold_ptr->ACE_Hash_Map_Entry::~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::~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::hash (const EXT_ID &ext_id) template int ACE_Hash_Map_Manager::equal (const EXT_ID &id1, - const EXT_ID &id2) + const EXT_ID &id2) { return id1 == id2; } template int ACE_Hash_Map_Manager::bind_i (const EXT_ID &ext_id, - const INT_ID &int_id) + const INT_ID &int_id, + ACE_Hash_Map_Entry *&entry) { - ACE_Hash_Map_Entry *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::bind_i (const EXT_ID &ext_id, ACE_ALLOCATOR_RETURN (ptr, this->allocator_->malloc (sizeof (ACE_Hash_Map_Entry)), -1); - - this->table_[loc] = - new (ptr) ACE_Hash_Map_Entry (ext_id, int_id, this->table_[loc]); + + this->table_[loc].next_ = entry = + new (ptr) ACE_Hash_Map_Entry (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; @@ -219,9 +231,18 @@ ACE_Hash_Map_Manager::bind_i (const EXT_ID &ext_id, return 1; } +template int +ACE_Hash_Map_Manager::bind_i (const EXT_ID &ext_id, + const INT_ID &int_id) +{ + ACE_Hash_Map_Entry *temp; + + return this->bind_i (ext_id, int_id, temp); +} + template int ACE_Hash_Map_Manager::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::bind (const EXT_ID &ext_id, } template int -ACE_Hash_Map_Manager::trybind_i (const EXT_ID &ext_id, - INT_ID &int_id) +ACE_Hash_Map_Manager::bind (const EXT_ID &ext_id, + const INT_ID &int_id, + ACE_Hash_Map_Entry *&entry) { - ACE_Hash_Map_Entry *temp; + ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); + return this->bind_i (ext_id, int_id, entry); +} + +template int +ACE_Hash_Map_Manager::trybind_i (const EXT_ID &ext_id, + INT_ID &int_id, + ACE_Hash_Map_Entry *&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::trybind_i (const EXT_ID &ext_id, this->allocator_->malloc (sizeof (ACE_Hash_Map_Entry)), -1); - this->table_[loc] = - new (ptr) ACE_Hash_Map_Entry (ext_id, int_id, this->table_[loc]); + this->table_[loc].next_ = entry = + new (ptr) ACE_Hash_Map_Entry (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 int +ACE_Hash_Map_Manager::trybind_i (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_Hash_Map_Entry *temp; + + return this->trybind_i (ext_id, int_id, temp); +} + template int ACE_Hash_Map_Manager::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 int +ACE_Hash_Map_Manager::trybind (const EXT_ID &ext_id, + INT_ID &int_id, + ACE_Hash_Map_Entry *&entry) +{ + ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); + + return this->trybind_i (ext_id, int_id, entry); +} + template int ACE_Hash_Map_Manager::unbind_i (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_Hash_Map_Entry *temp; - ACE_Hash_Map_Entry *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 int +ACE_Hash_Map_Manager::unbind_i (ACE_Hash_Map_Entry *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::~ACE_Hash_Map_Entry (); - this->allocator_->free (temp); + entry->ACE_Hash_Map_Entry::~ACE_Hash_Map_Entry (); + this->allocator_->free (entry); this->cur_size_--; return 0; } @@ -305,7 +360,7 @@ ACE_Hash_Map_Manager::unbind_i (const EXT_ID &ext_id) template int ACE_Hash_Map_Manager::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::unbind (const EXT_ID &ext_id) return this->unbind_i (ext_id) == -1 ? -1 : 0; } +template int +ACE_Hash_Map_Manager::unbind (ACE_Hash_Map_Entry *entry) +{ + ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); + + return this->unbind_i (entry) == -1 ? -1 : 0; +} + template int ACE_Hash_Map_Manager::shared_find (const EXT_ID &ext_id, ACE_Hash_Map_Entry *&entry, - ACE_Hash_Map_Entry *&prev, u_long &loc) { loc = this->hash (ext_id) % this->total_size_; - ACE_Hash_Map_Entry *temp = this->table_[loc]; + ACE_Hash_Map_Entry *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; @@ -347,18 +407,9 @@ ACE_Hash_Map_Manager::shared_find (const EXT_ID &ext_i } } -template int -ACE_Hash_Map_Manager::shared_find (const EXT_ID &ext_id, - ACE_Hash_Map_Entry *&entry, - u_long &loc) -{ - ACE_Hash_Map_Entry *prev; - return this->shared_find (ext_id, entry, prev, loc); -} - template int ACE_Hash_Map_Manager::find_i (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_Hash_Map_Entry *entry; @@ -383,7 +434,7 @@ ACE_Hash_Map_Manager::find_i (const EXT_ID &ext_id) template int ACE_Hash_Map_Manager::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::find (const EXT_ID &ext_id) } template int -ACE_Hash_Map_Manager::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::find_i (const EXT_ID &ext_id, + ACE_Hash_Map_Entry *&entry) { - ACE_Hash_Map_Entry *node; + u_long dummy; + return this->shared_find (ext_id, entry, dummy); +} + +template int +ACE_Hash_Map_Manager::find (const EXT_ID &ext_id, + ACE_Hash_Map_Entry *&entry) +{ + ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); + return this->find_i (ext_id, entry); +} + +template int +ACE_Hash_Map_Manager::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 *&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 int +ACE_Hash_Map_Manager::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 *node; + + return this->rebind_i (ext_id, + int_id, + old_ext_id, + old_int_id, + node); +} + template int ACE_Hash_Map_Manager::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 int +ACE_Hash_Map_Manager::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 *&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 void ACE_Hash_Map_Iterator::dump (void) const { @@ -447,7 +541,7 @@ ACE_Hash_Map_Iterator::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::next (ACE_Hash_Map_Entrymap_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::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::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 void +ACE_Hash_Map_Reverse_Iterator::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 +ACE_Hash_Map_Reverse_Iterator::ACE_Hash_Map_Reverse_Iterator (ACE_Hash_Map_Manager &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 int +ACE_Hash_Map_Reverse_Iterator::next (ACE_Hash_Map_Entry *&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 int +ACE_Hash_Map_Reverse_Iterator::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 int +ACE_Hash_Map_Reverse_Iterator::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 *ptr = 0); + ACE_Hash_Map_Entry *next = 0, + ACE_Hash_Map_Entry *prev = 0); + // Constructor. + + ACE_Hash_Map_Entry (ACE_Hash_Map_Entry *next, + ACE_Hash_Map_Entry *prev); // Constructor. ~ACE_Hash_Map_Entry (void); @@ -48,6 +50,9 @@ public: ACE_Hash_Map_Entry *next_; // Pointer to the next item in the bucket of overflow nodes. + ACE_Hash_Map_Entry *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 ACE_Hash_Map_Iterator; +// Forward decl. +template +class ACE_Hash_Map_Reverse_Iterator; + template 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; + friend class ACE_Hash_Map_Reverse_Iterator; public: + typedef EXT_ID KEY; + typedef INT_ID VALUE; typedef ACE_Hash_Map_Entry ENTRY; typedef ACE_Hash_Map_Iterator ITERATOR; + typedef ACE_Hash_Map_Reverse_Iterator REVERSE_ITERATOR; // = Initialization and termination methods. @@ -96,6 +109,20 @@ public: ~ACE_Hash_Map_Manager (void); // Initialize a with size . + int bind (const EXT_ID &item, + const INT_ID &int_id); + // Associate with . If is already in the + // map then the 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 *&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 with if and only if 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 with . If is already in the - // map then the 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 *&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 *&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 and pass out parameter via . 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 is in the mapping, otherwise -1. + int find (const EXT_ID &ext_id, + ACE_Hash_Map_Entry *&entry); + // Locate and pass out parameter via . If found, + // return 0, returns -1 if not found. + int unbind (const EXT_ID &ext_id); // Unbind (remove) the from the map. Don't return the // to the caller (this is useful for collections where the @@ -142,6 +183,9 @@ public: // Break any association of . Returns the value of // in case the caller needs to deallocate memory. + int unbind (ACE_Hash_Map_Entry *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 to . 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 to . 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 *&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 *&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 *&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 using as the key. Must be // called with locks held. @@ -181,20 +248,25 @@ protected: // Performs a find using 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 using as the key. Must - // be called with locks held. + int find_i (const EXT_ID &ext_id, + ACE_Hash_Map_Entry *&entry); + // Performs a find using 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 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 using as the - // key. Must be called with locks held. + int unbind_i (ACE_Hash_Map_Entry *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 . Must be called with @@ -210,14 +282,9 @@ private: int shared_find (const EXT_ID &ext_id, ACE_Hash_Map_Entry *&entry, u_long &loc); - int shared_find (const EXT_ID &ext_id, - ACE_Hash_Map_Entry *&entry, - ACE_Hash_Map_Entry *&prev, - u_long &loc); // Returns the that corresponds to . - // prev points to the previous entry. - ACE_Hash_Map_Entry **table_; + ACE_Hash_Map_Entry *table_; // Array of *s, each of which points to the // beginning of a linked list of s that hash to that bucket. @@ -270,6 +337,48 @@ private: // table slot. }; +template +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 &mm); + + // = Iteration methods. + + int next (ACE_Hash_Map_Entry *&next_entry); + // Pass back the next 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 &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 *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 + template ACE_Map_Entry::~ACE_Map_Entry (void) { // No-op just to keep some compilers happy... @@ -34,7 +34,7 @@ ACE_Map_Entry::dump (void) const ACE_ALLOC_HOOK_DEFINE(ACE_Map_Manager) -template void + template void ACE_Map_Manager::dump (void) const { ACE_TRACE ("ACE_Map_Manager::dump"); @@ -49,7 +49,7 @@ ACE_Map_Manager::dump (void) const template ACE_Map_Manager::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::free_search_structure (void) template int ACE_Map_Manager::open (size_t size, - ACE_Allocator *alloc) + ACE_Allocator *alloc) { ACE_TRACE ("ACE_Map_Manager::open"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -178,7 +178,7 @@ ACE_Map_Manager::open (size_t size, template int ACE_Map_Manager::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::shared_find (const EXT_ID &ext_id, template int ACE_Map_Manager::equal (const EXT_ID &id1, - const EXT_ID &id2) + const EXT_ID &id2) { return id1 == id2; } @@ -231,8 +231,8 @@ ACE_Map_Manager::shared_find (const EXT_ID &ext_id) template int ACE_Map_Manager::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::shared_bind (const EXT_ID &ext_id, template int ACE_Map_Manager::trybind_i (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::trybind_i"); int first_free = -1; @@ -289,7 +289,7 @@ ACE_Map_Manager::trybind_i (const EXT_ID &ext_id, template int ACE_Map_Manager::trybind (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::trybind"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -322,7 +322,7 @@ ACE_Map_Manager::find (const EXT_ID &ext_id) template int ACE_Map_Manager::unbind_i (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::unbind_i"); @@ -344,7 +344,7 @@ ACE_Map_Manager::unbind_i (const EXT_ID &ext_id, template int ACE_Map_Manager::bind_i (const EXT_ID &ext_id, - const INT_ID &int_id) + const INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::bind_i"); @@ -378,9 +378,9 @@ ACE_Map_Manager::bind_i (const EXT_ID &ext_id, template int ACE_Map_Manager::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::rebind_i"); @@ -410,7 +410,7 @@ ACE_Map_Manager::rebind_i (const EXT_ID &ext_id, template int ACE_Map_Manager::find_i (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::find_i"); @@ -473,7 +473,7 @@ ACE_Map_Manager::shared_unbind (const EXT_ID &ext_id) template int ACE_Map_Manager::unbind (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::unbind"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -483,7 +483,7 @@ ACE_Map_Manager::unbind (const EXT_ID &ext_id, template int ACE_Map_Manager::bind (const EXT_ID &ext_id, - const INT_ID &int_id) + const INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::bind"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -493,9 +493,9 @@ ACE_Map_Manager::bind (const EXT_ID &ext_id, template int ACE_Map_Manager::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::rebind"); ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -505,7 +505,7 @@ ACE_Map_Manager::rebind (const EXT_ID &ext_id, template int ACE_Map_Manager::find (const EXT_ID &ext_id, - INT_ID &int_id) + INT_ID &int_id) { ACE_TRACE ("ACE_Map_Manager::find"); ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1); @@ -550,7 +550,7 @@ ACE_Map_Manager::total_size (void) ACE_ALLOC_HOOK_DEFINE(ACE_Map_Iterator) -template void + template void ACE_Map_Iterator::dump (void) const { ACE_TRACE ("ACE_Map_Iterator::dump"); @@ -606,7 +606,7 @@ ACE_Map_Iterator::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::advance (void) ACE_ALLOC_HOOK_DEFINE(ACE_Map_Reverse_Iterator) -template void + template void ACE_Map_Reverse_Iterator::dump (void) const { ACE_TRACE ("ACE_Map_Reverse_Iterator::dump"); @@ -667,7 +667,7 @@ ACE_Map_Reverse_Iterator::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; friend class ACE_Map_Reverse_Iterator; public: // = Traits. + typedef EXT_ID KEY; + typedef INT_ID VALUE; typedef ACE_Map_Entry ENTRY; typedef ACE_Map_Iterator ITERATOR; typedef ACE_Map_Reverse_Iterator 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::dump (void) const ACE_Scheduling_Strategy::dump (); } -// Return the address of by default. This should typically be -// specialized! - -template size_t -ACE_Hash_Addr::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 /). This should -// typically be specialized. - -template int -ACE_Hash_Addr::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 -ACE_Hash_Addr::operator ADDR_T& (void) +template size_t +ACE_Hash_Addr::hash_i (const ADDR_T &b) const { - return addr_; + ACE_UNUSED_ARG (b); + return 0; } -template -ACE_Hash_Addr::operator const ADDR_T& (void) const +template +ACE_Hash_Addr::ACE_Hash_Addr (void) + : hash_value_ (0), + recyclable_ (0) { - return addr_; } -template -ACE_Hash_Addr::ACE_Hash_Addr (void) +template +ACE_Hash_Addr::ACE_Hash_Addr (const ADDR_T &a) : hash_value_ (0), - svc_handler_ (0) + recyclable_ (0), + addr_ (a) { + this->hash (); } -template -ACE_Hash_Addr::ACE_Hash_Addr (const ADDR_T &a, SVC_HANDLER *sh) +template +ACE_Hash_Addr::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 u_long -ACE_Hash_Addr::hash (void) const +template u_long +ACE_Hash_Addr::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::hash (void) const // relative to the simple comparison. if (this->hash_value_ == 0) - ((ACE_Hash_Addr *) this)->hash_value_ = this->hash_i (addr_); + ((ACE_Hash_Addr *) this)->hash_value_ = this->hash_i (addr_); return this->hash_value_; } -template int -ACE_Hash_Addr::operator== (const ACE_Hash_Addr &rhs) const +template int +ACE_Hash_Addr::operator== (const ACE_Hash_Addr &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 int +ACE_Hash_Addr::recyclable (void) const +{ + return this->recyclable_; +} + +template void +ACE_Hash_Addr::recyclable (int new_value) +{ + this->recyclable_ = new_value; } template int @@ -806,42 +794,111 @@ ACE_Cached_Connect_Strategy::connect_s int flags, int perms) { - ACE_Hash_Addr 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 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 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::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 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 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 + sh = entry->int_id_; + + // Tell the that it should prepare itself for being + // recycled. + sh->recycle (); + } + + // Mark the in the cache as being . + // Therefore recyclable is 0. + entry->ext_id_.recyclable (0); + + return 0; +} + +template +ACE_Cached_Connect_Strategy::~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 int +ACE_Cached_Connect_Strategy::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 in the cache as not being . + // Therefore recyclable is 1. + entry->ext_id_.recyclable (1); + return 0; } +template int +ACE_Cached_Connect_Strategy::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 +template class ACE_Hash_Addr // = TITLE // Internal class to compute hash values on addresses in // . // // = DESCRIPTION - // Intended to be used as a key to an . The - // class is expected to implement the following - // methods: - // = BEGIN - // = BEGIN - // int in_use() const; - // void in_use(int is_used); - // = END - // = END - // Likewise, the parameter/subclass is typically - // . It is expected to implement operator==(). + // + // Intended to be used as a key to an . + // parameter/subclass is typically . 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 &rhs) const; + int operator== (const ACE_Hash_Addr &rhs) const; // Compares two hash values. - operator ADDR_T& (void); - operator const ADDR_T& (void) const; - // Conversion operators allowing 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 which is used to detect - // "in-use" s so we can ignore them. See - // for details on methods required on . + int recyclable_; + // We need to know if the is "in-use". If it is, we + // can operator==() can skip the comparison. ADDR_T addr_; // The underlying address. }; template -class ACE_Cached_Connect_Strategy : public ACE_Connect_Strategy +class ACE_Cached_Connect_Strategy + : public ACE_Connection_Recycling_Strategy, + public ACE_Connect_Strategy // = TITLE // A connection strategy which caches connections to peers // (represented by instances), thereby allowing @@ -603,6 +593,10 @@ class ACE_Cached_Connect_Strategy : public ACE_Connect_Strategy. { 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 , SVC_HANDLER*, ACE_Null_Mutex> connection_cache_; + + // = Super class + typedef ACE_Connect_Strategy CONNECT_STRATEGY; + + // = Typedefs for managing the map + typedef ACE_Hash_Addr ADDRESS; + typedef ACE_Hash_Map_Manager CONNECTION_MAP; + typedef ACE_Hash_Map_Iterator CONNECTION_MAP_ITERATOR; + typedef ACE_Hash_Map_Entry CONNECTION_MAP_ENTRY; + + CONNECTION_MAP connection_cache_; // Table that maintains the cache of connected 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 ACE_Svc_Handler::ACE_Svc_Handler (ACE_Thread_Manager *tm, ACE_Message_Queue *mq, ACE_Reactor *reactor) - : ACE_Task (tm, mq) + : ACE_Task (tm, mq), + closing_ (0), + recycler_ (0), + recycling_act_ (0) { ACE_TRACE ("ACE_Svc_Handler::ACE_Svc_Handler"); @@ -128,7 +132,6 @@ ACE_Svc_Handler::ACE_Svc_Handler (ACE_Thread_Manager *tm, if (this->dynamic_) // Make sure to reset the flag ACE_Svc_Handler::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::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::info (char **, size_t) const ACE_TRACE ("ACE_Svc_Handler::info"); return -1; } + +template int +ACE_Svc_Handler::idle (u_long flags) +{ + if (this->recycler ()) + return this->recycler ()->cache (this->recycling_act_); + else + return this->close (flags); +} + +template void +ACE_Svc_Handler::recycler (ACE_Connection_Recycling_Strategy *recycler, + const void *recycling_act) +{ + ACE_TRACE ("ACE_Svc_Handler::recycler"); + this->recycler_ = recycler; + this->recycling_act_ = recycling_act; +} + +template ACE_Connection_Recycling_Strategy * +ACE_Svc_Handler::recycler (void) const +{ + ACE_TRACE ("ACE_Svc_Handler::recycler"); + return this->recycler_; +} + +template int +ACE_Svc_Handler::recycle (void *) +{ + ACE_TRACE ("ACE_Svc_Handler::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 class ACE_Svc_Handler : public ACE_Task // = 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 + // 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 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 ). + + 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 . - - 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 Binary files a/tests/tests.mdp and b/tests/tests.mdp differ -- cgit v1.2.1