00001
00002 #include "tao/Transport_Cache_Manager_T.h"
00003 #include "tao/debug.h"
00004 #include "tao/Connection_Purging_Strategy.h"
00005 #include "tao/Client_Strategy_Factory.h"
00006 #include "tao/Condition.h"
00007 #include "tao/Wait_Strategy.h"
00008 #include "ace/ACE.h"
00009 #include "ace/Reactor.h"
00010 #include "ace/Lock_Adapter_T.h"
00011
00012 #if !defined (__ACE_INLINE__)
00013 # include "tao/Transport_Cache_Manager_T.inl"
00014 #endif
00015
00016 ACE_RCSID (tao,
00017 Transport_Cache_Manager_T,
00018 "$Id: Transport_Cache_Manager_T.cpp 90455 2010-06-08 09:09:16Z johnnyw $")
00019
00020
00021
00022
00023
00024
00025
00026
00027 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00028
00029 namespace TAO
00030 {
00031 template <typename TT, typename TRDT, typename PSTRAT>
00032 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::Transport_Cache_Manager_T (
00033 int percent,
00034 purging_strategy* purging_strategy,
00035 size_t cache_maximum,
00036 bool locked,
00037 const char *orbid)
00038 : percent_ (percent)
00039 , purging_strategy_ (purging_strategy)
00040 , cache_map_ (cache_maximum)
00041 , cache_lock_ (0)
00042 , cache_maximum_ (cache_maximum)
00043 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00044 , purge_monitor_ (0)
00045 , size_monitor_ (0)
00046 #endif
00047 {
00048 if (locked)
00049 {
00050 ACE_NEW (this->cache_lock_,
00051 ACE_Lock_Adapter <TAO_SYNCH_MUTEX> (this->cache_map_mutex_));
00052 }
00053 else
00054 {
00055 ACE_NEW (this->cache_lock_,
00056 ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX>);
00057 }
00058
00059 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00060 ACE_NEW (this->purge_monitor_,
00061 ACE::Monitor_Control::Size_Monitor);
00062 ACE_NEW (this->size_monitor_,
00063 ACE::Monitor_Control::Size_Monitor);
00064
00065 ACE_CString purge_name ("Connection_Cache_Purge_");
00066 ACE_CString size_name ("Connection_Cache_Size_");
00067
00068 purge_name += orbid;
00069 size_name += orbid;
00070
00071 this->purge_monitor_->name (purge_name.c_str ());
00072 this->size_monitor_->name (size_name.c_str ());
00073
00074 this->purge_monitor_->add_to_registry ();
00075 this->size_monitor_->add_to_registry ();
00076 #else
00077 ACE_UNUSED_ARG (orbid);
00078 #endif
00079 }
00080
00081 template <typename TT, typename TRDT, typename PSTRAT>
00082 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::~Transport_Cache_Manager_T (void)
00083 {
00084 delete this->cache_lock_;
00085 this->cache_lock_ = 0;
00086
00087 delete this->purging_strategy_;
00088 this->purging_strategy_ = 0;
00089
00090 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00091 this->purge_monitor_->remove_from_registry ();
00092 this->size_monitor_->remove_from_registry ();
00093 this->purge_monitor_->remove_ref ();
00094 this->size_monitor_->remove_ref ();
00095 #endif
00096 }
00097
00098 template <typename TT, typename TRDT, typename PSTRAT>
00099 void
00100 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::set_entry_state (HASH_MAP_ENTRY *entry,
00101 TAO::Cache_Entries_State state)
00102 {
00103 ACE_MT (ACE_GUARD (ACE_Lock, guard, *this->cache_lock_));
00104 if (entry != 0)
00105 {
00106 entry->item ().recycle_state (state);
00107 if (state != ENTRY_UNKNOWN && state != ENTRY_CONNECTING
00108 && entry->item ().transport ())
00109 entry->item ().is_connected (
00110 entry->item ().transport ()->is_connected ());
00111 }
00112 }
00113
00114 template <typename TT, typename TRDT, typename PSTRAT>
00115 int
00116 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::bind_i (
00117 Cache_ExtId &ext_id,
00118 Cache_IntId &int_id)
00119 {
00120 if (TAO_debug_level > 4)
00121 {
00122 ACE_DEBUG ((LM_INFO,
00123 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::bind_i, ")
00124 ACE_TEXT ("Transport[%d] @ hash:index{%d:%d}\n"),
00125 int_id.transport ()->id (),
00126 ext_id.hash (),
00127 ext_id.index ()
00128 ));
00129 }
00130
00131
00132 HASH_MAP_ENTRY *entry = 0;
00133
00134
00135
00136 this->purging_strategy_->update_item (int_id.transport ());
00137 int retval = 0;
00138 bool more_to_do = true;
00139 while (more_to_do)
00140 {
00141 if (this->cache_map_.current_size () >= cache_maximum_)
00142 {
00143 retval = -1;
00144 if (TAO_debug_level > 0)
00145 {
00146 ACE_ERROR ((LM_ERROR,
00147 ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager_T::bind_i, ")
00148 ACE_TEXT("ERROR: unable to bind transport, cache is full\n")));
00149 }
00150 more_to_do = false;
00151 }
00152 else
00153 {
00154 retval = this->cache_map_.bind (ext_id, int_id, entry);
00155 if (retval == 0)
00156 {
00157
00158
00159 int_id.transport ()->cache_map_entry (entry);
00160 more_to_do = false;
00161 }
00162 else if (retval == 1)
00163 {
00164 if (entry->item ().transport () == int_id.transport ())
00165 {
00166
00167
00168 entry->item ().recycle_state (int_id.recycle_state ());
00169 if (TAO_debug_level > 9 &&
00170 entry->item ().is_connected () != int_id.is_connected ())
00171 ACE_DEBUG ((LM_DEBUG,
00172 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_")
00173 ACE_TEXT ("Manager::bind_i, Updating existing ")
00174 ACE_TEXT ("entry sets is_connected to %C\n"),
00175 (int_id.is_connected () ? "true" : "false")));
00176
00177 entry->item ().is_connected (int_id.is_connected ());
00178 retval = 0;
00179 more_to_do = false;
00180 }
00181 else
00182 {
00183 ext_id.index (ext_id.index () + 1);
00184 if (TAO_debug_level > 8)
00185 {
00186 ACE_DEBUG ((LM_DEBUG,
00187 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::bind_i, ")
00188 ACE_TEXT ("Unable to bind Transport[%d] @ hash:index{%d:%d}. ")
00189 ACE_TEXT ("Trying with a new index\n"),
00190 int_id.transport ()->id (),
00191 ext_id.hash (),
00192 ext_id.index ()));
00193 }
00194 }
00195 }
00196 else
00197 {
00198 if (TAO_debug_level > 0)
00199 {
00200 ACE_ERROR ((LM_ERROR,
00201 ACE_TEXT("TAO (%P|%t) - Transport_Cache_Manager_T::bind_i, ")
00202 ACE_TEXT("ERROR: unable to bind transport\n")));
00203 }
00204 more_to_do = false;
00205 }
00206 }
00207 }
00208 if (retval == 0)
00209 {
00210 if (TAO_debug_level > 4)
00211 {
00212 ACE_DEBUG ((LM_INFO,
00213 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::bind_i: ")
00214 ACE_TEXT ("Success Transport[%d] @ hash:index{%d:%d}. ")
00215 ACE_TEXT ("Cache size is [%d]\n"),
00216 int_id.transport ()->id (),
00217 ext_id.hash (),
00218 ext_id.index (),
00219 this->current_size ()
00220 ));
00221 }
00222 }
00223
00224 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00225 this->size_monitor_->receive (this->current_size ());
00226 #endif
00227
00228 return retval;
00229 }
00230
00231 template <typename TT, typename TRDT, typename PSTRAT>
00232 typename Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::Find_Result
00233 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::find_transport (
00234 transport_descriptor_type *prop,
00235 transport_type *&transport,
00236 size_t &busy_count)
00237 {
00238 if (prop == 0)
00239 {
00240 transport = 0;
00241 return CACHE_FOUND_NONE;
00242 }
00243
00244 Find_Result find_result = this->find (
00245 prop, transport, busy_count);
00246 if (find_result != CACHE_FOUND_NONE)
00247 {
00248 if (find_result == CACHE_FOUND_AVAILABLE)
00249 {
00250 if (transport->wait_strategy ()->non_blocking () == 0 &&
00251 transport->orb_core ()->client_factory ()->use_cleanup_options ())
00252 {
00253 ACE_Event_Handler * const eh =
00254 transport->event_handler_i ();
00255
00256 ACE_Reactor * const r =
00257 transport->orb_core ()->reactor ();
00258
00259 if (eh &&
00260 r->remove_handler (eh,
00261 ACE_Event_Handler::READ_MASK |
00262 ACE_Event_Handler::DONT_CALL) == -1)
00263 {
00264 if (TAO_debug_level > 0)
00265 ACE_ERROR ((LM_ERROR,
00266 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T[%d]")
00267 ACE_TEXT ("::find_transport, remove_handler failed\n"),
00268 transport->id ()));
00269 }
00270 else
00271 {
00272 transport->wait_strategy ()->is_registered (false);
00273 }
00274 }
00275 }
00276 }
00277 return find_result;
00278 }
00279
00280 template <typename TT, typename TRDT, typename PSTRAT>
00281 typename Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::Find_Result
00282 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::find_i (
00283 transport_descriptor_type *prop,
00284 transport_type *&transport,
00285 size_t &busy_count)
00286 {
00287
00288 Find_Result found = CACHE_FOUND_NONE;
00289
00290
00291 Cache_ExtId key (prop);
00292 HASH_MAP_ENTRY *entry = 0;
00293 busy_count = 0;
00294 int cache_status = 0;
00295 HASH_MAP_ENTRY *found_entry = 0;
00296
00297
00298
00299 while (found != CACHE_FOUND_AVAILABLE && cache_status == 0)
00300 {
00301 entry = 0;
00302 cache_status = this->cache_map_.find (key, entry);
00303 if (cache_status == 0 && entry)
00304 {
00305 if (this->is_entry_available_i (*entry))
00306 {
00307
00308
00309 found = CACHE_FOUND_AVAILABLE;
00310 found_entry = entry;
00311 entry->item ().recycle_state (ENTRY_BUSY);
00312
00313 if (TAO_debug_level > 6)
00314 {
00315 ACE_DEBUG ((LM_DEBUG,
00316 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::find_i, ")
00317 ACE_TEXT ("Found available Transport[%d] @hash:index {%d:%d}\n"),
00318 entry->item ().transport ()->id (),
00319 entry->ext_id_.hash (),
00320 entry->ext_id_.index ()
00321 ));
00322 }
00323 }
00324 else if (this->is_entry_connecting_i (*entry))
00325 {
00326 if (TAO_debug_level > 6)
00327 {
00328 ACE_DEBUG ((LM_DEBUG,
00329 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::find_i, ")
00330 ACE_TEXT ("Found connecting Transport[%d] @hash:index {%d:%d}\n"),
00331 entry->item ().transport ()->id (),
00332 entry->ext_id_.hash (),
00333 entry->ext_id_.index ()
00334 ));
00335 }
00336
00337 if (found != CACHE_FOUND_CONNECTING)
00338 {
00339 found_entry = entry;
00340 found = CACHE_FOUND_CONNECTING;
00341 }
00342 }
00343 else
00344 {
00345
00346 if (found == CACHE_FOUND_NONE && busy_count == 0)
00347 {
00348 found_entry = entry;
00349 found = CACHE_FOUND_BUSY;
00350 }
00351 ++busy_count;
00352 if (TAO_debug_level > 6)
00353 {
00354 ACE_DEBUG ((LM_DEBUG,
00355 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::find_i, ")
00356 ACE_TEXT ("Found busy Transport[%d] @hash:index {%d:%d}\n"),
00357 entry->item ().transport ()->id (),
00358 entry->ext_id_.hash (),
00359 entry->ext_id_.index ()
00360 ));
00361 }
00362 }
00363 }
00364
00365
00366 key.incr_index ();
00367 }
00368 if (found_entry != 0)
00369 {
00370 transport = found_entry->item ().transport ();
00371 transport->add_reference ();
00372 if (found == CACHE_FOUND_AVAILABLE)
00373 {
00374
00375
00376 this->purging_strategy_->update_item (transport);
00377 }
00378 }
00379 return found;
00380 }
00381
00382 template <typename TT, typename TRDT, typename PSTRAT>
00383 int
00384 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::make_idle_i (HASH_MAP_ENTRY *entry)
00385 {
00386 if (entry == 0)
00387 return -1;
00388
00389 entry->item ().recycle_state (ENTRY_IDLE_AND_PURGABLE);
00390
00391 return 0;
00392 }
00393
00394 template <typename TT, typename TRDT, typename PSTRAT>
00395 int
00396 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::update_entry (HASH_MAP_ENTRY *&entry)
00397 {
00398 ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00399 guard,
00400 *this->cache_lock_, -1));
00401
00402 if (entry == 0)
00403 return -1;
00404
00405 purging_strategy *st = this->purging_strategy_;
00406 (void) st->update_item (entry->item ().transport ());
00407
00408 return 0;
00409 }
00410
00411 template <typename TT, typename TRDT, typename PSTRAT>
00412 int
00413 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::close_i (Connection_Handler_Set &handlers)
00414 {
00415 HASH_MAP_ITER end_iter = this->cache_map_.end ();
00416
00417 for (HASH_MAP_ITER iter = this->cache_map_.begin ();
00418 iter != end_iter;
00419 ++iter)
00420 {
00421
00422 (*iter).int_id_.transport ()->provide_handler (handlers);
00423
00424
00425
00426
00427
00428 (*iter).int_id_.transport ()->cache_map_entry (0);
00429 }
00430
00431
00432 this->cache_map_.unbind_all ();
00433
00434 return 0;
00435 }
00436
00437 template <typename TT, typename TRDT, typename PSTRAT>
00438 bool
00439 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::blockable_client_transports_i (
00440 Connection_Handler_Set &h)
00441 {
00442 HASH_MAP_ITER end_iter = this->cache_map_.end ();
00443
00444 for (HASH_MAP_ITER iter = this->cache_map_.begin ();
00445 iter != end_iter;
00446 ++iter)
00447 {
00448
00449
00450 bool const retval =
00451 (*iter).int_id_.transport ()->provide_blockable_handler (h);
00452
00453
00454
00455 if (retval)
00456 (*iter).int_id_.recycle_state (ENTRY_CLOSED);
00457 }
00458
00459 return true;
00460 }
00461
00462 template <typename TT, typename TRDT, typename PSTRAT>
00463 int
00464 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::purge_entry_i (HASH_MAP_ENTRY *&entry)
00465 {
00466 int retval = 0;
00467
00468 if (entry != 0)
00469 {
00470
00471 retval = this->cache_map_.unbind (entry);
00472
00473
00474 entry = 0;
00475
00476 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00477 this->size_monitor_->receive (this->current_size ());
00478 #endif
00479 }
00480
00481 return retval;
00482 }
00483
00484 template <typename TT, typename TRDT, typename PSTRAT>
00485 void
00486 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::mark_invalid_i (HASH_MAP_ENTRY *entry)
00487 {
00488 if (entry != 0)
00489 {
00490
00491 entry->item ().recycle_state (ENTRY_PURGABLE_BUT_NOT_IDLE);
00492 }
00493 }
00494
00495 template <typename TT, typename TRDT, typename PSTRAT>
00496 bool
00497 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::is_entry_available_i (const HASH_MAP_ENTRY &entry)
00498 {
00499 Cache_Entries_State entry_state = entry.int_id_.recycle_state ();
00500 bool result = (entry_state == ENTRY_IDLE_AND_PURGABLE);
00501
00502 if (result && entry.int_id_.transport () != 0)
00503 {
00504
00505 result = entry.int_id_.is_connected ();
00506 }
00507
00508 if (TAO_debug_level > 8)
00509 {
00510 ACE_DEBUG ((LM_DEBUG,
00511 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::")
00512 ACE_TEXT ("is_entry_available_i[%d], %C state is %C\n"),
00513 entry.int_id_.transport () ? entry.int_id_.transport ()->id () : 0,
00514 (result ? "true" : "false"),
00515 Cache_IntId::state_name (entry_state)));
00516 }
00517
00518 return result;
00519 }
00520
00521 template <typename TT, typename TRDT, typename PSTRAT>
00522 bool
00523 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::is_entry_purgable_i (HASH_MAP_ENTRY &entry)
00524 {
00525 Cache_Entries_State entry_state = entry.int_id_.recycle_state ();
00526 transport_type* transport = entry.int_id_.transport ();
00527 bool result = (entry_state == ENTRY_IDLE_AND_PURGABLE ||
00528 entry_state == ENTRY_PURGABLE_BUT_NOT_IDLE)
00529 && transport->can_be_purged ();
00530
00531 if (TAO_debug_level > 8)
00532 {
00533 ACE_DEBUG ((LM_DEBUG,
00534 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::")
00535 ACE_TEXT ("is_entry_purgable_i[%d], %C state is %C\n"),
00536 entry.int_id_.transport ()->id (),
00537 (result ? "true" : "false"),
00538 Cache_IntId::state_name (entry_state)));
00539 }
00540
00541 return result;
00542 }
00543
00544 template <typename TT, typename TRDT, typename PSTRAT>
00545 bool
00546 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::
00547 is_entry_connecting_i (const HASH_MAP_ENTRY &entry)
00548 {
00549 Cache_Entries_State entry_state = entry.int_id_.recycle_state ();
00550 bool result = (entry_state == ENTRY_CONNECTING);
00551
00552 if (!result && entry.int_id_.transport () != 0)
00553 {
00554
00555
00556 result = !entry.int_id_.is_connected ();
00557 }
00558
00559 if (TAO_debug_level > 8)
00560 {
00561 ACE_DEBUG ((LM_DEBUG,
00562 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::")
00563 ACE_TEXT ("is_entry_connecting_i[%d], %C, state is %C\n"),
00564 entry.int_id_.transport () ? entry.int_id_.transport ()->id () : 0,
00565 (result ? "true" : "false"),
00566 Cache_IntId::state_name (entry_state)));
00567 }
00568
00569 return result;
00570 }
00571
00572 #if !defined (ACE_LACKS_QSORT)
00573 template <typename TT, typename TRDT, typename PSTRAT>
00574 int
00575 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::
00576 cpscmp(const void* a, const void* b)
00577 {
00578 const HASH_MAP_ENTRY** left = (const HASH_MAP_ENTRY**)a;
00579 const HASH_MAP_ENTRY** right = (const HASH_MAP_ENTRY**)b;
00580
00581 if ((*left)->int_id_.transport ()->purging_order () <
00582 (*right)->int_id_.transport ()->purging_order ())
00583 return -1;
00584
00585 if ((*left)->int_id_.transport ()->purging_order () >
00586 (*right)->int_id_.transport ()->purging_order ())
00587 return 1;
00588
00589 return 0;
00590 }
00591 #endif
00592
00593 template <typename TT, typename TRDT, typename PSTRAT>
00594 int
00595 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::purge (void)
00596 {
00597 typedef ACE_Unbounded_Set<transport_type*> transport_set_type;
00598 transport_set_type transports_to_be_closed;
00599
00600 {
00601 ACE_MT (ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->cache_lock_, 0));
00602
00603 DESCRIPTOR_SET sorted_set = 0;
00604 int const sorted_size = this->fill_set_i (sorted_set);
00605
00606
00607
00608
00609 if (sorted_set != 0)
00610 {
00611
00612
00613
00614
00615 int const amount = (sorted_size * this->percent_) / 100;
00616
00617 if (TAO_debug_level > 4)
00618 {
00619 ACE_DEBUG ((LM_INFO,
00620 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::purge, ")
00621 ACE_TEXT ("Trying to purge %d of %d cache entries\n"),
00622 amount,
00623 sorted_size));
00624 }
00625
00626 int count = 0;
00627
00628 for (int i = 0; count < amount && i < sorted_size; ++i)
00629 {
00630 if (this->is_entry_purgable_i (*sorted_set[i]))
00631 {
00632 transport_type* transport =
00633 sorted_set[i]->int_id_.transport ();
00634 sorted_set[i]->int_id_.recycle_state (ENTRY_BUSY);
00635 transport->add_reference ();
00636
00637 if (TAO_debug_level > 4)
00638 {
00639 ACE_DEBUG ((LM_INFO,
00640 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::purge, ")
00641 ACE_TEXT ("Purgable Transport[%d] found in ")
00642 ACE_TEXT ("cache\n"),
00643 transport->id ()));
00644 }
00645
00646 if (transports_to_be_closed.insert_tail (transport) != 0)
00647 {
00648 if (TAO_debug_level > 0)
00649 {
00650 ACE_ERROR ((LM_ERROR,
00651 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T")
00652 ACE_TEXT ("::purge, Unable to add transport[%d] ")
00653 ACE_TEXT ("on the to-be-closed set, so ")
00654 ACE_TEXT ("it will not be purged\n"),
00655 transport->id ()));
00656 }
00657 transport->remove_reference ();
00658 }
00659
00660
00661 ++count;
00662 }
00663 }
00664
00665 delete [] sorted_set;
00666 sorted_set = 0;
00667
00668 }
00669 }
00670
00671
00672 if (! transports_to_be_closed.is_empty ())
00673 {
00674 typename transport_set_type::iterator it (transports_to_be_closed);
00675 while (! it.done ())
00676 {
00677 transport_type *transport = *it;
00678
00679 it.advance ();
00680
00681 if (transport)
00682 {
00683 transport->close_connection ();
00684 transport->remove_reference ();
00685 }
00686 }
00687 }
00688
00689 if (TAO_debug_level > 4)
00690 {
00691 ACE_DEBUG ((LM_INFO,
00692 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::purge, ")
00693 ACE_TEXT ("Cache size after purging is [%d]\n"),
00694 this->current_size ()
00695 ));
00696 }
00697
00698 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
00699
00700
00701 this->purge_monitor_->receive (static_cast<size_t> (0UL));
00702
00703 this->size_monitor_->receive (this->current_size ());
00704 #endif
00705
00706 return 0;
00707 }
00708
00709 template <typename TT, typename TRDT, typename PSTRAT>
00710 void
00711 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::
00712 sort_set (DESCRIPTOR_SET& entries, int current_size)
00713 {
00714 #if defined (ACE_LACKS_QSORT)
00715
00716 for(int i = 1; i < current_size; ++i)
00717 {
00718 if (entries[i]->int_id_.transport ()->purging_order () <
00719 entries[i - 1]->int_id_.transport ()->purging_order ())
00720 {
00721 HASH_MAP_ENTRY* entry = entries[i];
00722
00723 for(int j = i; j > 0 &&
00724 entries[j - 1]->int_id_.transport ()->purging_order () >
00725 entry->item ().transport ()->purging_order (); --j)
00726 {
00727 HASH_MAP_ENTRY* holder = entries[j];
00728 entries[j] = entries[j - 1];
00729 entries[j - 1] = holder;
00730 }
00731 }
00732 }
00733 #else
00734 ACE_OS::qsort (entries, current_size,
00735 sizeof (HASH_MAP_ENTRY*), (ACE_COMPARE_FUNC)cpscmp);
00736 #endif
00737 }
00738
00739 template <typename TT, typename TRDT, typename PSTRAT>
00740 int
00741 Transport_Cache_Manager_T<TT, TRDT, PSTRAT>::
00742 fill_set_i (DESCRIPTOR_SET& sorted_set)
00743 {
00744 int current_size = 0;
00745 int const cache_maximum = this->purging_strategy_->cache_maximum ();
00746
00747
00748 sorted_set = 0;
00749
00750
00751 if (cache_maximum >= 0)
00752 {
00753 current_size = static_cast<int> (this->current_size ());
00754
00755 if (TAO_debug_level > 6)
00756 {
00757 ACE_DEBUG ((LM_DEBUG,
00758 ACE_TEXT ("TAO (%P|%t) - Transport_Cache_Manager_T::fill_set_i, ")
00759 ACE_TEXT ("current_size = %d, cache_maximum = %d\n"),
00760 current_size, cache_maximum));
00761 }
00762
00763 if (current_size >= cache_maximum)
00764 {
00765 ACE_NEW_RETURN (sorted_set, HASH_MAP_ENTRY*[current_size], 0);
00766
00767 HASH_MAP_ITER iter = this->cache_map_.begin ();
00768
00769 for (int i = 0; i < current_size; ++i)
00770 {
00771 sorted_set[i] = &(*iter);
00772 ++iter;
00773 }
00774
00775 this->sort_set (sorted_set, current_size);
00776 }
00777 }
00778
00779 return current_size;
00780 }
00781 }
00782
00783 TAO_END_VERSIONED_NAMESPACE_DECL