Skip to content

Commit 2eaaa97

Browse files
authored
Merge pull request #2523 from jwillemsen/jwi-idletransport
Add `-ORBTransportIdleTimeout` to purge idle transports
2 parents 2e72456 + 87a0d08 commit 2eaaa97

30 files changed

Lines changed: 1590 additions & 116 deletions

ACE/ace/Event_Handler_Handle_Timeout_Upcall.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ timeout (ACE_Timer_Queue &timer_queue,
1818
int recurring_timer,
1919
const ACE_Time_Value &cur_time)
2020
{
21-
int requires_reference_counting = 0;
21+
bool requires_reference_counting = false;
2222

2323
if (!recurring_timer)
2424
{
@@ -36,8 +36,7 @@ timeout (ACE_Timer_Queue &timer_queue,
3636
timer_queue.cancel (event_handler, 0); // 0 means "call handle_close()".
3737
}
3838

39-
if (!recurring_timer &&
40-
requires_reference_counting)
39+
if (!recurring_timer && requires_reference_counting)
4140
{
4241
event_handler->remove_reference ();
4342
}

ACE/ace/WFMO_Reactor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ ACE_WFMO_Reactor_Handler_Repository::make_changes_in_suspension_infos ()
868868
// the upcall.
869869
if (event_handler != nullptr)
870870
{
871-
int requires_reference_counting =
871+
bool const requires_reference_counting =
872872
event_handler->reference_counting_policy ().value () ==
873873
ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
874874

@@ -1962,7 +1962,7 @@ ACE_WFMO_Reactor::simple_dispatch_handler (DWORD slot,
19621962
ACE_Event_Handler *event_handler =
19631963
this->handler_rep_.current_info ()[slot].event_handler_;
19641964

1965-
int requires_reference_counting =
1965+
bool const requires_reference_counting =
19661966
event_handler->reference_counting_policy ().value () ==
19671967
ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
19681968

TAO/NEWS

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
USER VISIBLE CHANGES BETWEEN TAO-4.0.5 and TAO-4.0.6
22
====================================================
33

4-
. All issues from bugzilla.dre.vanderbilt.edu migrated to https://github.com/DOCGroup/bugzilla
4+
. All issues from bugzilla.dre.vanderbilt.edu migrated to
5+
https://github.com/DOCGroup/bugzilla
6+
7+
. Add -ORBTransportIdleTimeout to purge idle transports after
8+
a configurable timeout, default is 0 (no purging of idle transports)
59

610
USER VISIBLE CHANGES BETWEEN TAO-4.0.4 and TAO-4.0.5
711
====================================================

TAO/bin/tao_orb_tests.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ TAO/tests/TransportCurrent/Framework/run_test.pl -static: !DISABLE_TRANSPORT_CUR
431431
TAO/tests/TransportCurrent/IIOP/run_test.pl -dynamic: !DISABLE_TRANSPORT_CURRENT !STATIC !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !MINIMUM
432432
TAO/tests/TransportCurrent/IIOP/run_test.pl -static: !DISABLE_TRANSPORT_CURRENT STATIC !CORBA_E_COMPACT !CORBA_E_MICRO !DISABLE_INTERCEPTORS !MINIMUM
433433
TAO/tests/Transport_Cache_Manager/run_test.pl
434+
TAO/tests/Transport_Idle_Timeout/run_test.pl
434435
TAO/tests/UNKNOWN_Exception/run_test.pl:
435436
TAO/tests/Native_Exceptions/run_test.pl:
436437
TAO/tests/Servant_To_Reference_Test/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST

TAO/docs/Options.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,12 @@ <h4><a name="TDRF">1.1. Resource_Factory</a></h4>
13881388
to your config.h file.
13891389
</td>
13901390
</tr>
1391+
<tr>
1392+
<td><code>-ORBTransportIdleTimeout</code> <em>number</em></td>
1393+
<td>Number of seconds after which idle connections are closed and purged from
1394+
the transport cache. By default idle connections are kept until they are
1395+
explicitly closed or purged because the transport cache is almost full.</td>
1396+
</tr>
13911397
</tbody>
13921398
</table>
13931399
</p>

TAO/tao/Cache_Entries_T.inl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ namespace TAO
88
{
99
template <typename TRANSPORT_TYPE> ACE_INLINE
1010
Cache_IntId_T<TRANSPORT_TYPE>::Cache_IntId_T ()
11-
: transport_ (0),
11+
: transport_ (nullptr),
1212
recycle_state_ (ENTRY_UNKNOWN),
1313
is_connected_ (false)
1414
{
1515
}
1616

1717
template <typename TRANSPORT_TYPE> ACE_INLINE
1818
Cache_IntId_T<TRANSPORT_TYPE>::Cache_IntId_T (const Cache_IntId_T &rhs)
19-
: transport_ (0),
19+
: transport_ (nullptr),
2020
recycle_state_ (ENTRY_UNKNOWN),
2121
is_connected_ (false)
2222
{
@@ -75,7 +75,7 @@ namespace TAO
7575
{
7676
// Yield ownership of the TAO_Transport object.
7777
transport_type *val = this->transport_;
78-
this->transport_ = 0;
78+
this->transport_ = nullptr;
7979
return val;
8080
}
8181

@@ -112,7 +112,6 @@ namespace TAO
112112
is_delete_ (false),
113113
index_ (0)
114114
{
115-
116115
}
117116

118117
template <typename TRANSPORT_DESCRIPTOR_TYPE> ACE_INLINE

TAO/tao/Resource_Factory.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,17 @@ class TAO_Export TAO_Resource_Factory : public ACE_Service_Object
245245
virtual void disable_factory () = 0;
246246

247247
/// Return the resource usage strategy.
248-
virtual
249-
TAO_Resource_Factory::Resource_Usage
250-
resource_usage_strategy () const = 0;
248+
virtual TAO_Resource_Factory::Resource_Usage resource_usage_strategy () const = 0;
251249

252250
/// Return the value of the strategy that indicates whether
253251
/// the ORB should wait for the replies during shutdown or drop
254252
/// replies during shutdown.
255253
virtual bool drop_replies_during_shutdown () const = 0;
256254

255+
/// Amount of seconds after which an idle transport will be closed
256+
/// 0 means no closing of idle connections (default)
257+
virtual int transport_idle_timeout () const = 0;
258+
257259
protected:
258260
/**
259261
* Loads the default protocols. This method is used so that the

TAO/tao/Transport.cpp

Lines changed: 137 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
127127
, tail_ (nullptr)
128128
, incoming_message_queue_ (orb_core)
129129
, current_deadline_ (ACE_Time_Value::zero)
130-
, flush_timer_id_ (-1)
131130
, transport_timer_ (this)
131+
, transport_idle_timer_ (this)
132132
, handler_lock_ (orb_core->resource_factory ()->create_cached_connection_lock ())
133133
, id_ ((size_t) this)
134134
, purging_order_ (0)
@@ -183,10 +183,12 @@ TAO_Transport::~TAO_Transport ()
183183
{
184184
if (TAO_debug_level > 9)
185185
{
186-
TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Transport[%d]::~Transport\n"),
186+
TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Transport[%d]::~Transport, start\n"),
187187
this->id_));
188188
}
189189

190+
this->cancel_idle_timer ();
191+
190192
delete this->messaging_object_;
191193

192194
delete this->ws_;
@@ -217,6 +219,11 @@ TAO_Transport::~TAO_Transport ()
217219
#if TAO_HAS_TRANSPORT_CURRENT == 1
218220
delete this->stats_;
219221
#endif /* TAO_HAS_TRANSPORT_CURRENT == 1 */
222+
if (TAO_debug_level > 9)
223+
{
224+
TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - Transport[%d]::~Transport, end\n"),
225+
this->id_));
226+
}
220227
}
221228

222229
void
@@ -324,6 +331,16 @@ TAO_Transport::register_if_necessary ()
324331
void
325332
TAO_Transport::close_connection ()
326333
{
334+
if (TAO_debug_level > 4)
335+
{
336+
TAOLIB_DEBUG ((LM_DEBUG,
337+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::close_connection\n"),
338+
this->id ()));
339+
}
340+
341+
// Cancel any pending timer
342+
this->cancel_idle_timer ();
343+
327344
this->connection_handler_i ()->close_connection ();
328345
}
329346

@@ -375,8 +392,7 @@ TAO_Transport::register_handler ()
375392
this->ws_->is_registered (true);
376393

377394
// Register the handler with the reactor
378-
return r->register_handler (this->event_handler_i (),
379-
ACE_Event_Handler::READ_MASK);
395+
return r->register_handler (this->event_handler_i (), ACE_Event_Handler::READ_MASK);
380396
}
381397

382398
int
@@ -547,12 +563,24 @@ TAO_Transport::make_idle ()
547563
this->id ()));
548564
}
549565

