TAO::Transport_Cache_Manager Class Reference

The Transport Cache Manager for TAO. More...

#include <Transport_Cache_Manager.h>

Collaboration diagram for TAO::Transport_Cache_Manager:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_Hash_Map_Manager_Ex<
Cache_ExtId, Cache_IntId,
ACE_Hash< Cache_ExtId >,
ACE_Equal_To< Cache_ExtId >,
ACE_Null_Mutex
HASH_MAP
typedef HASH_MAP::iterator HASH_MAP_ITER
typedef ACE_Hash_Map_Entry<
Cache_ExtId, Cache_IntId
HASH_MAP_ENTRY
typedef TAO_Condition< TAO_SYNCH_MUTEX > CONDITION

Public Member Functions

 Transport_Cache_Manager (TAO_ORB_Core &orb_core)
 Constructor.

 ~Transport_Cache_Manager (void)
 Destructor.

int cache_transport (TAO_Transport_Descriptor_Interface *prop, TAO_Transport *transport)
 Add the transport to the cache.

int cache_idle_transport (TAO_Transport_Descriptor_Interface *prop, TAO_Transport *transport)
int find_transport (TAO_Transport_Descriptor_Interface *prop, TAO_Transport *&transport)
int purge (void)
 Remove entries from the cache depending upon the strategy.

int purge_entry (HASH_MAP_ENTRY *&)
 Purge the entry from the Cache Map.

void mark_invalid (HASH_MAP_ENTRY *&)
 Mark the entry as invalid for use but keep it in cache.

int make_idle (HASH_MAP_ENTRY *&entry)
 Make the entry idle and ready for use.

int update_entry (HASH_MAP_ENTRY *&entry)
int close (Connection_Handler_Set &handlers)
bool blockable_client_transports (Connection_Handler_Set &handlers)
size_t current_size (void) const
 Return the current size of the cache.

size_t total_size (void) const
 Return the total size of the cache.

HASH_MAPmap (void)
 Return the underlying cache map.


Private Types

typedef HASH_MAP_ENTRY ** DESCRIPTOR_SET

Private Member Functions

int bind (Cache_ExtId &ext_id, Cache_IntId &int_id)
int find (const Cache_ExtId &key, Cache_IntId &value)
int bind_i (Cache_ExtId &ext_id, Cache_IntId &int_id)
int find_i (const Cache_ExtId &key, Cache_IntId &value)
int make_idle_i (HASH_MAP_ENTRY *&entry)
 Non-locking version and actual implementation of make_idle ().

int close_i (Connection_Handler_Set &handlers)
 Non-locking version and actual implementation of close ().

int purge_entry_i (HASH_MAP_ENTRY *&entry)
 Purge the entry from the Cache Map.

void mark_invalid_i (HASH_MAP_ENTRY *&)
 Mark the entry as invalid for use but keep it in cache.

int get_last_index_bind (Cache_ExtId &key, Cache_IntId &val, HASH_MAP_ENTRY *&entry)
bool is_entry_idle (HASH_MAP_ENTRY *&entry)
void sort_set (DESCRIPTOR_SET &entries, int size)
 Sort the list of entries.

int fill_set_i (DESCRIPTOR_SET &sorted_set)
int wait_for_connection (Cache_ExtId &extid)
int is_wakeup_useful (Cache_ExtId &extid)
 Is the wakeup useful todo some work?

bool blockable_client_transports_i (Connection_Handler_Set &handlers)
 Non-locking version of blockable_client_transports ().


Static Private Member Functions

int cpscmp (const void *a, const void *b)
 Used by qsort.


Private Attributes

int percent_
 The percentage of the cache to purge at one time.

TAO_Connection_Purging_Strategypurging_strategy_
 The underlying connection purging strategy.

HASH_MAP cache_map_
 The hash map that has the connections.

CONDITIONcondition_
 The condition variable.

ACE_Lockcache_lock_
 The lock that is used by the cache map.

CORBA::ULong muxed_number_
 Number of allowed muxed connections.

int no_waiting_threads_
 Number of threads waiting for connections.

Cache_ExtIdlast_entry_returned_

Detailed Description

The Transport Cache Manager for TAO.

This class provides interfaces associating a TAO_Cache_ExtId & TAO_Cache_IntId. This class is wrapper around the ACE_Hash_Map_Manager class which is used as a container to Cache the connections. This class protects the entries with a lock. The map is updated only by holding the lock. The more compelling reason to have the lock in this class and not in the Hash_Map is that, we do quite a bit of work in this class for which we need a lock.

Definition at line 60 of file Transport_Cache_Manager.h.


Member Typedef Documentation

typedef TAO_Condition<TAO_SYNCH_MUTEX> TAO::Transport_Cache_Manager::CONDITION
 

Definition at line 77 of file Transport_Cache_Manager.h.

typedef HASH_MAP_ENTRY** TAO::Transport_Cache_Manager::DESCRIPTOR_SET [private]
 

Definition at line 215 of file Transport_Cache_Manager.h.

Referenced by fill_set_i(), purge(), and sort_set().

typedef ACE_Hash_Map_Manager_Ex<Cache_ExtId, Cache_IntId, ACE_Hash<Cache_ExtId>, ACE_Equal_To<Cache_ExtId>, ACE_Null_Mutex> TAO::Transport_Cache_Manager::HASH_MAP
 

Definition at line 69 of file Transport_Cache_Manager.h.

typedef ACE_Hash_Map_Entry<Cache_ExtId, Cache_IntId> TAO::Transport_Cache_Manager::HASH_MAP_ENTRY
 

Definition at line 75 of file Transport_Cache_Manager.h.

Referenced by bind_i(), TAO_Transport::cache_map_entry(), cpscmp(), fill_set_i(), find_i(), get_last_index_bind(), is_entry_idle(), make_idle(), make_idle_i(), mark_invalid(), mark_invalid_i(), purge_entry(), purge_entry_i(), sort_set(), and update_entry().

