summaryrefslogtreecommitdiff
path: root/TAO/tao/Strategies/UIOP_Connection_Handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/Strategies/UIOP_Connection_Handler.cpp')
-rw-r--r--TAO/tao/Strategies/UIOP_Connection_Handler.cpp296
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*/