550-
return this->transport_cache_manager ().make_idle (this->cache_map_entry_);
566+
int const result = this->transport_cache_manager ().make_idle (this->cache_map_entry_);
567+
if (result == 0)
568+
{
569+
this->schedule_idle_timer ();
570+
}
571+
return result;
551572
}
552573

553574
int
554575
TAO_Transport::update_transport ()
555576
{
577+
if (TAO_debug_level > 3)
578+
{
579+
TAOLIB_DEBUG ((LM_DEBUG,
580+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::update_transport\n"),
581+
this->id ()));
582+
}
583+
556584
return this->transport_cache_manager ().update_entry (this->cache_map_entry_);
557585
}
558586

@@ -852,7 +880,7 @@ TAO_Transport::schedule_output_i ()
852880
ACE_Event_Handler * const eh = this->event_handler_i ();
853881
ACE_Reactor * const reactor = eh->reactor ();
854882

855-
if (reactor == nullptr)
883+
if (!reactor)
856884
{
857885
if (TAO_debug_level > 1)
858886
{
@@ -940,23 +968,63 @@ TAO_Transport::handle_timeout (const ACE_Time_Value & /* current_time */,
940968
// pending.
941969
this->reset_flush_timer ();
942970

943-
TAO_Flushing_Strategy *flushing_strategy =
944-
this->orb_core ()->flushing_strategy ();
971+
TAO_Flushing_Strategy *flushing_strategy = this->orb_core ()->flushing_strategy ();
945972
int const result = flushing_strategy->schedule_output (this);
946973
if (result == TAO_Flushing_Strategy::MUST_FLUSH)
947974
{
948975
typedef ACE_Reverse_Lock<ACE_Lock> TAO_REVERSE_LOCK;
949976
TAO_REVERSE_LOCK reverse (*this->handler_lock_);
950977
ACE_GUARD_RETURN (TAO_REVERSE_LOCK, ace_mon, reverse, -1);
951-
if (flushing_strategy->flush_transport (this, nullptr) == -1) {
952-
return -1;
953-
}
978+
if (flushing_strategy->flush_transport (this, nullptr) == -1)
979+
{
980+
return -1;
981+
}
954982
}
955983
}
956984

957985
return 0;
958986
}
959987

988+
int
989+
TAO_Transport::handle_idle_timeout (const ACE_Time_Value & /* current_time */, const void */*act*/)
990+
{
991+
if (TAO_debug_level > 6)
992+
{
993+
TAOLIB_DEBUG ((LM_DEBUG,
994+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::handle_idle_timeout, ")
995+
ACE_TEXT ("idle timer expired, closing transport\n"),
996+
this->id ()));
997+
}
998+
999+
// Timer has expired, so setting the idle timer id back to -1
1000+
this->idle_timer_id_ = -1;
1001+
1002+
if (this->transport_cache_manager ().purge_entry_when_purgable (this->cache_map_entry_) == -1)
1003+
{
1004+
if (TAO_debug_level > 6)
1005+
TAOLIB_DEBUG ((LM_DEBUG,
1006+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::handle_idle_timeout, ")
1007+
ACE_TEXT ("idle_timeout, transport is not purgable, don't close it, reschedule it\n"),
1008+
this->id ()));
1009+
1010+
this->schedule_idle_timer ();
1011+
}
1012+
else
1013+
{
1014+
if (TAO_debug_level > 6)
1015+
TAOLIB_DEBUG ((LM_DEBUG,
1016+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::handle_idle_timeout, ")
1017+
ACE_TEXT ("idle_timeout, transport purged due to idle timeout\n"),
1018+
this->id ()));
1019+
1020+
// Close the underlying socket.
1021+
// close_connection() is safe to call from the reactor thread.
1022+
(void) this->close_connection ();
1023+
}
1024+
1025+
return 0;
1026+
}
1027+
9601028
TAO_Transport::Drain_Result
9611029
TAO_Transport::drain_queue (TAO::Transport::Drain_Constraints const & dc)
9621030
{
@@ -2729,8 +2797,7 @@ TAO_Transport::pre_close ()
27292797
// of the is_connected_ flag, so that during cache lookups the cache
27302798
// manager doesn't need to be burdened by the lock in is_connected().
27312799
this->is_connected_ = false;
2732-
this->transport_cache_manager ().mark_connected (this->cache_map_entry_,
2733-
false);
2800+
this->transport_cache_manager ().mark_connected (this->cache_map_entry_, false);
27342801
this->purge_entry ();
27352802
{
27362803
ACE_MT (ACE_GUARD (ACE_Lock, guard, *this->handler_lock_));
@@ -2804,13 +2871,13 @@ TAO_Transport::post_open (size_t id)
28042871
ACE_TEXT (", cache_map_entry_ is [%@]\n"), this->id_, this->cache_map_entry_));
28052872
}
28062873