typedef HASH_MAP::iterator TAO::Transport_Cache_Manager::HASH_MAP_ITER
 

Definition at line 71 of file Transport_Cache_Manager.h.

Referenced by blockable_client_transports_i(), close_i(), and fill_set_i().


Constructor & Destructor Documentation

TAO::Transport_Cache_Manager::Transport_Cache_Manager TAO_ORB_Core orb_core  ) 
 

Constructor.

If the cache is not going to be locked then dont create a condition variable. Make the to 0, else a single thread could get into waiting mode

Definition at line 27 of file Transport_Cache_Manager.cpp.

References ACE_NEW, TAO_Resource_Factory::locked_transport_cache(), muxed_number_, and TAO_ORB_Core::resource_factory().

00028     : percent_ (orb_core.resource_factory ()->purge_percentage ())
00029     , purging_strategy_ (orb_core.resource_factory ()->create_purging_strategy ())
00030     , cache_map_ (orb_core.resource_factory ()->cache_maximum ())
00031     , condition_ (0)
00032     , cache_lock_ (0)
00033     , muxed_number_ (orb_core.resource_factory ()->max_muxed_connections ())
00034     , no_waiting_threads_ (0)
00035     , last_entry_returned_ (0)
00036   {
00037     if (orb_core.resource_factory ()->locked_transport_cache ())
00038       {
00039         ACE_NEW (this->condition_,
00040                  TAO_Condition <TAO_SYNCH_MUTEX>);
00041 
00042         ACE_NEW (this->cache_lock_,
00043                  ACE_Lock_Adapter <TAO_SYNCH_MUTEX> (*this->condition_->mutex ()));
00044       }
00045     else
00046       {
00047         /// If the cache is not going to be locked then dont create a
00048         /// condition variable. Make the <muxed_number_> to 0, else a
00049         /// single thread could get into waiting mode
00050         this->muxed_number_ = 0;
00051         ACE_NEW (this->cache_lock_,
00052                  ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX>);
00053       }
00054   }

TAO::Transport_Cache_Manager::~Transport_Cache_Manager void   ) 
 

Destructor.

Definition at line 56 of file Transport_Cache_Manager.cpp.

References cache_lock_, no_waiting_threads_, and purging_strategy_.

00057   {
00058     // Wakeup all the waiting threads threads before we shutdown stuff
00059     if (this->no_waiting_threads_)
00060       {
00061         this->condition_->broadcast ();
00062       }
00063 
00064     // Delete the lock that we have
00065     if (this->cache_lock_)
00066       {
00067         delete this->cache_lock_;
00068         this->cache_lock_ = 0;
00069       }
00070 
00071     // Delete the purging strategy
00072     if (this->purging_strategy_)
00073       {
00074         delete this->purging_strategy_;
00075         this->purging_strategy_ = 0;
00076       }
00077 
00078     // Delete the condition variable
00079     if (this->condition_)
00080       {
00081         delete this->condition_;
00082         this->condition_ = 0;
00083       }
00084   }


Member Function Documentation

ACE_INLINE int TAO::Transport_Cache_Manager::bind Cache_ExtId ext_id,
Cache_IntId int_id
[private]
 

Associate ext_id with int_id. Grabs the lock and calls the implementation function bind_i.

Definition at line 11 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, and bind_i().

00013   {
00014     ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00015                               guard,
00016                               *this->cache_lock_,
00017                               -1));
00018 
00019     return this->bind_i (ext_id,
00020                          int_id);
00021   }

int TAO::Transport_Cache_Manager::bind_i Cache_ExtId ext_id,
Cache_IntId int_id
[private]
 

Non-Locking version and actual implementation of bind () call. Calls bind on the Hash_Map_Manager that it holds. If the bind succeeds, it adds the Hash_Map_Entry in to the Transport for its reference. If the bind fails because of an exiting entry, this method calls the get_last_index_bind ().

Definition at line 88 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_ERROR, cache_map_, TAO_Transport::cache_map_entry(), get_last_index_bind(), HASH_MAP_ENTRY, TAO_Transport::id(), LM_DEBUG, LM_ERROR, TAO::Cache_ExtId::property(), purging_strategy_, TAO_debug_level, TAO::Cache_IntId::transport(), and TAO_Connection_Purging_Strategy::update_item().

Referenced by bind(), cache_idle_transport(), and cache_transport().

00090   {
00091     if (TAO_debug_level > 0)
00092        {
00093          ACE_DEBUG ((LM_DEBUG,
00094                     "TAO (%P|%t) - Transport_Cache_Manager::bind_i, "
00095                     "0x%x -> 0x%x Transport[%d]\n",
00096                      ext_id.property (),
00097                     int_id.transport (),
00098                     int_id.transport ()->id ()));
00099        }
00100 
00101     // Get the entry too
00102     HASH_MAP_ENTRY *entry = 0;
00103 
00104     // Update the purging strategy information while we
00105     // are holding our lock
00106     this->purging_strategy_->update_item (int_id.transport ());
00107 
00108     int retval = this->cache_map_.bind (ext_id,
00109                                         int_id,
00110                                         entry);
00111     if (retval == 0)
00112       {
00113         // The entry has been added to cache succesfully
00114         // Add the cache_map_entry to the transport
00115         int_id.transport ()->cache_map_entry (entry);
00116       }
00117     else if (retval == 1)
00118       {
00119         if (TAO_debug_level > 4)
00120           {
00121             ACE_DEBUG ((LM_DEBUG,
00122                         "TAO (%P|%t) - Transport_Cache_Manager::bind_i, "
00123                         "unable to bind in the first attempt. "
00124                         "Trying with a new index\n"));
00125           }
00126 
00127         // There was an entry like this before, so let us do some
00128         // minor adjustments and rebind
00129         retval = this->get_last_index_bind (ext_id,
00130                                             int_id,
00131                                             entry);
00132         if (retval == 0)
00133           {
00134             int_id.transport ()->cache_map_entry (entry);
00135           }
00136       }
00137 
00138     if (TAO_debug_level > 5 && retval != 0)
00139       {
00140         ACE_ERROR ((LM_ERROR,
00141                     "TAO (%P|%t) - Transport_Cache_Manager::bind_i, "
00142                     "unable to bind\n"));
00143       }
00144     else if (TAO_debug_level > 3)
00145       {
00146         ACE_DEBUG ((LM_DEBUG,
00147                     "TAO (%P|%t) - Transport_Cache_Manager::bind_i, "
00148                     "cache size is [%d]\n",
00149                     this->current_size ()));
00150       }
00151 
00152     return retval;
00153   }

