Transport_Cache_Manager.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Transport_Cache_Manager.h
00006  *
00007  *  Transport_Cache_Manager.h,v 1.27 2005/11/24 11:05:46 ossama Exp
00008  *
00009  *  @author Balachandran Natarajan <bala@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef TAO_CONNECTION_CACHE_MANAGER_H
00014 #define TAO_CONNECTION_CACHE_MANAGER_H
00015 
00016 #include /**/ "ace/pre.h"
00017 #include "ace/Null_Mutex.h"
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 #define  ACE_LACKS_PRAGMA_ONCE
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 #include "ace/Hash_Map_Manager_T.h"
00024 
00025 #include "tao/Cache_Entries.h"
00026 #include "tao/orbconf.h"
00027 
00028 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00029 class ACE_Handle_Set;
00030 template <class T> class ACE_Unbounded_Set;
00031 template <class T> class ACE_Unbounded_Set_Iterator;
00032 ACE_END_VERSIONED_NAMESPACE_DECL
00033 
00034 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00035 
00036 class TAO_Connection_Handler;
00037 class TAO_ORB_Core;
00038 class TAO_Resource_Factory;
00039 class TAO_Connection_Purging_Strategy;
00040 
00041 template <class ACE_COND_MUTEX> class TAO_Condition;
00042 
00043 namespace TAO
00044 {
00045   typedef ACE_Unbounded_Set<TAO_Connection_Handler*> Connection_Handler_Set;
00046   /**
00047    * @class Transport_Cache_Manager
00048    *
00049    * @brief The Transport Cache Manager for TAO
00050    *
00051    * This class provides interfaces associating a TAO_Cache_ExtId
00052    * & TAO_Cache_IntId. This class is wrapper around the
00053    * ACE_Hash_Map_Manager  class which is used as a container to Cache
00054    * the connections. This class protects the entries with a lock. The
00055    * map is updated only by holding the lock. The more compelling reason
00056    * to have the lock in this class and not in the Hash_Map is that, we
00057    * do quite a bit of work in this class for which we need a lock.
00058    *
00059    */
00060   class TAO_Export Transport_Cache_Manager
00061   {
00062   public:
00063     // Some useful typedef's
00064     typedef ACE_Hash_Map_Manager_Ex <Cache_ExtId,
00065                                      Cache_IntId,
00066                                      ACE_Hash<Cache_ExtId>,
00067                                      ACE_Equal_To<Cache_ExtId>,
00068                                      ACE_Null_Mutex>
00069     HASH_MAP;
00070 
00071     typedef HASH_MAP::iterator HASH_MAP_ITER;
00072 
00073     typedef ACE_Hash_Map_Entry <Cache_ExtId,
00074                                 Cache_IntId>
00075     HASH_MAP_ENTRY;
00076 
00077     typedef TAO_Condition<TAO_SYNCH_MUTEX> CONDITION;
00078 
00079     // == Public methods
00080     /// Constructor
00081     Transport_Cache_Manager (TAO_ORB_Core &orb_core);
00082 
00083     /// Destructor
00084     ~Transport_Cache_Manager (void);
00085 
00086     /// Add the transport to the cache.
00087     /**
00088      * The transport has the property definition based on which caching
00089      * can be done. This method marks the transport
00090      * <CODE>ACE_RECYCLABLE_BUSY </CODE> which helps the threads
00091      * opening up connections to use the  transport immediately.
00092      */
00093     int cache_transport (TAO_Transport_Descriptor_Interface *prop,
00094                          TAO_Transport *transport);
00095 
00096     /// Similar to the one above, but the transport is left in <CODE>
00097     /// ENTRY_IDLE_AND_PURGABLE</CODE> state.
00098     int cache_idle_transport (TAO_Transport_Descriptor_Interface *prop,
00099                               TAO_Transport *transport);
00100 
00101     /// Check the Transport Cache to check whether the connection exists
00102     /// in the Cache and return the connection
00103     int find_transport (TAO_Transport_Descriptor_Interface *prop,
00104                         TAO_Transport *&transport);
00105 
00106     /// Remove entries from the cache depending upon the strategy.
00107     int purge (void);
00108 
00109     /// Purge the entry from the Cache Map
00110     int purge_entry (HASH_MAP_ENTRY *&);
00111 
00112     /// Mark the entry as invalid for use but keep it in cache.
00113     void mark_invalid (HASH_MAP_ENTRY *&);
00114 
00115     /// Make the entry idle and ready for use.
00116     int make_idle (HASH_MAP_ENTRY *&entry);
00117 
00118     /// Mark the entry as touched. This call updates the purging
00119     /// strategy policy information.
00120     int update_entry (HASH_MAP_ENTRY *&entry);
00121 
00122     /// Close the underlying hash map manager and return any handlers
00123     /// still registered
00124     int close (Connection_Handler_Set &handlers);
00125 
00126     /// Return a set of connection handlers that belong to transports
00127     /// that have a RW wait strategy.
00128     /**
00129      * This call is used for a specific use case by the ORB_Core
00130      * during shutdown. The only way the ORB can wake up threads
00131      * waiting on these sockstes for replies is to iterate over
00132      * these blockable transports and close the socket
00133      * handles. Without these the threads will continue to wait there
00134      * for ever.
00135      */
00136     bool blockable_client_transports (Connection_Handler_Set &handlers);
00137 
00138     /// Return the current size of the cache.
00139     size_t current_size (void) const;
00140 
00141     /// Return the total size of the cache.
00142     size_t total_size (void) const;
00143 
00144     /// Return the underlying cache map
00145     HASH_MAP &map (void);
00146 
00147   private:
00148     /// Associate @a ext_id with @a int_id. Grabs the lock and calls the
00149     /// implementation function bind_i.
00150     int bind (Cache_ExtId &ext_id,
00151               Cache_IntId &int_id);
00152 
00153     /// Lookup entry<key,value> in the cache. Grabs the lock and calls the
00154     /// implementation function find_i.
00155     int find (const Cache_ExtId &key,
00156               Cache_IntId &value);
00157 
00158     /**
00159      * Non-Locking version and actual implementation of bind ()
00160      * call. Calls bind on the Hash_Map_Manager that it holds. If the
00161      * bind succeeds, it adds the Hash_Map_Entry in to the
00162      * Transport for its reference. If the bind fails because
00163      * of an exiting entry, this method calls the get_last_index_bind
00164      * ().
00165      */
00166     int bind_i (Cache_ExtId &ext_id,
00167                 Cache_IntId &int_id);
00168 
00169     /**
00170      * Non-locking version and actual implementation of find ()
00171      * call. This calls the find () on the underlying
00172      * Hash_Map_Manager. If the find succeeds, it calls the
00173      * get_idle_transport ().
00174      */
00175     int find_i (const Cache_ExtId &key,
00176                 Cache_IntId &value);
00177 
00178     /// Non-locking version and actual implementation of make_idle ().
00179     int make_idle_i (HASH_MAP_ENTRY *&entry);
00180 
00181     /// Non-locking version and actual implementation of close ()
00182     int close_i (Connection_Handler_Set &handlers);
00183 
00184     /// Purge the entry from the Cache Map
00185     int purge_entry_i (HASH_MAP_ENTRY *&entry);
00186 
00187     /// Mark the entry as invalid for use but keep it in cache.
00188     void mark_invalid_i (HASH_MAP_ENTRY *&);
00189 
00190   private:
00191     /**
00192      * This is called by the bind () call when a bind fails with a
00193      * available entry. When a new connection is created in TAO with an
00194      * already existing endpoint, in addition to an exisitng one, we
00195      * mark the connections with an index. This method, finds out the
00196      * last highest index and binds the entry with an index = (last
00197      * highest index + 1).
00198      */
00199     int get_last_index_bind (Cache_ExtId &key,
00200                              Cache_IntId &val,
00201                              HASH_MAP_ENTRY *&entry);
00202 
00203   /**
00204    * Tries to find if the <int_id_> in entry is idle for use. If it is
00205    * idle it is immediately markes as busy and returns a value of
00206    * 1, else it returns a value of 0
00207    */
00208     bool is_entry_idle (HASH_MAP_ENTRY *&entry);
00209 
00210 #if !defined(ACE_LACKS_QSORT)
00211     /// Used by qsort
00212     static int cpscmp(const void* a, const void* b);
00213 #endif
00214 
00215     typedef HASH_MAP_ENTRY** DESCRIPTOR_SET;
00216 
00217     /// Sort the list of entries
00218     void sort_set (DESCRIPTOR_SET& entries, int size);
00219 
00220     /// Fill sorted_set in with the TAO_Transport_Descriptor_Interface's in
00221     /// a sorted order.
00222     int fill_set_i (DESCRIPTOR_SET& sorted_set);
00223 
00224     /// Wait for connections if we have reached the limit on the number
00225     /// of muxed connections. If not (ie. if we dont use a muxed
00226     /// connection or if we have not reached the limit) this just
00227     /// behaves as a no-op. <extid> has all the information about the
00228     /// connection that is being searched.
00229     int wait_for_connection (Cache_ExtId &extid);
00230 
00231     /// Is the wakeup useful todo some work?
00232     int is_wakeup_useful (Cache_ExtId &extid);
00233 
00234     /// Non-locking version of blockable_client_transports ().
00235     bool blockable_client_transports_i (Connection_Handler_Set &handlers);
00236 
00237   private:
00238     /// The percentage of the cache to purge at one time
00239     int percent_;
00240 
00241     /// The underlying connection purging strategy
00242     TAO_Connection_Purging_Strategy *purging_strategy_;
00243 
00244     /// The hash map that has the connections
00245     HASH_MAP cache_map_;
00246 
00247     /// The condition variable
00248     CONDITION *condition_;
00249 
00250     /// The lock that is used by the cache map
00251     ACE_Lock *cache_lock_;
00252 
00253     /// Number of allowed muxed connections
00254     CORBA::ULong muxed_number_;
00255 
00256     /// Number of threads waiting for connections
00257     int no_waiting_threads_;
00258 
00259     /// This is for optimization purposes. In a situation where number
00260     /// of threads are waiting for connections, the last connection that
00261     /// is put back is cached here. This should prevent all th threads
00262     /// trying to search for their required entry.
00263     Cache_ExtId *last_entry_returned_;
00264   };
00265 
00266 }
00267 
00268 TAO_END_VERSIONED_NAMESPACE_DECL
00269 
00270 #if defined (__ACE_INLINE__)
00271 # include "tao/Transport_Cache_Manager.inl"
00272 #endif /* __ACE_INLINE__ */
00273 
00274 #include /**/ "ace/post.h"
00275 
00276 #endif /*TAO_CONNECTION_CACHE_MANAGER_H*/

Generated on Thu Nov 9 11:54:26 2006 for TAO by doxygen 1.3.6