diff options
Diffstat (limited to 'TAO/tao/Strategies/UIOP_Connection_Handler.cpp')
-rw-r--r-- | TAO/tao/Strategies/UIOP_Connection_Handler.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp new file mode 100644 index 00000000000..e1df3817d2a --- /dev/null +++ b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp @@ -0,0 +1,296 @@ +// $Id$ + +#include "UIOP_Connection_Handler.h" + +#if TAO_HAS_UIOP == 1 + +#include "UIOP_Transport.h" +#include "tao/debug.h" +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "tao/CDR.h" +#include "tao/Timeprobe.h" +#include "tao/Server_Strategy_Factory.h" +#include "tao/Messaging_Policy_i.h" +#include "UIOP_Endpoint.h" +#include "tao/Base_Connection_Property.h" + +#if !defined (__ACE_INLINE__) +# include "UIOP_Connection_Handler.inl" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID(Strategies, UIOP_Connect, "$Id$") + +#include "tao/GIOP_Message_Acceptors.h" +#include "tao/GIOP_Message_Lite.h" + + + +TAO_UIOP_Connection_Handler::TAO_UIOP_Connection_Handler (ACE_Thread_Manager *t) + : TAO_UIOP_SVC_HANDLER (t, 0 , 0), + TAO_Connection_Handler (0), + transport_ (this, 0, 0), + refcount_ (1), + uiop_properties_ (0) +{ + // This constructor should *never* get called, it is just here to + // make the compiler happy: the default implementation of the + // Creation_Strategy requires a constructor with that signature, we + // don't use that implementation, but some (most?) compilers + // instantiate it anyway. + ACE_ASSERT (this->orb_core () != 0); +} + + +TAO_UIOP_Connection_Handler::TAO_UIOP_Connection_Handler (TAO_ORB_Core *orb_core, + CORBA::Boolean flag, + void *arg) + : TAO_UIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0), + TAO_Connection_Handler (orb_core), + transport_ (this, orb_core, flag), + refcount_ (1), + uiop_properties_ (ACE_static_cast + (TAO_UIOP_Properties *, arg)) +{ +} + + +TAO_UIOP_Connection_Handler::~TAO_UIOP_Connection_Handler (void) +{ + + // If the socket has not already been closed. + if (this->get_handle () != ACE_INVALID_HANDLE) + { + // Cannot deal with errors, and therefore they are ignored. + this->transport_.send_buffered_messages (); + } + else + { + // Dequeue messages and delete message blocks. + this->transport_.dequeue_all (); + } +} + + +// @@ Should I do something here to enable non-blocking?? (Alex). +// @@ Alex: I don't know if this is the place to do it, but the way to +// do it is: +// if (this->peer ().enable (ACE_NONBLOCK) == -1) +// return -1; +// Probably we will need to use the transport to decide if it is +// needed or not. + +int +TAO_UIOP_Connection_Handler::open (void*) +{ + if (this->set_socket_option (this->peer (), + this->uiop_properties_->send_buffer_size, + this->uiop_properties_->recv_buffer_size) == -1) + return -1; + + // Called by the <Strategy_Acceptor> when the handler is completely + // connected. + ACE_UNIX_Addr addr; + + if (this->peer ().get_remote_addr (addr) == -1) + return -1; + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) UIOP connection to server ") + ACE_TEXT ("<%s> on %d\n"), + addr.get_path_name (), this->peer ().get_handle ())); + + return 0; +} + +int +TAO_UIOP_Connection_Handler::activate (long flags, + int n_threads, + int force_active, + long priority, + int grp_id, + ACE_Task_Base *task, + ACE_hthread_t thread_handles[], + void *stack[], + size_t stack_size[], + ACE_thread_t thread_names[]) +{ + if (TAO_debug_level) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) UIOP_Connection_Handler::activate %d ") + ACE_TEXT ("threads, flags = %d\n"), + n_threads, + flags, + THR_BOUND)); + + return TAO_UIOP_SVC_HANDLER::activate (flags, + n_threads, + force_active, + priority, + grp_id, + task, + thread_handles, + stack, + stack_size, + thread_names); +} + +int +TAO_UIOP_Connection_Handler::svc (void) +{ + // This method is called when an instance is "activated", i.e., + // turned into an active object. Presumably, activation spawns a + // thread with this method as the "worker function". + + // Call the implementation here + return this->svc_i (); +} + + +int +TAO_UIOP_Connection_Handler::handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask rm) +{ + // @@ Alex: we need to figure out if the transport decides to close + // us or something else. If it is something else (for example + // the cached connector trying to make room for other + // connections) then we should let the transport know, so it can + // in turn take appropiate action (such as sending exceptions to + // all waiting reply handlers). + if (TAO_debug_level) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) ") + ACE_TEXT ("UIOP_Connection_Handler::handle_close ") + ACE_TEXT ("(%d, %d)\n"), + handle, + rm)); + + --this->refcount_; + if (this->refcount_ == 0 && + this->is_registered ()) + { + // Make sure there are no timers. + this->reactor ()->cancel_timer (this); + + // Set the flag to indicate that it is no longer registered with + // the reactor, so that it isn't included in the set that is + // passed to the reactor on ORB destruction. + this->is_registered (0); + + // Decrement the reference count + this->decr_ref_count (); + } + + return 0; +} + +ACE_HANDLE +TAO_UIOP_Connection_Handler::fetch_handle (void) +{ + return this->get_handle (); +} + + +int +TAO_UIOP_Connection_Handler::handle_timeout (const ACE_Time_Value &, + const void *) +{ + // This method is called when buffering timer expires. + // + ACE_Time_Value *max_wait_time = 0; + + TAO_Stub *stub = 0; + int has_timeout; + this->orb_core ()->call_timeout_hook (stub, + has_timeout, + *max_wait_time); + + // Cannot deal with errors, and therefore they are ignored. + this->transport ()->send_buffered_messages (max_wait_time); + + return 0; +} + + +int +TAO_UIOP_Connection_Handler::close (u_long) +{ + this->destroy (); + + return 0; +} + + +int +TAO_UIOP_Connection_Handler::add_handler_to_cache (void) +{ + ACE_UNIX_Addr addr; + + // Get the peername. + if (this->peer ().get_remote_addr (addr) == -1) + return -1; + + // Construct an UIOP_Endpoint object + TAO_UIOP_Endpoint endpoint (addr); + + // Construct a property object + TAO_Base_Connection_Property prop (&endpoint); + + // Add the handler to Cache + return this->orb_core ()->connection_cache ().cache_handler (&prop, + this); +} + + +int +TAO_UIOP_Connection_Handler::handle_input (ACE_HANDLE h) +{ + return this->handle_input_i (h); +} + + +int +TAO_UIOP_Connection_Handler::handle_input_i (ACE_HANDLE, + ACE_Time_Value *max_wait_time) +{ + this->refcount_++; + + // Call the transport read the message + int result = this->transport_.read_process_message (max_wait_time); + + // Now the message has been read + if (result == -1 && TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %p\n"), + ACE_TEXT ("UIOP_Connection_Handler::read_message \n"))); + + } + + // The upcall is done. Bump down the reference count + --this->refcount_; + if (this->refcount_ == 0) + this->decr_ref_count (); + + if (result == 0 || result == -1) + { + return result; + } + + return 0; +} + + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Svc_Handler<ACE_LSOCK_STREAM, ACE_NULL_SYNCH>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Svc_Handler<ACE_LSOCK_STREAM, ACE_NULL_SYNCH> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +#endif /*TAO_HAS_UIOP == 1*/ |