ACE_INLINE bool TAO::Transport_Cache_Manager::blockable_client_transports Connection_Handler_Set handlers  ) 
 

This call is used for a specific use case by the ORB_Core during shutdown. The only way the ORB can wake up threads waiting on these sockstes for replies is to iterate over these blockable transports and close the socket handles. Without these the threads will continue to wait there for ever.

Definition at line 127 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, blockable_client_transports_i(), and TAO::Connection_Handler_Set.

Referenced by TAO_Thread_Lane_Resources::cleanup_rw_transports().

00129   {
00130     ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00131                               guard,
00132                               *this->cache_lock_,
00133                               false));
00134 
00135     return this->blockable_client_transports_i (handlers);
00136   }

bool TAO::Transport_Cache_Manager::blockable_client_transports_i Connection_Handler_Set handlers  )  [private]
 

Non-locking version of blockable_client_transports ().

Definition at line 368 of file Transport_Cache_Manager.cpp.

References cache_map_, TAO::Connection_Handler_Set, TAO::ENTRY_CLOSED, and HASH_MAP_ITER.

Referenced by blockable_client_transports().

00370   {
00371     HASH_MAP_ITER end_iter = this->cache_map_.end ();
00372 
00373     for (HASH_MAP_ITER iter = this->cache_map_.begin ();
00374          iter != end_iter;
00375          ++iter)
00376       {
00377         // Get the transport to fill its associated connection's
00378         // handler.
00379         bool retval =
00380           (*iter).int_id_.transport ()->provide_blockable_handler (h);
00381 
00382         // Do not mark the entry as closed if we don't have a
00383         // blockable handler added
00384         if (retval)
00385           (*iter).int_id_.recycle_state (ENTRY_CLOSED);
00386       }
00387 
00388     return true;
00389   }

ACE_INLINE int TAO::Transport_Cache_Manager::cache_idle_transport TAO_Transport_Descriptor_Interface prop,
TAO_Transport transport
 

Similar to the one above, but the transport is left in ENTRY_IDLE_AND_PURGABLE state.

Definition at line 50 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, bind_i(), TAO::ENTRY_IDLE_AND_PURGABLE, and TAO::Cache_IntId::recycle_state().

Referenced by TAO_IIOP_Connection_Handler::add_transport_to_cache().

00053   {
00054     // Compose the ExternId & Intid
00055     Cache_ExtId ext_id (prop);
00056     Cache_IntId int_id (transport);
00057 
00058     int retval = 0;
00059     {
00060       ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00061                                 guard,
00062                                 *this->cache_lock_,
00063                                 -1));
00064 
00065       // Do as the semantics of this method dictates
00066       int_id.recycle_state (ENTRY_IDLE_AND_PURGABLE);
00067       retval = this->bind_i (ext_id,
00068                              int_id);
00069     }
00070 
00071     return retval;
00072   }

ACE_INLINE int TAO::Transport_Cache_Manager::cache_transport TAO_Transport_Descriptor_Interface prop,
TAO_Transport transport
 

Add the transport to the cache.

The transport has the property definition based on which caching can be done. This method marks the transport ACE_RECYCLABLE_BUSY which helps the threads opening up connections to use the transport immediately.

Definition at line 24 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, bind_i(), TAO::ENTRY_BUSY, and TAO::Cache_IntId::recycle_state().

Referenced by TAO_Transport::recache_transport().

00027   {
00028     // Compose the ExternId & Intid
00029     Cache_ExtId ext_id (prop);
00030     Cache_IntId int_id (transport);
00031 
00032     int retval = 0;
00033     {
00034       ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00035                                 guard,
00036                                 *this->cache_lock_,
00037                                 -1));
00038 
00039       // Do as the semantics of this method dictates
00040       int_id.recycle_state (ENTRY_BUSY);
00041 
00042       retval = this->bind_i (ext_id,
00043                              int_id);
00044     }
00045 
00046     return retval;
00047   }

ACE_INLINE int TAO::Transport_Cache_Manager::close Connection_Handler_Set handlers  ) 
 

Close the underlying hash map manager and return any handlers still registered

Definition at line 109 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, cache_lock_, close_i(), and TAO::Connection_Handler_Set.

Referenced by TAO_Thread_Lane_Resources::finalize().

00110   {
00111     // The cache lock pointer should only be zero if
00112     // Transport_Cache_Manager::open() was never called.  Note that
00113     // only one thread opens the Transport_Cache_Manager at any given
00114     // time, so it is safe to check for a non-zero lock pointer.
00115     if (this->cache_lock_ == 0)
00116       return -1;
00117 
00118     ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00119                               guard,
00120                               *this->cache_lock_,
00121                               -1));
00122 
00123     return this->close_i (handlers);
00124   }

int TAO::Transport_Cache_Manager::close_i Connection_Handler_Set handlers  )  [private]
 

Non-locking version and actual implementation of close ().

