@@ -134,7 +134,9 @@ TAO_Transport::TAO_Transport (CORBA::ULong tag,
134134 , incoming_message_queue_ (orb_core)
135135 , current_deadline_ (ACE_Time_Value::zero)
136136 , flush_timer_id_ (-1 )
137+ , idle_timer_id_ (-1 )
137138 , transport_timer_ (this )
139+ , transport_idle_timer_ (this )
138140 , handler_lock_ (orb_core->resource_factory ()->create_cached_connection_lock ())
139141 , id_ ((size_t ) this)
140142 , purging_order_ (0 )
@@ -202,6 +204,8 @@ TAO_Transport::~TAO_Transport (void)
202204 ));
203205 }
204206
207+ this ->cancel_idle_timer ();
208+
205209 delete this ->messaging_object_ ;
206210
207211 delete this ->ws_ ;
@@ -359,6 +363,16 @@ TAO_Transport::register_if_necessary (void)
359363void
360364TAO_Transport::close_connection (void )
361365{
366+ if (TAO_debug_level > 4 )
367+ {
368+ TAOLIB_DEBUG ((LM_DEBUG,
369+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::close_connection\n " ),
370+ this ->id ()));
371+ }
372+
373+ // Cancel any pending timer
374+ this ->cancel_idle_timer ();
375+
362376 this ->connection_handler_i ()->close_connection ();
363377}
364378
@@ -410,8 +424,7 @@ TAO_Transport::register_handler (void)
410424 this ->ws_ ->is_registered (true );
411425
412426 // Register the handler with the reactor
413- return r->register_handler (this ->event_handler_i (),
414- ACE_Event_Handler::READ_MASK);
427+ return r->register_handler (this ->event_handler_i (), ACE_Event_Handler::READ_MASK);
415428}
416429
417430int
@@ -582,7 +595,12 @@ TAO_Transport::make_idle (void)
582595 this ->id ()));
583596 }
584597
585- return this ->transport_cache_manager ().make_idle (this ->cache_map_entry_ );
598+ int const result = this ->transport_cache_manager ().make_idle (this ->cache_map_entry_ );
599+ if (result == 0 )
600+ {
601+ this ->schedule_idle_timer ();
602+ }
603+ return result;
586604}
587605
588606int
@@ -992,6 +1010,46 @@ TAO_Transport::handle_timeout (const ACE_Time_Value & /* current_time */,
9921010 return 0 ;
9931011}
9941012
1013+ int
1014+ TAO_Transport::handle_idle_timeout (const ACE_Time_Value & /* current_time */ , const void */*act*/)
1015+ {
1016+ if (TAO_debug_level > 6 )
1017+ {
1018+ TAOLIB_DEBUG ((LM_DEBUG,
1019+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::handle_idle_timeout, " )
1020+ ACE_TEXT (" idle timer expired, closing transport\n " ),
1021+ this ->id ()));
1022+ }
1023+
1024+ // Timer has expired, so setting the idle timer id back to -1
1025+ this ->idle_timer_id_ = -1 ;
1026+
1027+ if (this ->transport_cache_manager ().purge_entry_when_purgable (this ->cache_map_entry_ ) == -1 )
1028+ {
1029+ if (TAO_debug_level > 6 )
1030+ TAOLIB_DEBUG ((LM_DEBUG,
1031+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::handle_idle_timeout, " )
1032+ ACE_TEXT (" idle_timeout, transport is not purgable, don't close it, reschedule it\n " ),
1033+ this ->id ()));
1034+
1035+ this ->schedule_idle_timer ();
1036+ }
1037+ else
1038+ {
1039+ if (TAO_debug_level > 6 )
1040+ TAOLIB_DEBUG ((LM_DEBUG,
1041+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::handle_idle_timeout, " )
1042+ ACE_TEXT (" idle_timeout, transport purged due to idle timeout\n " ),
1043+ this ->id ()));
1044+
1045+ // Close the underlying socket.
1046+ // close_connection() is safe to call from the reactor thread.
1047+ (void ) this ->close_connection ();
1048+ }
1049+
1050+ return 0 ;
1051+ }
1052+
9951053TAO_Transport::Drain_Result
9961054TAO_Transport::drain_queue (TAO::Transport::Drain_Constraints const & dc)
9971055{
@@ -2767,8 +2825,7 @@ TAO_Transport::pre_close (void)
27672825 // of the is_connected_ flag, so that during cache lookups the cache
27682826 // manager doesn't need to be burdened by the lock in is_connected().
27692827 this ->is_connected_ = false ;
2770- this ->transport_cache_manager ().mark_connected (this ->cache_map_entry_ ,
2771- false );
2828+ this ->transport_cache_manager ().mark_connected (this ->cache_map_entry_ , false );
27722829 this ->purge_entry ();
27732830 {
27742831 ACE_MT (ACE_GUARD (ACE_Lock, guard, *this ->handler_lock_ ));
@@ -2842,13 +2899,13 @@ TAO_Transport::post_open (size_t id)
28422899 ACE_TEXT (" , cache_map_entry_ is [%@]\n " ), this ->id_ , this ->cache_map_entry_ ));
28432900 }
28442901
2845- this ->transport_cache_manager ().mark_connected (this ->cache_map_entry_ ,
2846- true );
2902+ this ->transport_cache_manager ().mark_connected (this ->cache_map_entry_ , true );
28472903
28482904 // update transport cache to make this entry available
2849- this ->transport_cache_manager ().set_entry_state (
2850- this ->cache_map_entry_ ,
2851- TAO::ENTRY_IDLE_AND_PURGABLE);
2905+ this ->transport_cache_manager ().set_entry_state (this ->cache_map_entry_ , TAO::ENTRY_IDLE_AND_PURGABLE);
2906+
2907+ // this transport is just opened, so schedule it for the idle timer
2908+ this ->schedule_idle_timer ();
28522909
28532910 return true ;
28542911}
@@ -2919,4 +2976,56 @@ TAO_Transport::connection_closed_on_read (void) const
29192976
29202977// @@ TAO_TRANSPORT_SPL_METHODS_ADD_HOOK
29212978
2979+ void
2980+ TAO_Transport::schedule_idle_timer ()
2981+ {
2982+ int const timeout_sec = this ->orb_core_ ->resource_factory ()->transport_idle_timeout ();
2983+ if (timeout_sec > 0 )
2984+ {
2985+ if (this ->idle_timer_id_ != -1 )
2986+ {
2987+ // The transport was marked as idle, but we have a timer running, cancel that old timer
2988+ // first
2989+ this ->cancel_idle_timer ();
2990+ }
2991+ ACE_Reactor *reactor = this ->orb_core_ ->reactor ();
2992+ if (reactor)
2993+ {
2994+ ACE_Time_Value const tv (static_cast <time_t > (timeout_sec));
2995+ this ->idle_timer_id_ = reactor->schedule_timer (&this ->transport_idle_timer_ , 0 , tv);
2996+
2997+ if (TAO_debug_level > 6 )
2998+ {
2999+ TAOLIB_DEBUG ((LM_DEBUG,
3000+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::schedule_idle_timer, " )
3001+ ACE_TEXT (" schedule idle timer with id [%d] " )
3002+ ACE_TEXT (" in the reactor.\n " ),
3003+ this ->id (), this ->idle_timer_id_ ));
3004+ }
3005+ }
3006+ }
3007+ }
3008+
3009+ void
3010+ TAO_Transport::cancel_idle_timer ()
3011+ {
3012+ if (this ->idle_timer_id_ != -1 )
3013+ {
3014+ ACE_Reactor *reactor = this ->orb_core ()->reactor ();
3015+ if (reactor)
3016+ {
3017+ if (TAO_debug_level > 6 )
3018+ {
3019+ TAOLIB_DEBUG ((LM_DEBUG,
3020+ ACE_TEXT (" TAO (%P|%t) - Transport[%d]::cancel_idle_timer, " )
3021+ ACE_TEXT (" cancel idle timer with id [%d] " )
3022+ ACE_TEXT (" from the reactor.\n " ),
3023+ this ->id (), this ->idle_timer_id_ ));
3024+ }
3025+ reactor->cancel_timer (this ->idle_timer_id_ );
3026+ this ->idle_timer_id_ = -1 ;
3027+ }
3028+ }
3029+ }
3030+
29223031TAO_END_VERSIONED_NAMESPACE_DECL
0 commit comments