Transport_Cache_Manager.h

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

Generated on Tue Feb 2 17:37:53 2010 for TAO by  doxygen 1.4.7