Definition at line 343 of file Transport_Cache_Manager.cpp.

References cache_map_, TAO::Connection_Handler_Set, and HASH_MAP_ITER.

Referenced by close().

00344   {
00345     HASH_MAP_ITER end_iter = this->cache_map_.end ();
00346 
00347     for (HASH_MAP_ITER iter = this->cache_map_.begin ();
00348          iter != end_iter;
00349          ++iter)
00350       {
00351         // Get the transport to fill its associated connection's handler.
00352         (*iter).int_id_.transport ()->provide_handler (handlers);
00353 
00354         // Inform the transport that has a reference to the entry in the
00355         // map that we are *gone* now. So, the transport should not use
00356         // the reference to the entry that he has, to acces us *at any
00357         // time*.
00358         (*iter).int_id_.transport ()->cache_map_entry (0);
00359       }
00360 
00361     // Unbind all the entries in the map
00362     this->cache_map_.unbind_all ();
00363 
00364     return 0;
00365   }

int TAO::Transport_Cache_Manager::cpscmp const void *  a,
const void *  b
[static, private]
 

Used by qsort.

Definition at line 468 of file Transport_Cache_Manager.cpp.

References HASH_MAP_ENTRY.

Referenced by sort_set().

00469   {
00470     const HASH_MAP_ENTRY** left  = (const HASH_MAP_ENTRY**)a;
00471     const HASH_MAP_ENTRY** right = (const HASH_MAP_ENTRY**)b;
00472 
00473     if ((*left)->int_id_.transport ()->purging_order () <
00474         (*right)->int_id_.transport ()->purging_order ())
00475       return -1;
00476 
00477     if ((*left)->int_id_.transport ()->purging_order () >
00478         (*right)->int_id_.transport ()->purging_order ())
00479       return 1;
00480 
00481     return 0;
00482   }

ACE_INLINE size_t TAO::Transport_Cache_Manager::current_size void   )  const
 

Return the current size of the cache.

Definition at line 139 of file Transport_Cache_Manager.inl.

References cache_map_.

00140   {
00141     return this->cache_map_.current_size ();
00142   }

int TAO::Transport_Cache_Manager::fill_set_i DESCRIPTOR_SET sorted_set  )  [private]
 

Fill sorted_set in with the TAO_Transport_Descriptor_Interface's in a sorted order.

Definition at line 605 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_NEW_RETURN, ACE_TEXT, cache_map_, TAO_Connection_Purging_Strategy::cache_maximum(), DESCRIPTOR_SET, HASH_MAP_ENTRY, HASH_MAP_ITER, LM_DEBUG, purging_strategy_, sort_set(), and TAO_debug_level.

Referenced by purge().

00606   {
00607     int current_size = 0;
00608     int cache_maximum = this->purging_strategy_->cache_maximum ();
00609 
00610     // set sorted_set to 0.  This signifies nothing to purge.
00611     sorted_set = 0;
00612 
00613     // Do we need to worry about cache purging?
00614     if (cache_maximum >= 0)
00615       {
00616         current_size = static_cast<int> (this->cache_map_.current_size ());
00617 
00618         if (TAO_debug_level > 0)
00619           {
00620             ACE_DEBUG ((LM_DEBUG,
00621                         ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager::fill_set_i, ")
00622                         ACE_TEXT("current_size = %d, cache_maximum = %d\n"),
00623                         current_size, cache_maximum));
00624           }
00625 
00626         if (current_size >= cache_maximum)
00627           {
00628             ACE_NEW_RETURN (sorted_set, HASH_MAP_ENTRY*[current_size], 0);
00629 
00630             HASH_MAP_ITER iter = this->cache_map_.begin ();
00631 
00632             for (int i = 0; i < current_size; ++i)
00633               {
00634                 sorted_set[i] = &(*iter);
00635                 iter++;
00636               }
00637 
00638             this->sort_set (sorted_set, current_size);
00639           }
00640     }
00641 
00642     return current_size;
00643   }

int TAO::Transport_Cache_Manager::find const Cache_ExtId key,
Cache_IntId value
[private]
 

Lookup entry<key,value> in the cache. Grabs the lock and calls the implementation function find_i.

Definition at line 207 of file Transport_Cache_Manager.cpp.

References ACE_GUARD_RETURN, find_i(), purging_strategy_, TAO::Cache_IntId::transport(), and TAO_Connection_Purging_Strategy::update_item().

Referenced by find_transport().

00209   {
00210     ACE_MT (ACE_GUARD_RETURN  (ACE_Lock,
00211                                guard,
00212                                *this->cache_lock_,
00213                                -1));
00214 
00215     int status =  this->find_i (key,
00216                                 value);
00217 
00218     if (status == 0)
00219       {
00220         // Update the purging strategy information while we
00221         // are holding our lock
00222         this->purging_strategy_->update_item (value.transport ());
00223       }
00224 
00225     return status;
00226   }

int TAO::Transport_Cache_Manager::find_i const Cache_ExtId key,
Cache_IntId value
[private]
 

Non-locking version and actual implementation of find () call. This calls the find () on the underlying Hash_Map_Manager. If the find succeeds, it calls the get_idle_transport ().

Definition at line 229 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_TEXT, cache_map_, TAO::ENTRY_BUSY, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::ext_id_, HASH_MAP_ENTRY, TAO::Cache_ExtId::incr_index(), ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, is_entry_idle(), LM_DEBUG, LM_ERROR, TAO::Cache_ExtId::property(), TAO_debug_level, and wait_for_connection().

Referenced by find().

