#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 or timed out? | |
| bool | is_open (void) const |
| Is the handler open? | |
| bool | is_timeout (void) const |
| Closed due to timeout? | |
| 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) |
| void | connection_pending (void) |
| void | cancel_pending_connection (void) |
| virtual int | set_dscp_codepoint (CORBA::Boolean set_network_priority) |
| virtual int | set_dscp_codepoint (CORBA::Long dscp_codepoint) |
| 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 | shared_open (void) |
| 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_ |
| bool | connection_pending_ |
| Stores the connection pending state. | |
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 56 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 connection_pending_ (false) 00030 { 00031 // @todo: We need to have a distinct option/ method in the resource 00032 // factory for this and TAO_Transport. 00033 this->lock_ = 00034 this->orb_core_->resource_factory ()->create_cached_connection_lock (); 00035 00036 // Put ourselves in the connection wait state as soon as we get 00037 // created 00038 this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT, 00039 this->orb_core_->leader_follower ()); 00040 } |
|
|
Destructor.
Definition at line 42 of file Connection_Handler.cpp.
00043 {
00044 // @@ TODO Use auto_ptr<>
00045 delete this->lock_;
00046
00047 //@@ CONNECTION_HANDLER_DESTRUCTOR_ADD_HOOK
00048 }
|
|
|
A pending connection may be canceled due to an error detected while the initiating thread is still in the Connector. Definition at line 58 of file Connection_Handler.inl. References connection_pending_, TAO_Transport::remove_reference(), and transport(). Referenced by TAO_IIOP_Connector::complete_connection(), and shared_open().
00059 {
00060 if (this->connection_pending_)
00061 {
00062 this->connection_pending_ = false;
00063 this->transport()->remove_reference();
00064 }
00065 }
|
|
|
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 298 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::pre_close(), 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().
00299 {
00300 // Save the ID for debugging messages
00301 ACE_HANDLE handle = eh->get_handle ();
00302
00303 size_t const id = this->transport ()->id ();
00304 if (TAO_debug_level)
00305 {
00306 ACE_DEBUG ((LM_DEBUG,
00307 "TAO (%P|%t) - Connection_Handler[%d]::"
00308 "close_connection_eh, purging entry from cache\n",
00309 handle));
00310 }
00311
00312 this->transport ()->pre_close ();
00313
00314 // @@ This seems silly, but if we have no reason to be in the
00315 // reactor, then we dont remove ourselves.
00316 if (this->transport ()->wait_strategy ()->is_registered ())
00317 {
00318 ACE_Reactor *eh_reactor = eh->reactor ();
00319
00320 if (this->orb_core_->has_shutdown () == 0)
00321 {
00322 // If the ORB is nil, get the reactor from orb_core which gets it
00323 // from LF.
00324 if (eh_reactor == 0)
00325 eh_reactor = this->transport()->orb_core()->reactor ();
00326 }
00327
00328 // The Reactor must not be null, otherwise something else is
00329 // horribly broken.
00330 ACE_ASSERT (eh_reactor != 0);
00331
00332 if (TAO_debug_level)
00333 {
00334 ACE_DEBUG ((LM_DEBUG,
00335 "TAO (%P|%t) - Connection_Handler[%d]::"
00336 "close_connection_eh, removing from the reactor\n",
00337 handle));
00338 }
00339
00340 // Use id instead of handle. Why? "handle" may be invalid for RW
00341 // cases when drop_reply_on_shutdown is on, and when the
00342 // orb_core is shutting down. This means that the handler will
00343 // be left behind in the reactor which would create problems
00344 // later. Just forcefully remove them. If none exists reactor
00345 // will make things safer.
00346 ACE_HANDLE tmp_handle = handle;
00347 if (this->orb_core_->has_shutdown ())
00348 tmp_handle = (ACE_HANDLE) id;
00349
00350 eh_reactor->remove_handler (tmp_handle,
00351 ACE_Event_Handler::ALL_EVENTS_MASK |
00352 ACE_Event_Handler::DONT_CALL);
00353
00354 // Also cancel any timers, we may create those for time-limited
00355 // buffering
00356 if (TAO_debug_level)
00357 {
00358 ACE_DEBUG ((LM_DEBUG,
00359 "TAO (%P|%t) - Connection_Handler[%d]::"
00360 "close_connection_eh, cancel all timers\n",
00361 handle));
00362 }
00363
00364 eh_reactor->cancel_timer (eh);
00365
00366 // @@ This seems silly, the reactor is a much better authority to
00367 // find out if a handle is registered...
00368 this->transport ()->wait_strategy ()->is_registered (false);
00369 }
00370
00371 // This call should be made only after the cache and reactor are
00372 // cleaned up. This call can make upcalls to the application which
00373 // in turn can make remote calls (Bug 1551 and Bug 1482). The remote
00374 // calls from the application can try to use this handler from the
00375 // cache or from the reactor. So clean them up before this is
00376 // called.
00377 this->transport ()->send_connection_closed_notifications ();
00378 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
00379 this->orb_core_->leader_follower ());
00380
00381 if (TAO_debug_level)
00382 {
00383 ACE_DEBUG ((LM_DEBUG,
00384 "TAO (%P|%t) - Connection_Handler[%d]::"
00385 "close_connection_eh\n",
00386 id));
00387 }
00388
00389 return 1;
00390 }
|
|
|
A close() hook, called by the Transport Connector when they want to close this handler Definition at line 432 of file Connection_Handler.cpp. References TAO_Transport::purge_entry(), TAO_Transport::remove_reference(), TAO_LF_Event::state_changed(), and transport(). Referenced by TAO_Connector::check_connection_closure(), and TAO_IIOP_Connection_Handler::close().
00433 {
00434 this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
00435 this->orb_core_->leader_follower ());
00436 this->transport ()->purge_entry();
00437 this->transport ()->remove_reference ();
00438
00439 // @@ I think that if the connection_pending state is true
00440 // when close_handler is calld, we should probably release
00441 // another reference so that the connector doesn't have to
00442 // worry about it.
00443
00444 return 0;
00445 }
|
|
|
When waiting for an asynchronous connection to complete an additional reference must be maintained, related to bugzilla #2417. However once the connection is successfully established, this reference must be removed. Using connection_pending allows the connection handler to know that it is opening as a result of a delayed asynch connection rather than an immediate synch connection, which has no additional reference needs. Definition at line 48 of file Connection_Handler.inl. References TAO_Transport::add_reference(), connection_pending_, and transport(). Referenced by TAO_IIOP_Connector::complete_connection().
00049 {
00050 if (!this->connection_pending_)
00051 {
00052 this->connection_pending_ = true;
00053 this->transport()->add_reference();
00054 }
00055 }
|
|
|
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 219 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().
00221 {
00222 // If we can't process upcalls just return
00223 if (!this->transport ()->wait_strategy ()->can_process_upcalls ())
00224 {
00225 if (TAO_debug_level > 6)
00226 ACE_DEBUG ((LM_DEBUG,
00227 "TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, "
00228 "not going to handle_input on transport "
00229 "because upcalls temporarily suspended on this thread\n",
00230 this->transport()->id()));
00231 return 0;
00232 }
00233
00234 int const result = this->handle_input_internal (h, eh);
00235
00236 if (result == -1)
00237 {
00238 this->close_connection ();
00239 return 0;
00240 }
00241
00242 return result;
00243 }
|
|
||||||||||||
|
Implement the handle_output() callback.
Definition at line 246 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().
00248 {
00249 // Let the transport know that it is used
00250 (void) this->transport ()->update_transport ();
00251
00252 // Grab the transport id now and use the cached value for printing
00253 // since the transport could dissappear by the time the thread
00254 // returns.
00255 size_t const t_id =
00256 this->transport ()->id ();
00257
00258 if (TAO_debug_level > 6)
00259 {
00260 ACE_HANDLE handle = eh->get_handle();
00261 ACE_DEBUG ((LM_DEBUG,
00262 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
00263 "handle = %d/%d\n",
00264 t_id, handle, h));
00265 }
00266
00267 TAO_Resume_Handle resume_handle (this->orb_core (), eh->get_handle ());
00268
00269 int return_value = 0;
00270
00271 this->pre_io_hook (return_value);
00272 if (return_value != 0)
00273 return return_value;
00274
00275 return_value = this->transport ()->handle_input (resume_handle);
00276
00277 this->pos_io_hook (return_value);
00278
00279 // Bug 1647; might need to change resume_handle's flag or
00280 // change handle_input return value.
00281 resume_handle.handle_input_return_value_hook(return_value);
00282
00283 if (TAO_debug_level > 6)
00284 {
00285 ACE_HANDLE handle = eh->get_handle ();
00286 ACE_DEBUG ((LM_DEBUG,
00287 "TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
00288 "handle = %d/%d, retval = %d\n",
00289 t_id, handle, h, return_value));
00290 }
00291
00292 if (return_value == -1)
00293 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00294 return return_value;
00295 }
|
|
||||||||||||
|
Implement the handle_output() callback.
Definition at line 187 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().
00189 {
00190 // Let the transport that it is going to be used
00191 (void) this->transport ()->update_transport ();
00192
00193 // Instantiate the resume handle here.. This will automatically
00194 // resume the handle once data is written..
00195 TAO_Resume_Handle resume_handle (this->orb_core (),
00196 eh->get_handle ());
00197
00198 int return_value = 0;
00199 this->pre_io_hook (return_value);
00200 if (return_value != 0)
00201 {
00202 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00203 return return_value;
00204 }
00205
00206 return_value = this->transport ()->handle_output ();
00207
00208 this->pos_io_hook (return_value);
00209
00210 if (return_value != 0)
00211 {
00212 resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
00213 }
00214
00215 return return_value;
00216 }
|
|
|
Is the handler closed or timed out?
Definition at line 22 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure(), and TAO_Connector::wait_for_connection_completion().
00023 {
00024 return (this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED ||
00025 this->state_ == TAO_LF_Event::LFS_TIMEOUT);
00026 }
|
|
|
Is the handler in the process of being connected?
Definition at line 41 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure().
00042 {
00043 return this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT;
00044 }
|
|
|
Is the handler open?
Definition at line 35 of file Connection_Handler.inl. Referenced by TAO_Connector::check_connection_closure(), and TAO_Connector::wait_for_connection_completion().
00036 {
00037 return this->state_ == TAO_LF_Event::LFS_SUCCESS;
00038 }
|
|
|
Closed due to timeout?
Definition at line 29 of file Connection_Handler.inl. Referenced by TAO_Connector::wait_for_connection_completion().
00030 {
00031 return (this->state_ == TAO_LF_Event::LFS_TIMEOUT);
00032 }
|
|
|
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 10 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().
00011 {
00012 return this->orb_core_;
00013 }
|
|
|
See the SSLIOP protocol for an interesting use-case Definition at line 427 of file Connection_Handler.cpp. Referenced by handle_input_internal(), and handle_output_eh().
00428 {
00429 }
|
|
|
See the SSLIOP protocol for an interesting use-case Definition at line 422 of file Connection_Handler.cpp. Referenced by handle_input_internal(), and handle_output_eh().
00423 {
00424 }
|
|
|
Release the OS resources related to this handler.
Reimplemented in TAO_IIOP_Connection_Handler. Definition at line 414 of file Connection_Handler.cpp.
00415 {
00416 return 0;
00417 }
|
|
|
Reimplemented in TAO_IIOP_Connection_Handler. Definition at line 408 of file Connection_Handler.cpp.
00409 {
00410 return 0;
00411 }
|
|
|
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 402 of file Connection_Handler.cpp. Referenced by TAO::Remote_Invocation::send_message().
00403 {
00404 return 0;
00405 }
|
|
||||||||||||||||
|
Set options on the socket.
Definition at line 64 of file Connection_Handler.cpp. References ACE_CLOEXEC, ACE_IPC_SAP::enable(), ENOTSUP, ACE_SOCK::set_option(), SO_RCVBUF, SO_SNDBUF, and SOL_SOCKET. Referenced by TAO_IIOP_Connection_Handler::open().
00067 {
00068 #if !defined (ACE_LACKS_SOCKET_BUFSIZ)
00069
00070 if (snd_size != 0
00071 && sock.set_option (SOL_SOCKET,
00072 SO_SNDBUF,
00073 (void *) &snd_size,
00074 sizeof (snd_size)) == -1
00075 && errno != ENOTSUP)
00076 {
00077 return -1;
00078 }
00079
00080 if (rcv_size != 0
00081 && sock.set_option (SOL_SOCKET,
00082 SO_RCVBUF,
00083 (void *) &rcv_size,
00084 sizeof (int)) == -1
00085 && errno != ENOTSUP)
00086 {
00087 return -1;
00088 }
00089 #else
00090 ACE_UNUSED_ARG (snd_size);
00091 ACE_UNUSED_ARG (rcv_size);
00092 #endif /* !ACE_LACKS_SOCKET_BUFSIZ */
00093
00094 // Set the close-on-exec flag for that file descriptor. If the
00095 // operation fails we are out of luck (some platforms do not support
00096 // it and return -1).
00097 (void) sock.enable (ACE_CLOEXEC);
00098
00099 return 0;
00100 }
|
|
|
A common function called at the start of any protocol-specific open. Returns -1 on a failure (although no failure mode is currently defined). Definition at line 51 of file Connection_Handler.cpp. References cancel_pending_connection(). Referenced by TAO_IIOP_Connection_Handler::open().
00052 {
00053 // This reference counting is related to asynch connections. It
00054 // should probably be managed by the ACE_Strategy_Connector, since
00055 // that's really the reference being managed here. also, whether
00056 // open ultimately succeeds or fails, the connection attempted is
00057 // ending, so the reference must be removed in any case.
00058 this->cancel_pending_connection();
00059
00060 return 0;
00061 }
|
|
|
This method is invoked from the svc () method of the Svc_Handler Object. Definition at line 103 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().
00104 {
00105 int result = 0;
00106
00107 if (TAO_debug_level > 0)
00108 ACE_DEBUG ((LM_DEBUG,
00109 ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n")));
00110
00111 // Here we simply synthesize the "typical" event loop one might find
00112 // in a reactive handler, except that this can simply block waiting
00113 // for input.
00114
00115 ACE_Time_Value *max_wait_time = 0;
00116 ACE_Time_Value timeout;
00117 ACE_Time_Value current_timeout;
00118
00119 if (this->orb_core_->thread_per_connection_timeout (timeout))
00120 {
00121 current_timeout = timeout;
00122 max_wait_time = ¤t_timeout;
00123 }
00124
00125 TAO_Resume_Handle rh (this->orb_core_,
00126 ACE_INVALID_HANDLE);
00127
00128 // We exit of the loop if
00129 // - If the ORB core is shutdown by another thread
00130 // - Or if the transport is null. This could happen if an error
00131 // occured.
00132 // - Or if during processing a return value of -1 is received.
00133 while (!this->orb_core_->has_shutdown ()
00134 && result >= 0)
00135 {
00136 // Let the transport know that it is used
00137 (void) this->transport ()->update_transport ();
00138
00139 result =
00140 this->transport ()->handle_input (rh,
00141 max_wait_time);
00142
00143 if (result == -1 && errno == ETIME)
00144 {
00145 // Ignore timeouts, they are only used to wake up and
00146 // shutdown.
00147 result = 0;
00148
00149 // Reset errno to make sure we don't trip over an old value
00150 // of errno in case it is not reset when the recv() call
00151 // fails if the socket has been closed.
00152 errno = 0;
00153 }
00154 else if (result == -1)
00155 {
00156 // Something went wrong with the socket. Just quit
00157 return result;
00158 }
00159
00160 current_timeout = timeout;
00161
00162 if (TAO_debug_level > 0)
00163 ACE_DEBUG ((LM_DEBUG,
00164 "TAO (%P|%t) - Connection_Handler::svc_i - "
00165 "loop <%d>\n", current_timeout.msec ()));
00166 }
00167
00168 if (TAO_debug_level > 0)
00169 ACE_DEBUG ((LM_DEBUG,
00170 "TAO (%P|%t) - Connection_Handler::svc_i end\n"));
00171
00172 return result;
00173 }
|
|
|
Set the underlying transport object.
Definition at line 176 of file Connection_Handler.cpp. References TAO_Transport::event_handler_i(), and ACE_Event_Handler::reference_counting_policy().
00177 {
00178 this->transport_ = transport;
00179
00180 // Enable reference counting on the event handler.
00181 this->transport_->event_handler_i ()->reference_counting_policy ().value (
00182 ACE_Event_Handler::Reference_Counting_Policy::ENABLED
00183 );
00184 }
|
|
|
|
Stores the connection pending state.
Definition at line 212 of file Connection_Handler.h. Referenced by cancel_pending_connection(), and connection_pending(). |
|
|
Internal state lock, needs to be separate from the reference count / pending upcalls lock because they interleave. Definition at line 209 of file Connection_Handler.h. |
|
|
Pointer to the TAO_ORB_Core.
Definition at line 202 of file Connection_Handler.h. |
|
|
Transport object reference.
Definition at line 205 of file Connection_Handler.h. |
1.3.6