2807-
this->transport_cache_manager ().mark_connected (this->cache_map_entry_,
2808-
true);
2874+
this->transport_cache_manager ().mark_connected (this->cache_map_entry_, true);
28092875

28102876
// update transport cache to make this entry available
2811-
this->transport_cache_manager ().set_entry_state (
2812-
this->cache_map_entry_,
2813-
TAO::ENTRY_IDLE_AND_PURGABLE);
2877+
this->transport_cache_manager ().set_entry_state (this->cache_map_entry_, TAO::ENTRY_IDLE_AND_PURGABLE);
2878+
2879+
// this transport is just opened, so schedule it for the idle timer
2880+
this->schedule_idle_timer ();
28142881

28152882
return true;
28162883
}
@@ -2874,4 +2941,56 @@ TAO_Transport::connection_closed_on_read () const
28742941
return connection_closed_on_read_;
28752942
}
28762943

2944+
void
2945+
TAO_Transport::schedule_idle_timer ()
2946+
{
2947+
int const timeout_sec = this->orb_core_->resource_factory ()->transport_idle_timeout ();
2948+
if (timeout_sec > 0)
2949+
{
2950+
if (this->idle_timer_id_ != -1)
2951+
{
2952+
// The transport was marked as idle, but we have a timer running, cancel that old timer
2953+
// first
2954+
this->cancel_idle_timer ();
2955+
}
2956+
ACE_Reactor *reactor = this->orb_core_->reactor ();
2957+
if (reactor)
2958+
{
2959+
ACE_Time_Value const tv (static_cast<time_t> (timeout_sec));
2960+
this->idle_timer_id_= reactor->schedule_timer (std::addressof(this->transport_idle_timer_), nullptr, tv);
2961+
2962+
if (TAO_debug_level > 6)
2963+
{
2964+
TAOLIB_DEBUG ((LM_DEBUG,
2965+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::schedule_idle_timer, ")
2966+
ACE_TEXT ("schedule idle timer with id [%d] ")
2967+
ACE_TEXT ("in the reactor.\n"),
2968+
this->id (), this->idle_timer_id_));
2969+
}
2970+
}
2971+
}
2972+
}
2973+
2974+
void
2975+
TAO_Transport::cancel_idle_timer ()
2976+
{
2977+
if (this->idle_timer_id_ != -1)
2978+
{
2979+
ACE_Reactor *reactor = this->orb_core ()->reactor ();
2980+
if (reactor)
2981+
{
2982+
if (TAO_debug_level > 6)
2983+
{
2984+
TAOLIB_DEBUG ((LM_DEBUG,
2985+
ACE_TEXT ("TAO (%P|%t) - Transport[%d]::cancel_idle_timer, ")
2986+
ACE_TEXT ("cancel idle timer with id [%d] ")
2987+
ACE_TEXT ("from the reactor.\n"),
2988+
this->id (), this->idle_timer_id_));
2989+
}
2990+
reactor->cancel_timer (this->idle_timer_id_);
2991+
this->idle_timer_id_ = -1;
2992+
}
2993+
}
2994+
}
2995+
28772996
TAO_END_VERSIONED_NAMESPACE_DECL

0 commit comments

Comments
 (0)