00231   {
00232     HASH_MAP_ENTRY *entry = 0;
00233 
00234     // Get the entry from the Hash Map
00235     int retval = 0;
00236 
00237     // Make a temporary object. It does not do a copy.
00238     Cache_ExtId tmp_key (key.property ());
00239 
00240     while (retval == 0)
00241       {
00242         // Wait for a connection..
00243         this->wait_for_connection (tmp_key);
00244 
00245         // Look for an entry in the map
00246         retval = this->cache_map_.find (tmp_key,
00247                                         entry);
00248 
00249         // We have an entry in the map, check whether it is idle.
00250         if (entry)
00251           {
00252             CORBA::Boolean idle =
00253               this->is_entry_idle (entry);
00254 
00255             if (idle)
00256               {
00257                 // Successfully found a TAO_Transport.
00258 
00259                 entry->int_id_.recycle_state (ENTRY_BUSY);
00260 
00261                 // NOTE: This assignment operator indirectly incurs two
00262                 //       lock operations since it duplicates and releases
00263                 //       TAO_Transport objects.
00264                 value = entry->int_id_;
00265 
00266                 if (TAO_debug_level > 4)
00267                   {
00268                     ACE_DEBUG ((LM_DEBUG,
00269                                 ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager::find_i, ")
00270                                 ACE_TEXT("at index %d (Transport[%d]) - idle\n"),
00271                                 entry->ext_id_.index (),
00272                                 entry->int_id_.transport ()->id ()));
00273                   }
00274 
00275                 return 0;
00276               }
00277             else if (TAO_debug_level > 6)
00278                   {
00279                     ACE_DEBUG ((LM_DEBUG,
00280                                 ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager::find_i, ")
00281                                 ACE_TEXT("at index %d (Transport[%d]) - not idle\n"),
00282                                 entry->ext_id_.index (),
00283                                 entry->int_id_.transport ()->id ()));
00284                   }
00285           }
00286 
00287         // Bump the index up
00288         tmp_key.incr_index ();
00289       }
00290 
00291     // If we are here then it is an error
00292     if (TAO_debug_level > 4 && retval != 0)
00293       {
00294         ACE_ERROR ((LM_ERROR,
00295                     "TAO (%P|%t) - Transport_Cache_Manager::find_i, "
00296                     "no idle transport is available\n"));
00297       }
00298 
00299     return retval;
00300   }

int TAO::Transport_Cache_Manager::find_transport TAO_Transport_Descriptor_Interface prop,
TAO_Transport *&  transport
 

Check the Transport Cache to check whether the connection exists in the Cache and return the connection

Definition at line 156 of file Transport_Cache_Manager.cpp.

References ACE_ERROR, ACE_TEXT, TAO_ORB_Core::client_factory(), TAO_Transport::event_handler_i(), find(), TAO_Transport::id(), TAO_Wait_Strategy::is_registered(), LM_ERROR, TAO_Wait_Strategy::non_blocking(), TAO_Transport::orb_core(), TAO_ORB_Core::reactor(), TAO::Cache_IntId::relinquish_transport(), ACE_Reactor::remove_handler(), TAO_debug_level, TAO_Client_Strategy_Factory::use_cleanup_options(), and TAO_Transport::wait_strategy().

Referenced by TAO_Connector::connect(), TAO::Profile_Transport_Resolver::find_transport(), and TAO_Connector::parallel_connect().

00159   {
00160     if (prop == 0)
00161       {
00162         transport = 0;
00163         return -1;
00164       }
00165 
00166     // Compose the ExternId
00167     Cache_ExtId ext_id (prop);
00168     Cache_IntId int_id;
00169 
00170     int retval = this->find (ext_id,
00171                              int_id);
00172     if (retval == 0)
00173       {
00174         transport = int_id.relinquish_transport ();
00175 
00176         if (transport->wait_strategy ()->non_blocking () == 0 &&
00177             transport->orb_core ()->client_factory ()->use_cleanup_options ())
00178           {
00179             ACE_Event_Handler *eh =
00180               transport->event_handler_i ();
00181 
00182             ACE_Reactor *r =
00183               transport->orb_core ()->reactor ();
00184 
00185             if (eh &&
00186                 r->remove_handler (eh,
00187                                    ACE_Event_Handler::READ_MASK |
00188                                    ACE_Event_Handler::DONT_CALL) == -1)
00189               {
00190                 if (TAO_debug_level > 0)
00191                   ACE_ERROR ((LM_ERROR,
00192                               ACE_TEXT ("TAO (%P|%t) - TAO_Transport_Cache_Manager[%d]")
00193                               ACE_TEXT ("::find_transport, remove_handler failed \n"),
00194                               transport->id ()));
00195               }
00196             else
00197               {
00198                 transport->wait_strategy ()->is_registered (false);
00199               }
00200           }
00201       }
00202 
00203     return retval;
00204   }

int TAO::Transport_Cache_Manager::get_last_index_bind Cache_ExtId key,
Cache_IntId val,
HASH_MAP_ENTRY *&  entry
[private]
 

This is called by the bind () call when a bind fails with a available entry. When a new connection is created in TAO with an already existing endpoint, in addition to an exisitng one, we mark the connections with an index. This method, finds out the last highest index and binds the entry with an index = (last highest index + 1).

Definition at line 421 of file Transport_Cache_Manager.cpp.

References cache_map_, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::ext_id_, HASH_MAP_ENTRY, and TAO::Cache_ExtId::index().

Referenced by bind_i().

00424   {
00425     CORBA::ULong ctr = entry->ext_id_.index ();
00426     int retval = 0;
00427 
00428     while (retval == 0)
00429       {
00430         // Set the index
00431         key.index (++ctr);
00432 
00433         // Check to see if an element exists in the Map. If it exists we
00434         // loop, else we drop out of the loop
00435         retval = this->cache_map_.find (key);
00436       }
00437 
00438     // Now do a bind again with the new index
00439     return  this->cache_map_.bind (key,
00440                                    val,
00441                                    entry);
00442   }

bool TAO::Transport_Cache_Manager::is_entry_idle HASH_MAP_ENTRY *&  entry  )  [private]
 

