summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-21 07:28:45 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-21 07:28:45 +0000
commit3bcfa7354450890a494736d7df71f2fc938fd0bc (patch)
treefa2bdd69f3684840dfe34db77710590cfa1dc56f /ace
parent6c05926380d2b3df287bf2142a6c7fdd6812a4bf (diff)
downloadATCD-3bcfa7354450890a494736d7df71f2fc938fd0bc.tar.gz
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r--ace/Strategies.h67
-rw-r--r--ace/Strategies.i63
-rw-r--r--ace/Strategies_T.cpp302
-rw-r--r--ace/Strategies_T.h130
-rw-r--r--ace/Strategies_T.i67
-rw-r--r--ace/Svc_Handler.cpp11
-rw-r--r--ace/Svc_Handler.h4
7 files changed, 448 insertions, 196 deletions
diff --git a/ace/Strategies.h b/ace/Strategies.h
index ec95bf7e2e5..03bd8d2d71d 100644
--- a/ace/Strategies.h
+++ b/ace/Strategies.h
@@ -96,11 +96,78 @@ public:
virtual int cache (const void *recycling_act) = 0;
// Add to cache.
+ virtual int mark_as_closed (const void *recycling_act) = 0;
+ // Mark as closed.
+
+ virtual int cleanup_hint (const void *recycling_act) = 0;
+ // Cleanup as hint.
+
protected:
ACE_Connection_Recycling_Strategy (void);
// Default ctor.
};
+class ACE_Export ACE_Recyclable
+{
+public:
+ enum State
+ {
+ IDLE,
+ BUSY,
+ CLOSED,
+ UNKNOWN
+ };
+
+ virtual ~ACE_Recyclable (void);
+ // Destructor.
+
+ // = Set/Get the recyclable bit
+ State state (void) const;
+ void state (State new_state);
+
+protected:
+ ACE_Recyclable (State initial_state);
+ // Protected constructor.
+
+ State state_;
+ // Our state.
+};
+
+class ACE_Export ACE_Hashable
+{
+public:
+ virtual ~ACE_Hashable (void);
+ // Destructor.
+
+ virtual u_long hash (void) const = 0;
+ // Computes and returns hash value.
+
+protected:
+ ACE_Hashable (void);
+ // Protected constructor.
+};
+
+class ACE_Export ACE_Refcountable
+{
+public:
+ virtual ~ACE_Refcountable (void);
+ // Destructor.
+
+ // = Increment/Decrement refcount
+ int increment (void);
+ int decrement (void);
+
+ int refcount (void) const;
+ // Returns the current refcount.
+
+protected:
+ ACE_Refcountable (int refcount);
+ // Protected constructor.
+
+ int refcount_;
+ // Current refcount.
+};
+
// This needs to come here to avoid circular dependencies.
#include "ace/Strategies_T.h"
diff --git a/ace/Strategies.i b/ace/Strategies.i
index bcc6318f9da..a0ef94ea2da 100644
--- a/ace/Strategies.i
+++ b/ace/Strategies.i
@@ -12,3 +12,66 @@ ACE_INLINE
ACE_Connection_Recycling_Strategy::ACE_Connection_Recycling_Strategy (void)
{
}
+
+ACE_INLINE
+ACE_Recyclable::ACE_Recyclable (ACE_Recyclable::State initial_state)
+ : state_ (initial_state)
+{
+}
+
+ACE_INLINE
+ACE_Recyclable::~ACE_Recyclable (void)
+{
+}
+
+ACE_INLINE ACE_Recyclable::State
+ACE_Recyclable::state (void) const
+{
+ return this->state_;
+}
+
+ACE_INLINE void
+ACE_Recyclable::state (ACE_Recyclable::State new_state)
+{
+ this->state_ = new_state;
+}
+
+ACE_INLINE
+ACE_Hashable::ACE_Hashable (void)
+{
+}
+
+ACE_INLINE
+ACE_Hashable::~ACE_Hashable (void)
+{
+}
+
+ACE_INLINE
+ACE_Refcountable::ACE_Refcountable (int refcount)
+ : refcount_ (refcount)
+{
+}
+
+ACE_INLINE
+ACE_Refcountable::~ACE_Refcountable (void)
+{
+}
+
+ACE_INLINE int
+ACE_Refcountable::increment (void)
+{
+ return ++this->refcount_;
+}
+
+ACE_INLINE int
+ACE_Refcountable::decrement (void)
+{
+ return --this->refcount_;
+}
+
+ACE_INLINE int
+ACE_Refcountable::refcount (void) const
+{
+ return this->refcount_;
+}
+
diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp
index 170af695e00..9d036e2b9ec 100644
--- a/ace/Strategies_T.cpp
+++ b/ace/Strategies_T.cpp
@@ -459,6 +459,135 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::open
return 0;
}
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> void
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::check_hint_i
+ (SVC_HANDLER *&sh,
+ HASH_ADDRESS &search_addr,
+ CONNECTION_MAP_ENTRY *&entry,
+ int &found)
+{
+ found = 0;
+
+ // Get the recycling act for the svc_handler
+ CONNECTION_MAP_ENTRY *possible_entry = (CONNECTION_MAP_ENTRY *) sh->recycling_act ();
+
+ // Check to see if the hint svc_handler has been closed down
+ if (possible_entry->ext_id_.state () == ACE_Recyclable::CLOSED)
+ {
+ // If close, decrement refcount
+ if (possible_entry->ext_id_.decrement () == 0)
+ {
+ // If refcount goes to zero, close down the svc_handler
+ possible_entry->int_id_->close ();
+ }
+
+ // Hint not successful
+ found = 0;
+
+ // Reset hint
+ sh = 0;
+ }
+
+ // If hint is not closed, see if it is connected to the correct
+ // address and is recyclable
+ else if (possible_entry->ext_id_ == search_addr)
+ {
+ // Hint successful
+ found = 1;
+
+ // Tell the <svc_handler> that it should prepare itself for
+ // being recycled.
+ this->prepare_for_recycling (sh);
+ }
+ else
+ {
+ // This hint will not be used.
+ possible_entry->ext_id_.decrement ();
+
+ // Hint not successful
+ found = 0;
+
+ // If <sh> is not connected to the correct address or is busy,
+ // we will not use it.
+ sh = 0;
+ }
+
+ if (found)
+ entry = possible_entry;
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::find_or_create_svc_handler_i
+ (SVC_HANDLER *&sh,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms,
+ HASH_ADDRESS &search_addr,
+ CONNECTION_MAP_ENTRY *&entry,
+ int &found)
+{
+ // 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.
+ if (this->connection_cache_.find (search_addr, entry) == -1)
+ {
+ // Set the flag
+ found = 0;
+
+ // Create a new svc_handler
+ if (this->make_svc_handler (sh) == -1)
+ return -1;
+
+ // Actively establish the connection. This is a timed blocking
+ // connect.
+ if (this->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;
+ }
+ else
+ {
+ // Insert the new SVC_HANDLER instance into the cache.
+ if (this->connection_cache_.bind (search_addr,
+ sh,
+ entry) == -1)
+ return -1;
+
+ // Set the recycler and the recycling act
+ this->assign_recycler (sh, this, entry);
+ }
+ }
+ else
+ // We found a cached svc_handler.
+ {
+ // Set the flag
+ found = 1;
+
+ // Get the cached <svc_handler>
+ sh = entry->int_id_;
+
+ // Tell the <svc_handler> that it should prepare itself for
+ // being recycled.
+ this->prepare_for_recycling (sh);
+ }
+
+ return 0;
+}
+
template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_svc_handler
(SVC_HANDLER *&sh,
@@ -478,105 +607,40 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::connect_s
CONNECTION_MAP_ENTRY *entry = 0;
// Create the search key
- ADDRESS search_addr (remote_addr);
+ HASH_ADDRESS search_addr (remote_addr);
// Synchronization is required here as the setting of the
- // recyclable bit must be done atomically with the finding and
+ // recyclable state 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);
// Check if the user passed a hint svc_handler
if (sh != 0)
- {
- // If so, see if it is connected to the correct address and is
- // recyclable
- entry = (CONNECTION_MAP_ENTRY *) sh->recycling_act ();
- if (entry->ext_id_ == search_addr)
- {
- // Set the flag
- found = 1;
-
- // Tell the <svc_handler> that it should prepare itself for
- // being recycled.
- this->prepare_for_recycling (sh);
- }
- else
- {
- // If <sh> is not connected to the correct address or is
- // busy, we will not use it.
- sh = 0;
- }
- }
+ this->check_hint_i (sh, search_addr, entry, found);
// If not found
if (!found)
{
- // 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.
- if (this->connection_cache_.find (search_addr, entry) == -1)
- {
- // Set the flag
- found = 0;
-
- // Create a new svc_handler
- if (this->make_svc_handler (sh) == -1)
- return -1;
-
- // Actively establish the connection. This is a timed
- // blocking connect.
- if (this->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;
- }
- else
- {
- //
- // Insert the new SVC_HANDLER instance into the cache.
- //
- // Create the key
- ADDRESS server_addr (remote_addr);
- if (this->connection_cache_.bind (server_addr,
- sh,
- entry) == -1)
- return -1;
-
- // Set the recycler and the recycling act
- this->assign_recycler (sh, this, entry);
- }
- }
- else
- // We found a cached svc_handler.
- {
- // Set the flag
- found = 1;
-
- // Get the cached <svc_handler>
- sh = entry->int_id_;
-
- // Tell the <svc_handler> that it should prepare itself
- // for being recycled.
- this->prepare_for_recycling (sh);
- }
+ int result = this->find_or_create_svc_handler_i (sh,
+ remote_addr,
+ timeout,
+ local_addr,
+ reuse_addr,
+ flags,
+ perms,
+ search_addr,
+ entry,
+ found);
+ if (result != 0)
+ return result;
}
// For all successful cases: mark the <svc_handler> in the cache
- // as being <in_use>. Therefore recyclable is 0.
- entry->ext_id_.recyclable (0);
+ // as being <in_use>. Therefore recyclable is BUSY.
+ entry->ext_id_.state (ACE_Recyclable::BUSY);
+
+ // And increment the refcount
+ entry->ext_id_.increment ();
}
// If it is a new connection, activate it.
@@ -599,16 +663,22 @@ 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
+ // state must be done atomically with respect to other threads that
// are querying the cache.
ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1);
+
+ return this->cache_i (recycling_act);
+}
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cache_i (const void *recycling_act)
+{
// 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);
+ // Therefore recyclable is IDLE.
+ entry->ext_id_.state (ACE_Recyclable::IDLE);
return 0;
}
@@ -619,13 +689,69 @@ ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge (co
// Excluded other threads from changing cache while we take this
// entry out.
ACE_GUARD_RETURN (MUTEX, ace_mon, this->lock_, -1);
+
+ return this->purge_i (recycling_act);
+}
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::purge_i (const void *recycling_act)
+{
// The wonders and perils of ACT
CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
return this->connection_cache_.unbind (entry);
}
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed (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);
+
+ return this->mark_as_closed_i (recycling_act);
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::mark_as_closed_i (const void *recycling_act)
+{
+ // The wonders and perils of ACT
+ CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
+
+ // Mark the <svc_handler> in the cache as CLOSED.
+ entry->ext_id_.state (ACE_Recyclable::CLOSED);
+
+ return 0;
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint (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);
+
+ return this->cleanup_hint_i (recycling_act);
+}
+
+template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX> int
+ACE_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, MUTEX>::cleanup_hint_i (const void *recycling_act)
+{
+ // The wonders and perils of ACT
+ CONNECTION_MAP_ENTRY *entry = (CONNECTION_MAP_ENTRY *) recycling_act;
+
+ // Decrement the refcount on the <svc_handler>.
+ int refcount = entry->ext_id_.decrement ();
+
+ // If the svc_handler state is closed and the refcount == 0, call
+ // close() on svc_handler.
+ if (entry->ext_id_.state () == ACE_Recyclable::CLOSED &&
+ refcount == 0)
+ entry->int_id_->close ();
+
+ return 0;
+}
+
template <class SVC_HANDLER> void
ACE_DLL_Strategy<SVC_HANDLER>::dump (void) const
{
diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h
index 5c17c90f112..b5514295ea5 100644
--- a/ace/Strategies_T.h
+++ b/ace/Strategies_T.h
@@ -686,59 +686,6 @@ public:
// This is a no-op.
};
-template <class T>
-class ACE_Recyclable
-{
-public:
-
- // = Initialization methods.
- ACE_Recyclable (void);
- // Default constructor.
-
- ACE_Recyclable (const T &t, int recyclable = 0);
- // Constructor.
-
- ~ACE_Recyclable (void);
- // Destructor.
-
- int operator== (const ACE_Recyclable<T> &rhs) const;
- // Compares two values.
-
- // = Set/Get the recyclable bit
- int recyclable (void) const;
- void recyclable (int new_value);
-
-protected:
- int recyclable_;
- // We need to know if the <T> is "in-use". If it is, we can
- // operator==() can skip the comparison.
-
- T t_;
- // The underlying class.
-};
-
-template <class T>
-class ACE_Hash_Recyclable : public ACE_Recyclable<T>
-{
-public:
-
- // = Initialization methods.
- ACE_Hash_Recyclable (void);
- // Default constructor.
-
- ACE_Hash_Recyclable (const T &t, int recyclable = 0);
- // Constructor.
-
- ~ACE_Hash_Recyclable (void);
- // Destructor.
-
- u_long hash (void) const;
- // Computes and returns hash value.
-
- int operator== (const ACE_Recyclable<T> &rhs) const;
- // Compares two values.
-};
-
template <class ADDR_T>
class ACE_Hash_Addr
{
@@ -780,6 +727,33 @@ private:
// The underlying address.
};
+template <class T>
+class ACE_Refcounted_Hash_Recyclable : public ACE_Refcountable,
+ public ACE_Hashable,
+ public ACE_Recyclable
+{
+public:
+ ACE_Refcounted_Hash_Recyclable (void);
+ // Default constructor.
+
+ ACE_Refcounted_Hash_Recyclable (const T &t,
+ int refcount = 0,
+ ACE_Recyclable::State state = ACE_Recyclable::UNKNOWN);
+ // Constructor.
+
+ virtual ~ACE_Refcounted_Hash_Recyclable (void);
+ // Destructor
+
+ u_long hash (void) const;
+ // Computes and returns hash value.
+
+ int operator== (const ACE_Refcounted_Hash_Recyclable<T> &rhs) const;
+ // Compares two instances.
+
+protected:
+ T t_;
+};
+
template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class MUTEX>
class ACE_Cached_Connect_Strategy : public ACE_Connection_Recycling_Strategy, public ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
{
@@ -868,7 +842,12 @@ public:
virtual int cache (const void *recycling_act);
// Add to cache.
-private:
+ virtual int mark_as_closed (const void *recycling_act);
+ // Mark as closed.
+
+ virtual int cleanup_hint (const void *recycling_act);
+ // Cleanup hint.
+
// = Define some useful typedefs.
typedef ACE_Creation_Strategy<SVC_HANDLER>
CREATION_STRATEGY;
@@ -883,16 +862,47 @@ private:
// = Typedefs for managing the map
typedef ACE_Hash_Addr<ACE_PEER_CONNECTOR_ADDR>
- ADDRESS;
- typedef ACE_Hash_Recyclable<ADDRESS>
- RECYCLABLE_ADDRESS;
- typedef ACE_Hash_Map_Manager <RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex>
+ HASH_ADDRESS;
+ typedef ACE_Refcounted_Hash_Recyclable<HASH_ADDRESS>
+ REFCOUNTED_HASH_RECYCLABLE_ADDRESS;
+ typedef ACE_Hash_Map_Manager <REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex>
CONNECTION_MAP;
- typedef ACE_Hash_Map_Iterator <RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex>
+ typedef ACE_Hash_Map_Iterator <REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *, ACE_Null_Mutex>
CONNECTION_MAP_ITERATOR;
- typedef ACE_Hash_Map_Entry<RECYCLABLE_ADDRESS, SVC_HANDLER *>
+ typedef ACE_Hash_Map_Entry<REFCOUNTED_HASH_RECYCLABLE_ADDRESS, SVC_HANDLER *>
CONNECTION_MAP_ENTRY;
+protected:
+
+ virtual int purge_i (const void *recycling_act);
+ // Remove from cache (non-locking version).
+
+ virtual int cache_i (const void *recycling_act);
+ // Add to cache (non-locking version).
+
+ virtual int mark_as_closed_i (const void *recycling_act);
+ // Mark as closed (non-locking version).
+
+ virtual int cleanup_hint_i (const void *recycling_act);
+ // Cleanup hint.
+
+ // = Helpers
+ void check_hint_i (SVC_HANDLER *&sh,
+ HASH_ADDRESS &search_addr,
+ CONNECTION_MAP_ENTRY *&entry,
+ int &found);
+
+ int find_or_create_svc_handler_i (SVC_HANDLER *&sh,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms,
+ HASH_ADDRESS &search_addr,
+ CONNECTION_MAP_ENTRY *&entry,
+ int &found);
+
CONNECTION_MAP connection_cache_;
// Table that maintains the cache of connected <SVC_HANDLER>s.
diff --git a/ace/Strategies_T.i b/ace/Strategies_T.i
index 026d3afc899..cdd1188ec5b 100644
--- a/ace/Strategies_T.i
+++ b/ace/Strategies_T.i
@@ -368,72 +368,43 @@ ACE_Schedule_All_Threaded_Strategy<SVC_HANDLER>::resume (void)
}
template <class T> ASYS_INLINE
-ACE_Recyclable<T>::ACE_Recyclable (void)
- : recyclable_ (0),
- t_ (T ())
+ACE_Refcounted_Hash_Recyclable<T>::ACE_Refcounted_Hash_Recyclable (void)
+ : ACE_Refcountable (0),
+ ACE_Hashable (),
+ ACE_Recyclable (ACE_Recyclable::UNKNOWN),
+ t_ ()
{
}
template <class T> ASYS_INLINE
-ACE_Recyclable<T>::ACE_Recyclable (const T &t, int recyclable)
- : recyclable_ (recyclable),
+ACE_Refcounted_Hash_Recyclable<T>::ACE_Refcounted_Hash_Recyclable (const T &t,
+ int refcount,
+ ACE_Recyclable::State state)
+ : ACE_Refcountable (refcount),
+ ACE_Hashable (),
+ ACE_Recyclable (state),
t_ (t)
{
}
template <class T> ASYS_INLINE
-ACE_Recyclable<T>::~ACE_Recyclable (void)
-{
-}
-
-template <class T> ASYS_INLINE int
-ACE_Recyclable<T>::operator== (const ACE_Recyclable<T> &rhs) const
-{
- if (!this->recyclable ())
- return 0;
- else
- return this->t_ == rhs.t_;
-}
-
-template <class T> ASYS_INLINE int
-ACE_Recyclable<T>::recyclable (void) const
-{
- return this->recyclable_;
-}
-
-template <class T> ASYS_INLINE void
-ACE_Recyclable<T>::recyclable (int new_value)
-{
- this->recyclable_ = new_value;
-}
-
-template <class T> ASYS_INLINE
-ACE_Hash_Recyclable<T>::ACE_Hash_Recyclable (void)
- : ACE_Recyclable<T> ()
-{
-}
-
-template <class T> ASYS_INLINE
-ACE_Hash_Recyclable<T>::ACE_Hash_Recyclable (const T &t, int recyclable)
- : ACE_Recyclable<T> (t, recyclable)
-{
-}
-
-template <class T> ASYS_INLINE
-ACE_Hash_Recyclable<T>::~ACE_Hash_Recyclable (void)
+ACE_Refcounted_Hash_Recyclable<T>::~ACE_Refcounted_Hash_Recyclable (void)
{
}
template <class T> ASYS_INLINE u_long
-ACE_Hash_Recyclable<T>::hash (void) const
+ACE_Refcounted_Hash_Recyclable<T>::hash (void) const
{
return this->t_.hash ();
}
-template <class T> ASYS_INLINE int
-ACE_Hash_Recyclable<T>::operator== (const ACE_Recyclable<T> &rhs) const
+template <class T> ASYS_INLINE int
+ACE_Refcounted_Hash_Recyclable<T>::operator== (const ACE_Refcounted_Hash_Recyclable<T> &rhs) const
{
- return ACE_Recyclable<T>::operator== (rhs);
+ if (this->state () != ACE_Recyclable::IDLE)
+ return 0;
+ else
+ return this->t_ == rhs.t_;
}
template<class ADDR_T> ASYS_INLINE
diff --git a/ace/Svc_Handler.cpp b/ace/Svc_Handler.cpp
index 83a993b5bf7..7d7cc779d61 100644
--- a/ace/Svc_Handler.cpp
+++ b/ace/Svc_Handler.cpp
@@ -156,6 +156,17 @@ ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown (void)
}
template <PR_ST_1, ACE_SYNCH_DECL> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown");
+
+ // Remove as hint.
+ if (this->recycler ())
+ this->recycler ()->cleanup_hint (this->recycling_act_);
+
+}
+
+template <PR_ST_1, ACE_SYNCH_DECL> void
ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const
{
ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump");
diff --git a/ace/Svc_Handler.h b/ace/Svc_Handler.h
index d04ca2db879..4bec5635ba8 100644
--- a/ace/Svc_Handler.h
+++ b/ace/Svc_Handler.h
@@ -61,6 +61,10 @@ public:
// instead of closing it. If the object does not have a recycler,
// it will be closed.
+ virtual void cleanup_hint (void);
+ // When the svc_handle is no longer needed around as a hint, call
+ // this method.
+
// = Dynamic linking hooks.
virtual int init (int argc, ASYS_TCHAR *argv[]);
// Default version does no work and returns -1. Must be overloaded