summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog-99b22
-rw-r--r--ace/Caching_Utility_T.cpp122
-rw-r--r--ace/Caching_Utility_T.h58
-rw-r--r--ace/Cleanup_Strategies_T.cpp10
-rw-r--r--ace/Cleanup_Strategies_T.h21
-rw-r--r--ace/Strategies.h4
-rw-r--r--ace/Strategies_T.h8
7 files changed, 242 insertions, 3 deletions
diff --git a/ChangeLog-99b b/ChangeLog-99b
index ccbbc4ea2cb..1900b3a6021 100644
--- a/ChangeLog-99b
+++ b/ChangeLog-99b
@@ -1,3 +1,25 @@
+Tue Aug 03 18:30:47 1999 Kirthika Parameswaran <kirthika@cs.wustl.edu>
+
+ * ace/Strategies.h (ACE_Connection_Recycling_Strategy):
+ Added a new pure virtual method <marked_as_closed_i> which
+ will provide a non-locking implementation of the
+ <mark_as_closed> method.
+
+ * ace/Strategies_T.h (ACE_Cached_Connect_Strategy):
+ Made <mark_as_closed_i> public.
+
+ * ace/Caching_Utility_T.{h,cpp}
+ (ACE_Refcounted_Recyclable_Caching_Utility):
+ Added this class which caters to purging of refcounted and
+ recyclable handlers.
+
+ * ace/Cleanup_Strategy_T.{h,cpp}:
+ (ACE_Refcounted_Recyclable_Cleanup_Strategy):
+ Added this class which caters to the cleanup of handlers which
+ are refcounted and recyclable. Heres where the necessity of
+ making the non-locking version of <marked_as_closed> public
+ arose in the first place.
+
Tue Aug 03 16:58:08 1999 Joe Hoffert <joeh@cs.wustl.edu>
* ace/ATM_Acceptor.{h,cpp}:
diff --git a/ace/Caching_Utility_T.cpp b/ace/Caching_Utility_T.cpp
index 2d9b4c072ef..e571e7509e1 100644
--- a/ace/Caching_Utility_T.cpp
+++ b/ace/Caching_Utility_T.cpp
@@ -232,6 +232,128 @@ ACE_Recyclable_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUT
////////////////////////////////////////////////////////////////////////////////
template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES>
+ACE_Refcounted_Recyclable_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUTES>::ACE_Refcounted_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER> *cleanup_strategy,
+ int delete_cleanup_strategy)
+ : cleanup_strategy_ (cleanup_strategy),
+ delete_cleanup_strategy_ (delete_cleanup_strategy),
+ marked_as_closed_entries_ (0)
+{
+ if (cleanup_strategy == 0)
+ {
+ ACE_NEW (this->cleanup_strategy_,
+ CLEANUP_STRATEGY);
+ this->delete_cleanup_strategy_ = 1;
+ }
+}
+
+template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES>
+ACE_Refcounted_Recyclable_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUTES>::~ACE_Refcounted_Recyclable_Handler_Caching_Utility (void)
+{
+ if (this->delete_cleanup_strategy_)
+ delete this->cleanup_strategy_;
+}
+
+template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES> int
+ACE_Refcounted_Recyclable_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUTES>::clear_cache (CONTAINER &container,
+ double purge_percent)
+{
+ // Check that the purge_percent is non-zero.
+ if (purge_percent == 0)
+ return 0;
+
+ // Get the number of entries in the container which can be considered for purging.
+ size_t available_entries = container.current_size () - this->marked_as_closed_entries_;
+
+ // Also whether the number of entries in the cache zero.
+ // Oops! then there is no way out but exiting.
+ if (available_entries <= 0)
+ return 0;
+
+ // Calculate the no of entries to remove from the cache depending
+ // upon the <purge_percent>.
+ size_t entries_to_remove = size_t ((double (purge_percent) / 100 * available_entries) + 0.5);
+
+ if (entries_to_remove >= available_entries ||
+ entries_to_remove == 0)
+ entries_to_remove = available_entries - 1;
+
+ KEY *key_to_remove = 0;
+ VALUE *value_to_remove = 0;
+
+ for (size_t i = 0; i < entries_to_remove ; ++i)
+ {
+ this->minimum (container,
+ key_to_remove,
+ value_to_remove);
+
+ // Simply verifying that the key is non-zero.
+ // This is important for strategies where the minimum
+ // entry cant be found due to constraints on the type of entry
+ // to remove.
+ if (key_to_remove == 0)
+ return 0;
+
+ if (this->cleanup_strategy_->cleanup (container,
+ key_to_remove,
+ value_to_remove) == -1)
+ return -1;
+
+ ++this->marked_as_closed_entries_;
+ }
+
+ return 0;
+}
+
+template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES> void
+ACE_Refcounted_Recyclable_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUTES>::minimum (CONTAINER &container,
+ KEY *&key_to_remove,
+ VALUE *&value_to_remove)
+{
+ // Starting values.
+ ITERATOR end = container.end ();
+ ITERATOR iter = container.begin ();
+ ATTRIBUTES min = (*iter).int_id_.second ();
+ key_to_remove = 0;
+ value_to_remove = 0;
+ // Found the minimum entry to be purged?
+ int found = 0;
+
+ // The iterator moves thru the container searching for the entry
+ // with the lowest ATTRIBUTES.
+ for (;
+ iter != end;
+ ++iter)
+ {
+ // If the <min> entry isnt IDLE_AND_PURGABLE continue until you reach
+ // the first entry which can be purged. This is the minimum with
+ // which you will compare the rest of the purgable entries.
+ if ((*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE ||
+ (*iter).ext_id_.recycle_state () == ACE_RECYCLABLE_PURGABLE_BUT_NOT_IDLE)
+ {
+ if (found == 0)
+ {
+ min = (*iter).int_id_.second ();
+ key_to_remove = &(*iter).ext_id_;
+ value_to_remove = &(*iter).int_id_;
+ found = 1;
+ }
+ else
+ {
+ // Ah! an entry with lower ATTTRIBUTES...
+ if (min > (*iter).int_id_.second ())
+ {
+ min = (*iter).int_id_.second ();
+ key_to_remove = &(*iter).ext_id_;
+ value_to_remove = &(*iter).int_id_;
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES>
ACE_Handler_Caching_Utility<KEY, VALUE, CONTAINER, ITERATOR, ATTRIBUTES>::ACE_Handler_Caching_Utility (ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER> *cleanup_strategy,
int delete_cleanup_strategy)
: cleanup_strategy_ (cleanup_strategy),
diff --git a/ace/Caching_Utility_T.h b/ace/Caching_Utility_T.h
index cb036782343..56798bf6903 100644
--- a/ace/Caching_Utility_T.h
+++ b/ace/Caching_Utility_T.h
@@ -129,6 +129,64 @@ protected:
////////////////////////////////////////////////////////////////////////////////////////
template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES>
+class ACE_Refcounted_Recyclable_Handler_Caching_Utility
+{
+ // = TITLE
+ // Defines a helper class for the Caching Strategies.
+ //
+ // = DESCRIPTION
+ // This class defines the methods commonly used by the different
+ // caching strategies. For instance: clear_cache () method which
+ // decides and purges the entry from the container. Note: This
+ // class helps in the caching_strategies using a container
+ // containing entries of <Refcounted_KEY,
+ // Recyclable_Connection_Handler> kind. The attributes helps in
+ // deciding the entries to be purged. The Cleanup_Strategy is the
+ // callback class to which the entries to be cleaned up will be
+ // delegated.
+
+public:
+
+ typedef ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy<KEY, VALUE, CONTAINER> CLEANUP_STRATEGY;
+ typedef ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER> CLEANUP_STRATEGY_BASE;
+
+ ACE_Refcounted_Recyclable_Handler_Caching_Utility (ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER> *cleanup_strategy = 0,
+ int delete_cleanup_strategy = 0);
+
+ // Constructor.
+
+ ~ACE_Refcounted_Recyclable_Handler_Caching_Utility (void);
+ // Destructor.
+
+ int clear_cache (CONTAINER &container,
+ double purge_percent);
+ // Purge entries from the <container>. The Cleanup_Strategy will do
+ // the actual job of cleanup once the entries to be cleaned up are
+ // decided.
+
+protected:
+
+ void minimum (CONTAINER &container,
+ KEY *&key_to_remove,
+ VALUE *&value_to_remove);
+ // Find the entry with minimum caching attributes.
+
+ CLEANUP_STRATEGY_BASE *cleanup_strategy_;
+ // This is the default Cleanup Strategy for this utility.
+
+ int delete_cleanup_strategy_;
+ // Whether the cleanup_strategy should be destroyed or not.
+
+ size_t marked_as_closed_entries_;
+ // This figure denotes the number of entries are there in the
+ // container which have been marked as closed already but might
+ // not have been unbound from the container.
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+template <class KEY, class VALUE, class CONTAINER, class ITERATOR, class ATTRIBUTES>
class ACE_Handler_Caching_Utility
{
// = TITLE
diff --git a/ace/Cleanup_Strategies_T.cpp b/ace/Cleanup_Strategies_T.cpp
index b11d68b78bd..ea0f023a0e5 100644
--- a/ace/Cleanup_Strategies_T.cpp
+++ b/ace/Cleanup_Strategies_T.cpp
@@ -51,6 +51,16 @@ ACE_Recyclable_Handler_Cleanup_Strategy<KEY, VALUE, CONTAINER>::cleanup (CONTAIN
/////////////////////////////////////////////////////////////////////////////
template <class KEY, class VALUE, class CONTAINER> int
+ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy<KEY, VALUE, CONTAINER>::cleanup (CONTAINER &,
+ KEY *,
+ VALUE *value)
+{
+ return value->first ()->handle_close_i ();
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+template <class KEY, class VALUE, class CONTAINER> int
ACE_Handler_Cleanup_Strategy<KEY, VALUE, CONTAINER>::cleanup (CONTAINER &container,
KEY *key,
VALUE *value)
diff --git a/ace/Cleanup_Strategies_T.h b/ace/Cleanup_Strategies_T.h
index 15c615a9d09..25580b27f79 100644
--- a/ace/Cleanup_Strategies_T.h
+++ b/ace/Cleanup_Strategies_T.h
@@ -64,6 +64,27 @@ public:
//////////////////////////////////////////////////////////////////////
template <class KEY, class VALUE, class CONTAINER>
+class ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy : public ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER>
+{
+ // = TITLE
+ // Defines a strategy to be followed for cleaning up
+ // entries which are svc_handlers from a container.
+ //
+ // = DESCRIPTION
+ // The entry to be cleaned up is removed from the container.
+ // Here, since we are dealing with recyclable svc_handlers with
+ // addresses which are refcountable specifically, we perform a
+ // couple of extra operations and do so without any locking.
+
+public:
+
+ virtual int cleanup (CONTAINER &container, KEY *key, VALUE *value);
+ // The method which will do the cleanup of the entry in the container.
+};
+
+//////////////////////////////////////////////////////////////////////
+
+template <class KEY, class VALUE, class CONTAINER>
class ACE_Handler_Cleanup_Strategy : public ACE_Cleanup_Strategy<KEY, VALUE, CONTAINER>
{
// = TITLE
diff --git a/ace/Strategies.h b/ace/Strategies.h
index 29ad3d01c2e..f35b753de88 100644
--- a/ace/Strategies.h
+++ b/ace/Strategies.h
@@ -102,12 +102,16 @@ public:
virtual int recycle_state (const void *recycling_act,
ACE_Recyclable_State new_state) = 0;
+
virtual ACE_Recyclable_State recycle_state (const void *recycling_act) const = 0;
// Get/Set <recycle_state>.
virtual int mark_as_closed (const void *recycling_act) = 0;
// Mark as closed.
+ virtual int mark_as_closed_i (const void *recycling_act) = 0;
+ // Mark as closed.(non-locking version)
+
virtual int cleanup_hint (const void *recycling_act) = 0;
// Cleanup as hint.
diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h
index 1c1d0a33711..01e5bd60d44 100644
--- a/ace/Strategies_T.h
+++ b/ace/Strategies_T.h
@@ -760,6 +760,11 @@ public:
virtual int mark_as_closed (const void *recycling_act);
// Mark as closed.
+ virtual int mark_as_closed_i (const void *recycling_act);
+ // Mark as closed (non-locking version). This method needs to be public
+ // as it is used in the cleanup of handlers where teh locked version causes
+ // a deadlock.
+
virtual int cleanup_hint (const void *recycling_act);
// Cleanup hint.
@@ -818,9 +823,6 @@ protected:
virtual ACE_Recyclable_State recycle_state_i (const void *recycling_act) const;
// Get/Set <recycle_state> (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.