Tries to find if the in entry is idle for use. If it is idle it is immediately markes as busy and returns a value of 1, else it returns a value of 0

Definition at line 446 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_TEXT, TAO::Cache_Entries_State, TAO::ENTRY_IDLE_AND_PURGABLE, TAO::ENTRY_IDLE_BUT_NOT_PURGABLE, HASH_MAP_ENTRY, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, LM_DEBUG, and TAO_debug_level.

Referenced by find_i(), and purge().

00447   {
00448     Cache_Entries_State entry_state =
00449       entry->int_id_.recycle_state ();
00450 
00451     if (TAO_debug_level)
00452       {
00453         ACE_DEBUG ((LM_DEBUG,
00454                     ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager::is_entry_idle, ")
00455                     ACE_TEXT("state is [%d]\n"),
00456                     entry_state));
00457       }
00458 
00459     if (entry_state == ENTRY_IDLE_AND_PURGABLE ||
00460         entry_state == ENTRY_IDLE_BUT_NOT_PURGABLE)
00461       return true;
00462 
00463     return false;
00464   }

int TAO::Transport_Cache_Manager::is_wakeup_useful Cache_ExtId extid  )  [private]
 

Is the wakeup useful todo some work?

Definition at line 688 of file Transport_Cache_Manager.cpp.

References TAO::Cache_ExtId::index(), TAO_Transport_Descriptor_Interface::is_equivalent(), last_entry_returned_, no_waiting_threads_, and TAO::Cache_ExtId::property().

Referenced by wait_for_connection().

00689   {
00690     // Get the underlying property that we are looking for
00691     TAO_Transport_Descriptor_Interface *prop = extid.property ();
00692 
00693     // Just check the underlying property for equivalence. If the last
00694     // connection that was returned  had the same property just return
00695     // 1.
00696     if (this->last_entry_returned_ &&
00697         prop->is_equivalent (this->last_entry_returned_->property ()))
00698       {
00699         // Set the index to be right so that we can pick teh connection
00700         // right away..
00701         extid.index (this->last_entry_returned_->index ());
00702 
00703         // There is no more use for it ...
00704         this->last_entry_returned_ = 0;
00705 
00706         return 1;
00707       }
00708 
00709     // If there  is an entry that was returned and if there are more
00710     // threads just wake up the peer to check for the returned
00711     // connection.
00712     if (this->last_entry_returned_ &&
00713         this->no_waiting_threads_ > 1)
00714       {
00715         this->condition_->signal ();
00716       }
00717 
00718     return 0;
00719   }

ACE_INLINE int TAO::Transport_Cache_Manager::make_idle HASH_MAP_ENTRY *&  entry  ) 
 

Make the entry idle and ready for use.

Definition at line 99 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, HASH_MAP_ENTRY, and make_idle_i().

Referenced by TAO_Transport::make_idle().

00100   {
00101     if(entry == 0)
00102       return -1;
00103 
00104     ACE_MT (ACE_GUARD_RETURN (ACE_Lock, guard, *this->cache_lock_, -1));
00105     return this->make_idle_i (entry);
00106   }

int TAO::Transport_Cache_Manager::make_idle_i HASH_MAP_ENTRY *&  entry  )  [private]
 

Non-locking version and actual implementation of make_idle ().

Definition at line 303 of file Transport_Cache_Manager.cpp.

References TAO::ENTRY_IDLE_AND_PURGABLE, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::ext_id_, HASH_MAP_ENTRY, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, last_entry_returned_, and no_waiting_threads_.

Referenced by make_idle().

00304   {
00305     if (entry == 0)
00306       return -1;
00307 
00308     entry->int_id_.recycle_state (ENTRY_IDLE_AND_PURGABLE);
00309 
00310     // Does any one need waking?
00311     if (this->no_waiting_threads_)
00312       {
00313         // We returned this entry to the map
00314         this->last_entry_returned_ = &entry->ext_id_;
00315 
00316         // Wake up a thread
00317         this->condition_->signal ();
00318       }
00319 
00320     return 0;
00321   }

ACE_INLINE Transport_Cache_Manager::HASH_MAP & TAO::Transport_Cache_Manager::map void   ) 
 

Return the underlying cache map.

Definition at line 151 of file Transport_Cache_Manager.inl.

References cache_map_.

00152   {
00153     return this->cache_map_;
00154   }

ACE_INLINE void TAO::Transport_Cache_Manager::mark_invalid HASH_MAP_ENTRY *&   ) 
 

Mark the entry as invalid for use but keep it in cache.

Definition at line 87 of file Transport_Cache_Manager.inl.

References ACE_GUARD, HASH_MAP_ENTRY, and mark_invalid_i().

00088   {
00089     if(entry == 0)
00090       return;
00091 
00092     // Double checked locking
00093     ACE_MT (ACE_GUARD (ACE_Lock, guard, *this->cache_lock_));
00094 
00095     this->mark_invalid_i (entry);
00096   }

void TAO::Transport_Cache_Manager::mark_invalid_i HASH_MAP_ENTRY *&   )  [private]
 

Mark the entry as invalid for use but keep it in cache.

Definition at line 409 of file Transport_Cache_Manager.cpp.

References TAO::ENTRY_PURGABLE_BUT_NOT_IDLE, HASH_MAP_ENTRY, and ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_.

Referenced by mark_invalid().

00410   {
00411     if (entry == 0)
00412       {
00413         return;
00414       }
00415 
00416     // Mark the entry as not usable
00417     entry->int_id_.recycle_state (ENTRY_PURGABLE_BUT_NOT_IDLE);
00418   }

int TAO::Transport_Cache_Manager::purge void   ) 
 

Remove entries from the cache depending upon the strategy.

