#include <Connection_Handler.h>
Inheritance diagram for TAO_Connection_Handler:
Public Member Functions | |
TAO_Connection_Handler (void) | |
Constructor. | |
TAO_Connection_Handler (TAO_ORB_Core *orb_core) | |
Constructor. | |
virtual | ~TAO_Connection_Handler (void) |
Destructor. | |
TAO_Transport * | transport (void) |
Return the underlying transport object. | |
void | transport (TAO_Transport *transport) |
Set the underlying transport object. | |
bool | is_closed (void) const |
Is the handler closed? | |
bool | is_open (void) const |
Is the handler open? | |
bool | is_connecting (void) const |
Is the handler in the process of being connected? | |
virtual int | close_connection (void)=0 |
Close the underlying connection. | |
virtual int | handle_input (ACE_HANDLE fd)=0 |
int | svc_i (void) |
virtual int | open_handler (void *)=0 |
A open () hook. | |
virtual int | close_handler (void) |
virtual int | set_dscp_codepoint (CORBA::Boolean set_network_priority) |
virtual int | release_os_resources (void) |
Release the OS resources related to this handler. | |
Protected Member Functions | |
TAO_ORB_Core * | orb_core (void) |
Return our TAO_ORB_Core pointer. | |
int | set_socket_option (ACE_SOCK &sock, int snd_size, int rcv_size) |
Set options on the socket. | |
Helper methods for Event_Handler-based derived classes. | |
Many (actually all so far) implementations of TAO_Connection_Handler are a mixin of TAO_Connection_Handler and some form of ACE_Event_Handler. The following methods simplify such implementations by capturing the common code in a single place. | |
int | handle_output_eh (ACE_HANDLE h, ACE_Event_Handler *eh) |
Implement the handle_output() callback. | |
int | handle_input_eh (ACE_HANDLE h, ACE_Event_Handler *eh) |
Implement the handle_input() callback. | |
int | handle_input_internal (ACE_HANDLE h, ACE_Event_Handler *eh) |
Implement the handle_output() callback. | |
int | close_connection_eh (ACE_Event_Handler *eh) |
virtual void | pre_io_hook (int &return_value) |
virtual void | pos_io_hook (int &return_value) |
Private Attributes | |
TAO_ORB_Core *const | orb_core_ |
Pointer to the TAO_ORB_Core. | |
TAO_Transport * | transport_ |
Transport object reference. | |
ACE_Lock * | lock_ |
This class is an abstraction for the connection handlers. The connections handler in every protocol can derive from this class as well as the ACE_Svc_Handler specialised for the right protocol. This way, most of the common code for the different protocols would be in this implementation.
Definition at line 54 of file Connection_Handler.h.
|
Constructor.
|
|
Constructor.
Definition at line 26 of file Connection_Handler.cpp. References TAO_Resource_Factory::create_cached_connection_lock(), TAO_ORB_Core::resource_factory(), and TAO_LF_Event::state_changed().
00027 : orb_core_ (orb_core) 00028 , transport_ (0) 00029 { 00030 // @@todo: We need to have a distinct option/ method in the resource 00031 // factory for this and TAO_Transport. 00032 this->lock_ = 00033 this->orb_core_->resource_factory ()->create_cached_connection_lock (); 00034 00035 // Put ourselves in the connection wait state as soon as we get 00036 // created 00037 this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT, 00038 this->orb_core_->leader_follower ()); 00039 } |
|
Destructor.
Definition at line 41 of file Connection_Handler.cpp. References ACE_ERROR, LM_ERROR, release_os_resources(), and TAO_debug_level.
00042 { 00043 int const result = 00044 this->release_os_resources (); 00045 00046 if (result == -1 && TAO_debug_level) 00047 { 00048 ACE_ERROR ((LM_ERROR, 00049 "TAO (%P|%t) - Connection_Handler::~Connection_Handler," 00050 "release_os_resources() failed %m\n")); 00051 } 00052 00053 // @@ TODO Use auto_ptr<> 00054 delete this->lock_; 00055 00056 //@@ CONNECTION_HANDLER_DESTRUCTOR_ADD_HOOK 00057 } |
|
Close the underlying connection. Used by the ORB to actively close connections that are idle, stale or somehow are determined to be broken before the Reactor does.
Implemented in TAO_IIOP_Connection_Handler. Referenced by TAO_Transport::close_connection(), handle_input_eh(), and TAO_Thread_Per_Connection_Handler::~TAO_Thread_Per_Connection_Handler(). |
|
Implement close_connection() for Connection_Handlers that are also Event_Handlers. Definition at line 296 of file Connection_Handler.cpp. References ACE_ASSERT, ACE_DEBUG, ACE_Reactor::cancel_timer(), ACE_Event_Handler::get_handle(), TAO_ORB_Core::has_shutdown(), TAO_Transport::id(), TAO_Wait_Strategy::is_registered(), LM_DEBUG, TAO_Transport::orb_core(), TAO_Transport::purge_entry(), TAO_ORB_Core::reactor(), ACE_Event_Handler::reactor(), ACE_Reactor::remove_handler(), TAO_Transport::send_connection_closed_notifications(), TAO_LF_Event::state_changed(), TAO_debug_level, transport(), and TAO_Transport::wait_strategy(). Referenced by TAO_IIOP_Connection_Handler::close_connection().
00297 { 00298 // Save the ID for debugging messages 00299 ACE_HANDLE handle = eh->get_handle (); 00300 00301 size_t const id = this->transport ()->id (); 00302 if (TAO_debug_level) 00303 { 00304 ACE_DEBUG ((LM_DEBUG, 00305 "TAO (%P|%t) - Connection_Handler[%d]::" 00306 "close_connection_eh, purging entry from cache\n", 00307 handle)); 00308 } 00309 00310 this->transport ()->purge_entry (); 00311 00312 // @@ This seems silly, but if we have no reason to be in the 00313 // reactor, then we dont remove ourselves. 00314 if (this->transport ()->wait_strategy ()->is_registered ()) 00315 { 00316 ACE_Reactor *eh_reactor = eh->reactor (); 00317 00318 if (this->orb_core_->has_shutdown () == 0) 00319 { 00320 // If the ORB is nill, get the reactor from orb_core which gets it 00321 // from LF. 00322 if (eh_reactor == 0) 00323 eh_reactor = this->transport()->orb_core()->reactor (); 00324 } 00325 00326 // The Reactor must not be null, otherwise something else is 00327 // horribly broken. 00328 ACE_ASSERT (eh_reactor != 0); 00329 00330 if (TAO_debug_level) 00331 { 00332 ACE_DEBUG ((LM_DEBUG, 00333 "TAO (%P|%t) - Connection_Handler[%d]::" 00334 "close_connection_eh, removing from the reactor\n", 00335 handle)); 00336 } 00337 00338 // Use id instead of handle. Why? "handle" may be invalid for RW 00339 // cases when drop_reply_on_shutdown is on, and when the 00340 // orb_core is shutting down. This means that the handler will 00341 // be left behind in the reactor which would create problems 00342 // later. Just forcefully remove them. If none exists reactor 00343 // will make things safer. 00344 ACE_HANDLE tmp_handle = handle; 00345 if (this->orb_core_->has_shutdown ()) 00346 tmp_handle = (ACE_HANDLE) id; 00347 00348 eh_reactor->remove_handler (tmp_handle, 00349 ACE_Event_Handler::ALL_EVENTS_MASK | 00350 ACE_Event_Handler::DONT_CALL); 00351 00352 // Also cancel any timers, we may create those for time-limited 00353 // buffering 00354 if (TAO_debug_level) 00355 { 00356 ACE_DEBUG ((LM_DEBUG, 00357 "TAO (%P|%t) - Connection_Handler[%d]::" 00358 "close_connection_eh, cancel all timers\n", 00359 handle)); 00360 } 00361 00362 eh_reactor->cancel_timer (eh); 00363 00364 // @@ This seems silly, the reactor is a much better authority to 00365 // find out if a handle is registered... 00366 this->transport ()->wait_strategy ()->is_registered (false); 00367 } 00368 00369 // This call should be made only after the cache and reactor are 00370 // cleaned up. This call can make upcalls to the application which 00371 // in turn can make remote calls (Bug 1551 and Bug 1482). The remote 00372 // calls from the application can try to use this handler from the 00373 // cache or from the reactor. So clean them up before this is 00374 // called. 00375 this->transport ()->send_connection_closed_notifications (); 00376 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED, 00377 this->orb_core_->leader_follower ()); 00378 00379 if (TAO_debug_level) 00380 { 00381 ACE_DEBUG ((LM_DEBUG, 00382 "TAO (%P|%t) - Connection_Handler[%d]::" 00383 "close_connection_eh\n", 00384 id)); 00385 } 00386 00387 return 1; 00388 } |
|
A close() hook, called by the Transport Connector when they want to close this handler Definition at line 424 of file Connection_Handler.cpp. References TAO_Transport::remove_reference(), TAO_LF_Event::state_changed(), and transport(). Referenced by TAO_Connector::check_connection_closure(), and TAO_IIOP_Connection_Handler::close().
00425 { 00426 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED, 00427 this->orb_core_->leader_follower ()); 00428 this->transport ()->remove_reference (); 00429 return 0; 00430 } |
|
The event handler calls, here so that other objects who hold a reference to this object can call the event handler methods. Implemented in TAO_IIOP_Connection_Handler. |
|
Implement the handle_input() callback.
Definition at line 216 of file Connection_Handler.cpp. References ACE_DEBUG, TAO_Wait_Strategy::can_process_upcalls(), close_connection(), handle_input_internal(), LM_DEBUG, TAO_debug_level, transport(), and TAO_Transport::wait_strategy(). Referenced by TAO_IIOP_Connection_Handler::handle_input().
00218 { 00219 // If we can't process upcalls just return 00220 if (!this->transport ()->wait_strategy ()->can_process_upcalls ()) 00221 { 00222 if (TAO_debug_level > 6) 00223 ACE_DEBUG ((LM_DEBUG, 00224 "TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, " 00225 "not going to handle_input on transport " 00226 "because upcalls temporarily suspended on this thread\n", 00227 this->transport()->id())); 00228 return 0; 00229 } 00230 00231 int const result = this->handle_input_internal (h, eh); 00232 00233 if (result == -1) 00234 { 00235 this->close_connection (); 00236 return 0; 00237 } 00238 00239 return result; 00240 } |
|
Implement the handle_output() callback.
Definition at line 243 of file Connection_Handler.cpp. References ACE_DEBUG, ACE_Event_Handler::get_handle(), TAO_Transport::handle_input(), TAO_Resume_Handle::handle_input_return_value_hook(), TAO_Transport::id(), LM_DEBUG, pos_io_hook(), pre_io_hook(), TAO_Resume_Handle::set_flag(), TAO_debug_level, transport(), and TAO_Transport::update_transport(). Referenced by handle_input_eh().
00245 { 00246 // Let the transport know that it is used 00247 (void) this->transport ()->update_transport (); 00248 00249 // Grab the transport id now and use the cached value for printing 00250 // since the transport could dissappear by the time the thread 00251 // returns. 00252 size_t const t_id = 00253 this->transport ()->id (); 00254 00255 if (TAO_debug_level > 6) 00256 { 00257 ACE_HANDLE handle = eh->get_handle(); 00258 ACE_DEBUG ((LM_DEBUG, 00259 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, " 00260 "handle = %d/%d\n", 00261 t_id, handle, h)); 00262 } 00263 00264 TAO_Resume_Handle resume_handle (this->orb_core (), 00265 eh->get_handle ()); 00266 00267 int return_value = 0; 00268 00269 this->pre_io_hook (return_value); 00270 if (return_value != 0) 00271 return return_value; 00272 00273 return_value = this->transport ()->handle_input (resume_handle); 00274 00275 this->pos_io_hook (return_value); 00276 00277 // Bug 1647; might need to change resume_handle's flag or 00278 // change handle_input return value. 00279 resume_handle.handle_input_return_value_hook(return_value); 00280 00281 if (TAO_debug_level > 6) 00282 { 00283 ACE_HANDLE handle = eh->get_handle (); 00284 ACE_DEBUG ((LM_DEBUG, 00285 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, " 00286 "handle = %d/%d, retval = %d\n", 00287 t_id, handle, h, return_value)); 00288 } 00289 00290 if (return_value == -1) 00291 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED); 00292 return return_value; 00293 } |
|
Implement the handle_output() callback.
Definition at line 184 of file Connection_Handler.cpp. References ACE_Event_Handler::get_handle(), TAO_Transport::handle_output(), pos_io_hook(), pre_io_hook(), TAO_Resume_Handle::set_flag(), transport(), and TAO_Transport::update_transport(). Referenced by TAO_IIOP_Connection_Handler::handle_output().
00186 { 00187 // Let the transport that it is going to be used 00188 (void) this->transport ()->update_transport (); 00189 00190 // Instantiate the resume handle here.. This will automatically 00191 // resume the handle once data is written.. 00192 TAO_Resume_Handle resume_handle (this->orb_core (), 00193 eh->get_handle ()); 00194 00195 int return_value = 0; 00196 this->pre_io_hook (return_value); 00197 if (return_value != 0) 00198 { 00199 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED); 00200 return return_value; 00201 } 00202 00203 return_value = this->transport ()->handle_output (); 00204 00205 this->pos_io_hook (return_value); 00206 00207 if (return_value != 0) 00208 { 00209 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED); 00210 } 00211 00212 return return_value; 00213 } |
|
Is the handler closed?
Definition at line 20 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure(), and TAO_Connector::wait_for_connection_completion().
00021 { 00022 return (this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED || 00023 this->state_ == TAO_LF_Event::LFS_TIMEOUT); 00024 } |
|
Is the handler in the process of being connected?
Definition at line 33 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure().
00034 { 00035 return this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT; 00036 } |
|
Is the handler open?
Definition at line 27 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure().
00028 { 00029 return this->state_ == TAO_LF_Event::LFS_SUCCESS; 00030 } |
|
A open () hook. See Thread_Per_Connection_Handler for a use case Implemented in TAO_IIOP_Connection_Handler. Referenced by TAO_Thread_Per_Connection_Handler::open(). |
|
Return our TAO_ORB_Core pointer.
Definition at line 8 of file Connection_Handler.inl. Referenced by TAO_IIOP_Connection_Handler::add_transport_to_cache(), TAO_IIOP_Connection_Handler::close_connection(), TAO_IIOP_Connection_Handler::open(), and TAO_IIOP_Connection_Handler::set_dscp_codepoint().
00009 { 00010 return this->orb_core_; 00011 } |
|
See the SSLIOP protocol for an interesting use-case Definition at line 419 of file Connection_Handler.cpp. Referenced by handle_input_internal(), and handle_output_eh().
00420 { 00421 } |
|
See the SSLIOP protocol for an interesting use-case Definition at line 414 of file Connection_Handler.cpp. Referenced by handle_input_internal(), and handle_output_eh().
00415 { 00416 } |
|
Release the OS resources related to this handler.
Reimplemented in TAO_IIOP_Connection_Handler. Definition at line 406 of file Connection_Handler.cpp. Referenced by ~TAO_Connection_Handler().
00407 {
00408 return 0;
00409 }
|
|
Set the Diff-Serv codepoint on outgoing packets. Only has effect for remote protocols (e.g., IIOP); no effect for local protocols (UIOP). Default implementation is for local protocols. Remote protocols must overwrite implementation. Reimplemented in TAO_IIOP_Connection_Handler. Definition at line 400 of file Connection_Handler.cpp. Referenced by TAO::Remote_Invocation::send_message().
00401 {
00402 return 0;
00403 }
|
|
Set options on the socket.
Definition at line 61 of file Connection_Handler.cpp. References ACE_CLOEXEC, ACE_IPC_SAP::enable(), ENOTSUP, and ACE_SOCK::set_option(). Referenced by TAO_IIOP_Connection_Handler::open().
00064 { 00065 #if !defined (ACE_LACKS_SOCKET_BUFSIZ) 00066 00067 if (snd_size != 0 00068 && sock.set_option (SOL_SOCKET, 00069 SO_SNDBUF, 00070 (void *) &snd_size, 00071 sizeof (snd_size)) == -1 00072 && errno != ENOTSUP) 00073 { 00074 return -1; 00075 } 00076 00077 if (rcv_size != 0 00078 && sock.set_option (SOL_SOCKET, 00079 SO_RCVBUF, 00080 (void *) &rcv_size, 00081 sizeof (int)) == -1 00082 && errno != ENOTSUP) 00083 { 00084 return -1; 00085 } 00086 #else 00087 ACE_UNUSED_ARG (snd_size); 00088 ACE_UNUSED_ARG (rcv_size); 00089 #endif /* !ACE_LACKS_SOCKET_BUFSIZ */ 00090 00091 (void) sock.enable (ACE_CLOEXEC); 00092 // Set the close-on-exec flag for that file descriptor. If the 00093 // operation fails we are out of luck (some platforms do not support 00094 // it and return -1). 00095 00096 return 0; 00097 } |
|
This method is invoked from the svc () method of the Svc_Handler Object. Definition at line 100 of file Connection_Handler.cpp. References ACE_DEBUG, ACE_TEXT, ETIME, TAO_Transport::handle_input(), TAO_ORB_Core::has_shutdown(), LM_DEBUG, ACE_Time_Value::msec(), TAO_debug_level, TAO_ORB_Core::thread_per_connection_timeout(), transport(), and TAO_Transport::update_transport(). Referenced by TAO_Thread_Per_Connection_Handler::svc().
00101 { 00102 int result = 0; 00103 00104 if (TAO_debug_level > 0) 00105 ACE_DEBUG ((LM_DEBUG, 00106 ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n"))); 00107 00108 // Here we simply synthesize the "typical" event loop one might find 00109 // in a reactive handler, except that this can simply block waiting 00110 // for input. 00111 00112 ACE_Time_Value *max_wait_time = 0; 00113 ACE_Time_Value timeout; 00114 ACE_Time_Value current_timeout; 00115 00116 if (this->orb_core_->thread_per_connection_timeout (timeout)) 00117 { 00118 current_timeout = timeout; 00119 max_wait_time = ¤t_timeout; 00120 } 00121 00122 TAO_Resume_Handle rh (this->orb_core_, 00123 ACE_INVALID_HANDLE); 00124 00125 // We exit of the loop if 00126 // - If the ORB core is shutdown by another thread 00127 // - Or if the transport is null. This could happen if an error 00128 // occured. 00129 // - Or if during processing a return value of -1 is received. 00130 while (!this->orb_core_->has_shutdown () 00131 && result >= 0) 00132 { 00133 // Let the transport know that it is used 00134 (void) this->transport ()->update_transport (); 00135 00136 result = 00137 this->transport ()->handle_input (rh, 00138 max_wait_time); 00139 00140 if (result == -1 && errno == ETIME) 00141 { 00142 // Ignore timeouts, they are only used to wake up and 00143 // shutdown. 00144 result = 0; 00145 00146 // Reset errno to make sure we don't trip over an old value 00147 // of errno in case it is not reset when the recv() call 00148 // fails if the socket has been closed. 00149 errno = 0; 00150 } 00151 else if (result == -1) 00152 { 00153 // Something went wrong with the socket. Just quit 00154 return result; 00155 } 00156 00157 current_timeout = timeout; 00158 00159 if (TAO_debug_level > 0) 00160 ACE_DEBUG ((LM_DEBUG, 00161 "TAO (%P|%t) - Connection_Handler::svc_i - " 00162 "loop <%d>\n", current_timeout.msec ())); 00163 } 00164 00165 if (TAO_debug_level > 0) 00166 ACE_DEBUG ((LM_DEBUG, 00167 "TAO (%P|%t) - Connection_Handler::svc_i end\n")); 00168 00169 return result; 00170 } |
|
Set the underlying transport object.
Definition at line 173 of file Connection_Handler.cpp. References TAO_Transport::event_handler_i(), and ACE_Event_Handler::reference_counting_policy().
00174 { 00175 this->transport_ = transport; 00176 00177 // Enable reference counting on the event handler. 00178 this->transport_->event_handler_i ()->reference_counting_policy ().value ( 00179 ACE_Event_Handler::Reference_Counting_Policy::ENABLED 00180 ); 00181 } |
|
|
Internal state lock, needs to be separate from the reference count / pending upcalls lock because they interleave. Definition at line 188 of file Connection_Handler.h. |
|
Pointer to the TAO_ORB_Core.
Definition at line 181 of file Connection_Handler.h. |
|
Transport object reference.
Definition at line 184 of file Connection_Handler.h. |