TAO_Connection_Handler. More...
#include <Connection_Handler.h>


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 (u_long flags=0) |
| 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. | |
| virtual int | handle_write_ready (const ACE_Time_Value *timeout) |
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 Member Functions | |
| void | operator= (const TAO_Connection_Handler &) |
| TAO_Connection_Handler (const TAO_Connection_Handler &) | |
Private Attributes | |
| TAO_ORB_Core *const | orb_core_ |
| Pointer to the TAO_ORB_Core. | |
| TAO_Transport * | transport_ |
| Transport object reference. | |
| bool | connection_pending_ |
| Stores the connection pending state. | |
| bool | is_closed_ |
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.
| TAO_Connection_Handler::TAO_Connection_Handler | ( | void | ) |
Constructor.
| TAO_Connection_Handler::TAO_Connection_Handler | ( | TAO_ORB_Core * | orb_core | ) |
Constructor.
Definition at line 27 of file Connection_Handler.cpp.
: orb_core_ (orb_core), transport_ (0), connection_pending_ (false), is_closed_ (false) { // Put ourselves in the connection wait state as soon as we get // created this->state_changed (TAO_LF_Event::LFS_CONNECTION_WAIT, this->orb_core_->leader_follower ()); }
| TAO_Connection_Handler::~TAO_Connection_Handler | ( | void | ) | [virtual] |
Destructor.
Definition at line 39 of file Connection_Handler.cpp.
{
//@@ CONNECTION_HANDLER_DESTRUCTOR_ADD_HOOK
}
| TAO_Connection_Handler::TAO_Connection_Handler | ( | const TAO_Connection_Handler & | ) | [private] |
| void TAO_Connection_Handler::cancel_pending_connection | ( | void | ) |
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.
{
if (this->connection_pending_)
{
this->connection_pending_ = false;
this->transport()->remove_reference();
}
}
| virtual int TAO_Connection_Handler::close_connection | ( | void | ) | [pure virtual] |
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, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.
| int TAO_Connection_Handler::close_connection_eh | ( | ACE_Event_Handler * | eh | ) | [protected] |
Implement close_connection() for Connection_Handlers that are also Event_Handlers.
Definition at line 297 of file Connection_Handler.cpp.
{
this->is_closed_ = true;
// Save the ID for debugging messages
ACE_HANDLE const handle = eh->get_handle ();
size_t const id = this->transport ()->id ();
if (TAO_debug_level)
{
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::"
"close_connection_eh, purging entry from cache\n",
handle));
}
this->transport ()->pre_close ();
// @@ This seems silly, but if we have no reason to be in the
// reactor, then we dont remove ourselves.
if (this->transport ()->wait_strategy ()->is_registered ())
{
ACE_Reactor *eh_reactor = eh->reactor ();
if (this->orb_core_->has_shutdown () == 0)
{
// If the ORB is nil, get the reactor from orb_core which gets it
// from LF.
if (eh_reactor == 0)
eh_reactor = this->transport()->orb_core()->reactor ();
}
// The Reactor must not be null, otherwise something else is
// horribly broken.
ACE_ASSERT (eh_reactor != 0);
if (TAO_debug_level)
{
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::"
"close_connection_eh, removing from the reactor\n",
handle));
}
// Use id instead of handle. Why? "handle" may be invalid for RW
// cases when drop_reply_on_shutdown is on, and when the
// orb_core is shutting down. This means that the handler will
// be left behind in the reactor which would create problems
// later. Just forcefully remove them. If none exists reactor
// will make things safer.
ACE_HANDLE tmp_handle = handle;
if (this->orb_core_->has_shutdown ())
tmp_handle = (ACE_HANDLE) id;
eh_reactor->remove_handler (tmp_handle,
ACE_Event_Handler::ALL_EVENTS_MASK |
ACE_Event_Handler::DONT_CALL);
// Also cancel any timers, we may create those for time-limited
// buffering
if (TAO_debug_level)
{
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::"
"close_connection_eh, cancel all timers\n",
handle));
}
eh_reactor->cancel_timer (eh);
// @@ This seems silly, the reactor is a much better authority to
// find out if a handle is registered...
this->transport ()->wait_strategy ()->is_registered (false);
}
// This call should be made only after the cache and reactor are
// cleaned up. This call can make upcalls to the application which
// in turn can make remote calls (Bug 1551 and Bug 1482). The remote
// calls from the application can try to use this handler from the
// cache or from the reactor. So clean them up before this is
// called.
this->transport ()->send_connection_closed_notifications ();
this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
this->orb_core_->leader_follower ());
if (TAO_debug_level)
{
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::"
"close_connection_eh\n",
id));
}
return 1;
}
| int TAO_Connection_Handler::close_handler | ( | u_long | flags = 0 |
) | [virtual] |
A close() hook, called by the Transport Connector when they want to close this handler
Definition at line 434 of file Connection_Handler.cpp.
{
this->is_closed_ = true;
this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED,
this->orb_core_->leader_follower ());
// If there was a pending connection cancel it.
this->cancel_pending_connection ();
// Purge transport from cache if it's in cache.
this->transport ()->purge_entry();
return 0;
}
| void TAO_Connection_Handler::connection_pending | ( | void | ) |
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.
{
if (!this->connection_pending_)
{
this->connection_pending_ = true;
this->transport()->add_reference();
}
}
| virtual int TAO_Connection_Handler::handle_input | ( | ACE_HANDLE | fd | ) | [pure virtual] |
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, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.
| int TAO_Connection_Handler::handle_input_eh | ( | ACE_HANDLE | h, | |
| ACE_Event_Handler * | eh | |||
| ) | [protected] |
Implement the handle_input() callback.
Definition at line 219 of file Connection_Handler.cpp.
{
// If we can't process upcalls just return
if (!this->transport ()->wait_strategy ()->can_process_upcalls ())
{
if (TAO_debug_level > 6)
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::handle_input_eh, "
"not going to handle_input on transport "
"because upcalls temporarily suspended on this thread\n",
this->transport()->id()));
return 0;
}
int const result = this->handle_input_internal (h, eh);
if (result == -1)
{
this->close_connection ();
return 0;
}
return result;
}
| int TAO_Connection_Handler::handle_input_internal | ( | ACE_HANDLE | h, | |
| ACE_Event_Handler * | eh | |||
| ) | [protected] |
Implement the handle_output() callback.
Definition at line 245 of file Connection_Handler.cpp.
{
// Let the transport know that it is used
(void) this->transport ()->update_transport ();
// Grab the transport id now and use the cached value for printing
// since the transport could dissappear by the time the thread
// returns.
size_t const t_id = this->transport ()->id ();
if (TAO_debug_level > 6)
{
ACE_HANDLE handle = eh->get_handle();
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
"handle = %d/%d\n",
t_id, handle, h));
}
TAO_Resume_Handle resume_handle (this->orb_core (), eh->get_handle ());
int return_value = 0;
this->pre_io_hook (return_value);
if (return_value != 0)
return return_value;
return_value = this->transport ()->handle_input (resume_handle);
this->pos_io_hook (return_value);
// Bug 1647; might need to change resume_handle's flag or
// change handle_input return value.
resume_handle.handle_input_return_value_hook(return_value);
if (TAO_debug_level > 6)
{
ACE_HANDLE handle = eh->get_handle ();
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler[%d]::handle_input, "
"handle = %d/%d, retval = %d\n",
t_id, handle, h, return_value));
}
if (return_value == -1)
resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
return return_value;
}
| int TAO_Connection_Handler::handle_output_eh | ( | ACE_HANDLE | h, | |
| ACE_Event_Handler * | eh | |||
| ) | [protected] |
Implement the handle_output() callback.
Definition at line 182 of file Connection_Handler.cpp.
{
// Let the transport that it is going to be used
(void) this->transport ()->update_transport ();
// Instantiate the resume handle here.. This will automatically
// resume the handle once data is written..
TAO_Resume_Handle resume_handle (this->orb_core (),
eh->get_handle ());
int return_value = 0;
this->pre_io_hook (return_value);
if (return_value != 0)
{
resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
return return_value;
}
// The default constraints are to never block.
TAO::Transport::Drain_Constraints dc;
if (this->transport ()->handle_output (dc) == TAO_Transport::DR_ERROR)
{
return_value = -1;
}
this->pos_io_hook (return_value);
if (return_value != 0)
{
resume_handle.set_flag (TAO_Resume_Handle::TAO_HANDLE_LEAVE_SUSPENDED);
}
return return_value;
}
| int TAO_Connection_Handler::handle_write_ready | ( | const ACE_Time_Value * | timeout | ) | [virtual] |
Derived classes should implement this for proper support with the Blocking Flushing Strategy.
Reimplemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.
Definition at line 70 of file Connection_Handler.inl.
{
return 0;
}
| bool TAO_Connection_Handler::is_closed | ( | void | ) | const |
Is the handler closed or timed out?
Definition at line 22 of file Connection_Handler.inl.
{
return (this->state_ == TAO_LF_Event::LFS_CONNECTION_CLOSED ||
this->state_ == TAO_LF_Event::LFS_TIMEOUT || this->is_closed_);
}
| bool TAO_Connection_Handler::is_connecting | ( | void | ) | const |
Is the handler in the process of being connected?
Definition at line 41 of file Connection_Handler.inl.
{
return this->state_ == TAO_LF_Event::LFS_CONNECTION_WAIT;
}
| bool TAO_Connection_Handler::is_open | ( | void | ) | const |
Is the handler open?
Definition at line 35 of file Connection_Handler.inl.
{
return this->state_ == TAO_LF_Event::LFS_SUCCESS;
}
| bool TAO_Connection_Handler::is_timeout | ( | void | ) | const |
Closed due to timeout?
Definition at line 29 of file Connection_Handler.inl.
{
return (this->state_ == TAO_LF_Event::LFS_TIMEOUT);
}
| virtual int TAO_Connection_Handler::open_handler | ( | void * | ) | [pure virtual] |
A open () hook.
See Thread_Per_Connection_Handler for a use case
Implemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.
| void TAO_Connection_Handler::operator= | ( | const TAO_Connection_Handler & | ) | [private] |
| TAO_ORB_Core * TAO_Connection_Handler::orb_core | ( | void | ) | [protected] |
Return our TAO_ORB_Core pointer.
Definition at line 10 of file Connection_Handler.inl.
{
return this->orb_core_;
}
| void TAO_Connection_Handler::pos_io_hook | ( | int & | return_value | ) | [protected, virtual] |
Post-invocation hook for I/O operations (handle_input() & handle_output()) See the SSLIOP protocol for an interesting use-case
Definition at line 429 of file Connection_Handler.cpp.
{
}
| void TAO_Connection_Handler::pre_io_hook | ( | int & | return_value | ) | [protected, virtual] |
Pre-invocation hook for I/O operations (handle_input() & handle_output()) See the SSLIOP protocol for an interesting use-case
Definition at line 424 of file Connection_Handler.cpp.
{
}
| int TAO_Connection_Handler::release_os_resources | ( | void | ) | [virtual] |
Release the OS resources related to this handler.
Reimplemented in TAO_IIOP_Connection_Handler, TAO_DIOP_Connection_Handler, and TAO_UIOP_Connection_Handler.
Definition at line 416 of file Connection_Handler.cpp.
{
return 0;
}
| int TAO_Connection_Handler::set_dscp_codepoint | ( | CORBA::Long | dscp_codepoint | ) | [virtual] |
Reimplemented in TAO_IIOP_Connection_Handler, and TAO_DIOP_Connection_Handler.
Definition at line 410 of file Connection_Handler.cpp.
{
return 0;
}
| int TAO_Connection_Handler::set_dscp_codepoint | ( | CORBA::Boolean | set_network_priority | ) | [virtual] |
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, and TAO_DIOP_Connection_Handler.
Definition at line 404 of file Connection_Handler.cpp.
{
return 0;
}
| int TAO_Connection_Handler::set_socket_option | ( | ACE_SOCK & | sock, | |
| int | snd_size, | |||
| int | rcv_size | |||
| ) | [protected] |
Set options on the socket.
Definition at line 58 of file Connection_Handler.cpp.
{
#if !defined (ACE_LACKS_SO_SNDBUF)
if (snd_size != 0
&& sock.set_option (SOL_SOCKET,
SO_SNDBUF,
(void *) &snd_size,
sizeof (snd_size)) == -1
&& errno != ENOTSUP)
{
return -1;
}
#endif /* !ACE_LACKS_SO_SNDBUF */
#if !defined (ACE_LACKS_SO_RCVBUF)
if (rcv_size != 0
&& sock.set_option (SOL_SOCKET,
SO_RCVBUF,
(void *) &rcv_size,
sizeof (int)) == -1
&& errno != ENOTSUP)
{
return -1;
}
#endif /* !ACE_LACKS_SO_RCVBUF */
#if defined (ACE_LACKS_SO_SNDBUF) && defined (ACE_LACKS_SO_RCVBUF)
ACE_UNUSED_ARG (snd_size);
ACE_UNUSED_ARG (rcv_size);
#endif
// Set the close-on-exec flag for that file descriptor. If the
// operation fails we are out of luck (some platforms do not support
// it and return -1).
(void) sock.enable (ACE_CLOEXEC);
return 0;
}
| int TAO_Connection_Handler::shared_open | ( | void | ) | [protected] |
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 45 of file Connection_Handler.cpp.
{
// This reference counting is related to asynch connections. It
// should probably be managed by the ACE_Strategy_Connector, since
// that's really the reference being managed here. also, whether
// open ultimately succeeds or fails, the connection attempted is
// ending, so the reference must be removed in any case.
this->cancel_pending_connection();
return 0;
}
| int TAO_Connection_Handler::svc_i | ( | void | ) |
This method is invoked from the svc () method of the Svc_Handler Object.
Definition at line 100 of file Connection_Handler.cpp.
{
int result = 0;
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) - Connection_Handler::svc_i begin\n")));
// Here we simply synthesize the "typical" event loop one might find
// in a reactive handler, except that this can simply block waiting
// for input.
ACE_Time_Value *max_wait_time = 0;
ACE_Time_Value timeout;
ACE_Time_Value current_timeout;
if (this->orb_core_->thread_per_connection_timeout (timeout))
{
current_timeout = timeout;
max_wait_time = ¤t_timeout;
}
TAO_Resume_Handle rh (this->orb_core_,
ACE_INVALID_HANDLE);
// We exit of the loop if
// - If the ORB core is shutdown by another thread
// - Or if the transport is null. This could happen if an error
// occured.
// - Or if during processing a return value of -1 is received.
while (!this->orb_core_->has_shutdown ()
&& result >= 0)
{
// Let the transport know that it is used
(void) this->transport ()->update_transport ();
result = this->transport ()->handle_input (rh, max_wait_time);
if (result == -1 && errno == ETIME)
{
// Ignore timeouts, they are only used to wake up and
// shutdown.
result = 0;
// Reset errno to make sure we don't trip over an old value
// of errno in case it is not reset when the recv() call
// fails if the socket has been closed.
errno = 0;
}
else if (result == -1)
{
// Something went wrong with the socket. Just quit
return result;
}
current_timeout = timeout;
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler::svc_i - "
"loop <%d>\n", current_timeout.msec ()));
}
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"TAO (%P|%t) - Connection_Handler::svc_i end\n"));
return result;
}
| TAO_Transport * TAO_Connection_Handler::transport | ( | void | ) |
Return the underlying transport object.
Definition at line 16 of file Connection_Handler.inl.
{
return this->transport_;
}
| void TAO_Connection_Handler::transport | ( | TAO_Transport * | transport | ) |
Set the underlying transport object.
Definition at line 171 of file Connection_Handler.cpp.
{
this->transport_ = transport;
// Enable reference counting on the event handler.
this->transport_->event_handler_i ()->reference_counting_policy ().value (
ACE_Event_Handler::Reference_Counting_Policy::ENABLED
);
}
bool TAO_Connection_Handler::connection_pending_ [private] |
Stores the connection pending state.
Definition at line 214 of file Connection_Handler.h.
bool TAO_Connection_Handler::is_closed_ [private] |
Once closed make sure the transport is not added back to the cache. This is distinct from the leader-follower state so it cannot be reset.
Definition at line 218 of file Connection_Handler.h.
TAO_ORB_Core* const TAO_Connection_Handler::orb_core_ [private] |
Pointer to the TAO_ORB_Core.
Definition at line 208 of file Connection_Handler.h.
TAO_Transport* TAO_Connection_Handler::transport_ [private] |
Transport object reference.
Definition at line 211 of file Connection_Handler.h.
1.7.0