Definition at line 486 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_GUARD_RETURN, ACE_TEXT, TAO_Transport::add_reference(), TAO_Transport::close_connection(), DESCRIPTOR_SET, TAO::ENTRY_BUSY, fill_set_i(), TAO_Transport::id(), ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, ACE_Unbounded_Stack< T >::is_empty(), is_entry_idle(), LM_DEBUG, LM_INFO, percent_, ACE_Unbounded_Stack< T >::pop(), ACE_Unbounded_Stack< T >::push(), TAO_Transport::remove_reference(), and TAO_debug_level.

Referenced by TAO_Connector::connect(), and TAO_Creation_Strategy< SVC_HANDLER >::make_svc_handler().

00487   {
00488     ACE_Unbounded_Stack<TAO_Transport*> transports_to_be_closed;
00489 
00490     {
00491       ACE_MT (ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->cache_lock_, 0));
00492 
00493       DESCRIPTOR_SET sorted_set = 0;
00494       int sorted_size = this->fill_set_i (sorted_set);
00495 
00496       // Only call close_entries () if sorted_set != 0.  It takes
00497       // control of sorted_set and cleans up any allocated memory.  If
00498       // sorted_set == 0, then there is nothing to de-allocate.
00499       if (sorted_set != 0)
00500         {
00501           // BEGIN FORMER close_entries
00502           // Calculate the number of entries to purge
00503           const int amount = (sorted_size * this->percent_) / 100;
00504 
00505           if (TAO_debug_level > 0)
00506             {
00507               ACE_DEBUG ((LM_DEBUG,
00508                           ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager::")
00509                           ACE_TEXT ("purge,  purging %d of %d cache entries\n"),
00510                           amount,
00511                           sorted_size));
00512             }
00513 
00514           int count = 0;
00515 
00516           for (int i = 0; count < amount && i < sorted_size; ++i)
00517             {
00518               if (this->is_entry_idle (sorted_set[i]))
00519                 {
00520                   sorted_set[i]->int_id_.recycle_state (ENTRY_BUSY);
00521 
00522                   TAO_Transport* transport =
00523                     sorted_set[i]->int_id_.transport ();
00524                   transport->add_reference ();
00525 
00526                   if (transports_to_be_closed.push (transport) != 0)
00527                     {
00528                       ACE_DEBUG ((LM_INFO,
00529                                   ACE_TEXT ("TAO (%P|%t) - ")
00530                                   ACE_TEXT ("Unable to push transport %u ")
00531                                   ACE_TEXT ("on the to-be-closed stack, so ")
00532                                   ACE_TEXT ("it will leak\n"),
00533                                 transport->id ()));
00534                     }
00535 
00536                   if (TAO_debug_level > 0)
00537                     {
00538                       ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - ")
00539                                   ACE_TEXT ("Idle transport found in ")
00540                                   ACE_TEXT ("cache: [%d] \n"),
00541                                   transport->id ()));
00542                     }
00543 
00544                   // Count this as a successful purged entry
00545                   count++;
00546                 }
00547             }
00548 
00549           delete [] sorted_set;
00550           sorted_set = 0;
00551           // END FORMER close_entries
00552         }
00553     }
00554 
00555     // Now, without the lock held, lets go through and close all the transports.
00556     TAO_Transport *transport = 0;
00557 
00558     while (! transports_to_be_closed.is_empty ())
00559       {
00560         if (transports_to_be_closed.pop (transport) == 0)
00561           {
00562             if (transport)
00563               {
00564                 transport->close_connection ();
00565                 transport->remove_reference ();
00566               }
00567           }
00568       }
00569 
00570     return 0;
00571   }

ACE_INLINE int TAO::Transport_Cache_Manager::purge_entry HASH_MAP_ENTRY *&   ) 
 

Purge the entry from the Cache Map.

Definition at line 75 of file Transport_Cache_Manager.inl.

References ACE_GUARD_RETURN, HASH_MAP_ENTRY, and purge_entry_i().

Referenced by TAO_Transport::purge_entry().

00076   {
00077     // Double checked locking
00078     if(entry == 0)
00079       return 0;
00080 
00081     ACE_MT (ACE_GUARD_RETURN (ACE_Lock, guard, *this->cache_lock_, -1));
00082 
00083     return this->purge_entry_i (entry);
00084   }

int TAO::Transport_Cache_Manager::purge_entry_i HASH_MAP_ENTRY *&  entry  )  [private]
 

Purge the entry from the Cache Map.

Definition at line 392 of file Transport_Cache_Manager.cpp.

References cache_map_, and HASH_MAP_ENTRY.

Referenced by purge_entry().

00393   {
00394     if (entry == 0)
00395       {
00396         return 0;
00397       }
00398 
00399     // Remove the entry from the Map
00400     int retval = this->cache_map_.unbind (entry);
00401 
00402     // Set the entry pointer to zero
00403     entry = 0;
00404 
00405     return retval;
00406   }

void TAO::Transport_Cache_Manager::sort_set DESCRIPTOR_SET entries,
int  size
[private]
 

Sort the list of entries.

Definition at line 575 of file Transport_Cache_Manager.cpp.

References ACE_COMPARE_FUNC, cpscmp(), DESCRIPTOR_SET, HASH_MAP_ENTRY, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, and ACE_OS::qsort().

Referenced by fill_set_i().

00577   {
00578 #if defined (ACE_LACKS_QSORT)
00579     // Use insertion sort if we don't have qsort
00580     for(int i = 1; i < current_size; ++i)
00581       {
00582         if (entries[i]->int_id_.transport ()->purging_order () <
00583             entries[i - 1]->int_id_.transport ()->purging_order ())
00584           {
00585             HASH_MAP_ENTRY* entry = entries[i];
00586 
00587             for(int j = i; j > 0 &&
00588                   entries[j - 1]->int_id_.transport ()->purging_order () >
00589                   entry->int_id_.transport ()->purging_order (); --j)
00590               {
00591                 HASH_MAP_ENTRY* holder = entries[j];
00592                 entries[j] = entries[j - 1];
00593                 entries[j - 1] = holder;
00594               }
00595           }
00596       }
00597 #else
00598     ACE_OS::qsort (entries, current_size,
00599                    sizeof (HASH_MAP_ENTRY*), (ACE_COMPARE_FUNC)cpscmp);
00600 #endif /* ACE_LACKS_QSORT */
00601   }

ACE_INLINE size_t TAO::Transport_Cache_Manager::total_size void   )  const
 

Return the total size of the cache.

Definition at line 145 of file Transport_Cache_Manager.inl.

References cache_map_.

00146   {
00147     return this->cache_map_.total_size ();
00148   }

int TAO::Transport_Cache_Manager::update_entry HASH_MAP_ENTRY *&  entry  ) 
 

Mark the entry as touched. This call updates the purging strategy policy information.

Definition at line 324 of file Transport_Cache_Manager.cpp.

References ACE_GUARD_RETURN, HASH_MAP_ENTRY, ACE_Hash_Map_Entry< EXT_ID, INT_ID >::int_id_, purging_strategy_, and TAO_Connection_Purging_Strategy::update_item().

Referenced by TAO_Transport::update_transport().

00325   {
00326     if(entry == 0)
00327       return -1;
00328 
00329     ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00330                               guard,
00331                             *this->cache_lock_, -1));
00332 
00333     if (entry == 0)
00334       return -1;
00335 
00336     TAO_Connection_Purging_Strategy *st = this->purging_strategy_;
00337     (void) st->update_item (entry->int_id_.transport ());
00338 
00339     return 0;
00340   }

int TAO::Transport_Cache_Manager::wait_for_connection Cache_ExtId extid  )  [private]
 

Wait for connections if we have reached the limit on the number of muxed connections. If not (ie. if we dont use a muxed connection or if we have not reached the limit) this just behaves as a no-op. has all the information about the connection that is being searched.

Definition at line 647 of file Transport_Cache_Manager.cpp.

References ACE_DEBUG, ACE_TEXT, TAO::Cache_ExtId::index(), is_wakeup_useful(), LM_DEBUG, muxed_number_, no_waiting_threads_, and TAO_debug_level.

Referenced by find_i().

00648   {
00649     if (this->muxed_number_ && this->muxed_number_ == extid.index ())
00650       {
00651         // If we have a limit on the number of muxed connections for
00652         // a particular endpoint just wait to get the connection
00653         ++this->no_waiting_threads_;
00654 
00655         if (TAO_debug_level > 2)
00656           {
00657             ACE_DEBUG ((LM_DEBUG,
00658                         ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager")
00659                         ACE_TEXT("::wait_for_connection, ")
00660                         ACE_TEXT("entering wait loop\n")));
00661           }
00662 
00663         int ready_togo = 0;
00664 
00665         while (ready_togo == 0)
00666           {
00667             this->condition_->wait ();
00668 
00669             // Check whether we are waiting for this connection
00670             ready_togo = this->is_wakeup_useful (extid);
00671           }
00672 
00673         if (TAO_debug_level > 2)
00674           {
00675             ACE_DEBUG ((LM_DEBUG,
00676                         ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager::wait_for_connection, ")
00677                         ACE_TEXT("left wait loop\n")));
00678           }
00679 
00680         // We are not waiting anymore
00681         --this->no_waiting_threads_;
00682       }
00683 
00684     return 0;
00685   }


Member Data Documentation

ACE_Lock* TAO::Transport_Cache_Manager::cache_lock_ [private]
 

The lock that is used by the cache map.

Definition at line 251 of file Transport_Cache_Manager.h.

Referenced by close(), and ~Transport_Cache_Manager().

HASH_MAP TAO::Transport_Cache_Manager::cache_map_ [private]
 

The hash map that has the connections.

Definition at line 245 of file Transport_Cache_Manager.h.

Referenced by bind_i(), blockable_client_transports_i(), close_i(), current_size(), fill_set_i(), find_i(), get_last_index_bind(), map(), purge_entry_i(), and total_size().

CONDITION* TAO::Transport_Cache_Manager::condition_ [private]
 

The condition variable.

Definition at line 248 of file Transport_Cache_Manager.h.

Cache_ExtId* TAO::Transport_Cache_Manager::last_entry_returned_ [private]
 

This is for optimization purposes. In a situation where number of threads are waiting for connections, the last connection that is put back is cached here. This should prevent all th threads trying to search for their required entry.

Definition at line 263 of file Transport_Cache_Manager.h.

Referenced by is_wakeup_useful(), and make_idle_i().

CORBA::ULong TAO::Transport_Cache_Manager::muxed_number_ [private]
 

Number of allowed muxed connections.

Definition at line 254 of file Transport_Cache_Manager.h.

Referenced by Transport_Cache_Manager(), and wait_for_connection().

int TAO::Transport_Cache_Manager::no_waiting_threads_ [private]
 

Number of threads waiting for connections.

Definition at line 257 of file Transport_Cache_Manager.h.

Referenced by is_wakeup_useful(), make_idle_i(), wait_for_connection(), and ~Transport_Cache_Manager().

int TAO::Transport_Cache_Manager::percent_ [private]
 

The percentage of the cache to purge at one time.

Definition at line 239 of file Transport_Cache_Manager.h.

Referenced by purge().

TAO_Connection_Purging_Strategy* TAO::Transport_Cache_Manager::purging_strategy_ [private]
 

The underlying connection purging strategy.

Definition at line 242 of file Transport_Cache_Manager.h.

Referenced by bind_i(), fill_set_i(), find(), update_entry(), and ~Transport_Cache_Manager().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 12:27:10 2006 for TAO by doxygen 1.3.6