UIPMC_Connection_Handler.cpp

Go to the documentation of this file.
00001 // This may look like C, but it's really -*- C++ -*-
00002 //
00003 // $Id: UIPMC_Connection_Handler.cpp 79015 2007-07-24 15:03:04Z vridosh $
00004 
00005 
00006 #include "orbsvcs/PortableGroup/UIPMC_Connection_Handler.h"
00007 #include "orbsvcs/PortableGroup/UIPMC_Endpoint.h"
00008 
00009 #include "tao/Timeprobe.h"
00010 #include "tao/debug.h"
00011 #include "tao/ORB_Core.h"
00012 #include "tao/ORB.h"
00013 #include "tao/CDR.h"
00014 #include "tao/Server_Strategy_Factory.h"
00015 #include "tao/Transport_Cache_Manager.h"
00016 #include "tao/Thread_Lane_Resources.h"
00017 #include "tao/Base_Transport_Property.h"
00018 #include "tao/Resume_Handle.h"
00019 #include "tao/Protocols_Hooks.h"
00020 
00021 
00022 ACE_RCSID(PortableGroup,
00023           UIPMC_Connection_Handler,
00024           "$Id: UIPMC_Connection_Handler.cpp 79015 2007-07-24 15:03:04Z vridosh $")
00025 
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 TAO_UIPMC_Connection_Handler::TAO_UIPMC_Connection_Handler (ACE_Thread_Manager *t)
00029   : TAO_UIPMC_SVC_HANDLER (t, 0 , 0),
00030     TAO_Connection_Handler (0),
00031     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00032 {
00033   // This constructor should *never* get called, it is just here to
00034   // make the compiler happy: the default implementation of the
00035   // Creation_Strategy requires a constructor with that signature, we
00036   // don't use that implementation, but some (most?) compilers
00037   // instantiate it anyway.
00038   ACE_ASSERT (0);
00039 }
00040 
00041 TAO_UIPMC_Connection_Handler::TAO_UIPMC_Connection_Handler (TAO_ORB_Core *orb_core)
00042   : TAO_UIPMC_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
00043     TAO_Connection_Handler (orb_core),
00044     dscp_codepoint_ (IPDSFIELD_DSCP_DEFAULT << 2)
00045 {
00046   UIPMC_TRANSPORT* specific_transport = 0;
00047   ACE_NEW(specific_transport,
00048           UIPMC_TRANSPORT (this, orb_core));
00049 
00050   // store this pointer (indirectly increment ref count)
00051   this->transport (specific_transport);
00052 }
00053 
00054 TAO_UIPMC_Connection_Handler::~TAO_UIPMC_Connection_Handler (void)
00055 {
00056   delete this->transport ();
00057   int const result =
00058     this->release_os_resources ();
00059 
00060   if (result == -1 && TAO_debug_level)
00061     {
00062       ACE_ERROR ((LM_ERROR,
00063                   ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::")
00064                   ACE_TEXT("~UIPMC_Connection_Handler, ")
00065                   ACE_TEXT("release_os_resources() failed %m\n")));
00066     }
00067 }
00068 
00069 const ACE_INET_Addr &
00070 TAO_UIPMC_Connection_Handler::addr (void)
00071 {
00072   return this->addr_;
00073 }
00074 
00075 void
00076 TAO_UIPMC_Connection_Handler::addr (const ACE_INET_Addr &addr)
00077 {
00078   this->addr_ = addr;
00079 }
00080 
00081 const ACE_INET_Addr &
00082 TAO_UIPMC_Connection_Handler::local_addr (void)
00083 {
00084   return local_addr_;
00085 }
00086 
00087 void
00088 TAO_UIPMC_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
00089 {
00090   local_addr_ = addr;
00091 }
00092 
00093 ssize_t
00094 TAO_UIPMC_Connection_Handler::send (const iovec iov[],
00095                                     int n,
00096                                     const ACE_Addr &addr,
00097                                     int flags) const
00098 {
00099   return this->peer ().send (iov, n, addr, flags);
00100 }
00101 
00102 int
00103 TAO_UIPMC_Connection_Handler::open_handler (void *v)
00104 {
00105   return this->open (v);
00106 }
00107 
00108 int
00109 TAO_UIPMC_Connection_Handler::open (void*)
00110 {
00111   this->peer ().open (this->local_addr_);
00112 
00113   if (TAO_debug_level > 5)
00114   {
00115      ACE_DEBUG ((LM_DEBUG,
00116                  ACE_TEXT("TAO (%P|%t) - UIPMC_Connection_Handler::open, ")
00117                  ACE_TEXT("listening on: <%s:%u>\n"),
00118                  this->local_addr_.get_host_addr (),
00119                  this->local_addr_.get_port_number ()));
00120   }
00121 
00122   // Set that the transport is now connected, if fails we return -1
00123   // Use C-style cast b/c otherwise we get warnings on lots of
00124   // compilers
00125   if (!this->transport ()->post_open ((size_t) this->peer ().get_handle ()))
00126     return -1;
00127 
00128   this->state_changed (TAO_LF_Event::LFS_SUCCESS,
00129                        this->orb_core ()->leader_follower ());
00130 
00131   return 0;
00132 }
00133 
00134 int
00135 TAO_UIPMC_Connection_Handler::resume_handler (void)
00136 {
00137   return ACE_Event_Handler::ACE_APPLICATION_RESUMES_HANDLER;
00138 }
00139 
00140 int
00141 TAO_UIPMC_Connection_Handler::close_connection (void)
00142 {
00143   return this->close_connection_eh (this);
00144 }
00145 
00146 int
00147 TAO_UIPMC_Connection_Handler::handle_input (ACE_HANDLE h)
00148 {
00149   return this->handle_input_eh (h, this);
00150 }
00151 
00152 int
00153 TAO_UIPMC_Connection_Handler::handle_output (ACE_HANDLE handle)
00154 {
00155   int result =
00156     this->handle_output_eh (handle, this);
00157 
00158   if (result == -1)
00159     {
00160       this->close_connection ();
00161       return 0;
00162     }
00163 
00164   return result;
00165 }
00166 
00167 int
00168 TAO_UIPMC_Connection_Handler::handle_timeout (const ACE_Time_Value &,
00169                                               const void *)
00170 {
00171   // Using this to ensure this instance will be deleted (if necessary)
00172   // only after reset_state(). Without this, when this refcount==1 -
00173   // the call to close() will cause a call to remove_reference() which
00174   // will delete this. At that point this->reset_state() is in no
00175   // man's territory and that causes SEGV on some platforms (Windows!)
00176 
00177   TAO_Auto_Reference<TAO_UIPMC_Connection_Handler> safeguard (*this);
00178 
00179   // NOTE: Perhaps not the best solution, as it feels like the upper
00180   // layers should be responsible for this?
00181 
00182   // We don't use this upcall for I/O.  This is only used by the
00183   // Connector to indicate that the connection timedout.  Therefore,
00184   // we should call close().
00185   int ret = this->close ();
00186   this->reset_state (TAO_LF_Event::LFS_TIMEOUT);
00187   return ret;
00188 }
00189 
00190 int
00191 TAO_UIPMC_Connection_Handler::handle_close (ACE_HANDLE,
00192                                             ACE_Reactor_Mask)
00193 {
00194   // No asserts here since the handler is registered with the Reactor
00195   // and the handler ownership is given to the Reactor.  When the
00196   // Reactor closes, it will call handle_close() on the handler.  It
00197   // is however important to overwrite handle_close() to do nothing
00198   // since the base class does too much.
00199   return 0;
00200 }
00201 
00202 int
00203 TAO_UIPMC_Connection_Handler::close (u_long)
00204 {
00205   return this->close_handler ();
00206 }
00207 
00208 int
00209 TAO_UIPMC_Connection_Handler::release_os_resources (void)
00210 {
00211   return this->peer ().close ();
00212 }
00213 
00214 int
00215 TAO_UIPMC_Connection_Handler::add_transport_to_cache (void)
00216 {
00217   ACE_INET_Addr addr;
00218 
00219   // This function is called by the acceptor to add this
00220   // transport to the transport cache.  This is really
00221   // important for proper shutdown.  The address used
00222   // is irrelevent, since UIPMC is connectionless.
00223 
00224   // Construct a UIPMC_Endpoint object.
00225   TAO_UIPMC_Endpoint endpoint (addr);
00226 
00227   // Construct a property object
00228   TAO_Base_Transport_Property prop (&endpoint);
00229 
00230   // Add the handler to Cache
00231   return this->orb_core ()->lane_resources ()
00232           .transport_cache ().cache_transport (&prop,
00233                                                this->transport ());
00234 }
00235 
00236 int
00237 TAO_UIPMC_Connection_Handler::set_tos (int tos)
00238 {
00239   // Since only client can send data over MIOP
00240   // then dscp is only applicable to client socket.
00241   if (tos != this->dscp_codepoint_)
00242     {
00243       int result = 0;
00244 #if defined (ACE_HAS_IPV6)
00245       ACE_INET_Addr local_addr;
00246       if (this->peer ().get_local_addr (local_addr) == -1)
00247         return -1;
00248       else if (local_addr.get_type () == AF_INET6)
00249 # if !defined (IPV6_TCLASS)
00250       // IPv6 defines option IPV6_TCLASS for specifying traffic class/priority
00251       // but not many implementations yet (very new;-).
00252         {
00253           if (TAO_debug_level)
00254             {
00255               ACE_DEBUG ((LM_DEBUG,
00256                           "TAO (%P|%t) - UIPMC_Connection_Handler::"
00257                           "set_dscp_codepoint -> IPV6_TCLASS not supported yet\n"));
00258             }
00259           return 0;
00260         }
00261 # else /* !IPV6_TCLASS */
00262         result = this->peer ().set_option (IPPROTO_IPV6,
00263                                            IPV6_TCLASS,
00264                                            (int *) &tos,
00265                                            (int) sizeof (tos));
00266       else
00267 # endif /* IPV6_TCLASS */
00268 #endif /* ACE_HAS_IPV6 */
00269       result = this->peer ().set_option (IPPROTO_IP,
00270                                          IP_TOS,
00271                                          (int *) &tos,
00272                                          (int) sizeof (tos));
00273 
00274       if (TAO_debug_level)
00275         {
00276           ACE_DEBUG ((LM_DEBUG,
00277                       "TAO (%P|%t) - UIPMC_Connection_Handler::"
00278                       "set_dscp_codepoint -> dscp: %x; result: %d; %s\n",
00279                       tos,
00280                       result,
00281                       result == -1 ? "try running as superuser" : ""));
00282         }
00283 
00284       // On successful setting of TOS field.
00285       if (result == 0)
00286         this->dscp_codepoint_ = tos;
00287     }
00288 
00289   return 0;
00290 }
00291 
00292 int
00293 TAO_UIPMC_Connection_Handler::set_dscp_codepoint (CORBA::Long dscp_codepoint)
00294 {
00295   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00296 
00297   CORBA::Long codepoint = dscp_codepoint;
00298 
00299   tos = static_cast<int> (codepoint) << 2;
00300 
00301   this->set_tos (tos);
00302 
00303   return 0;
00304 }
00305 
00306 int
00307 TAO_UIPMC_Connection_Handler::set_dscp_codepoint (CORBA::Boolean set_network_priority)
00308 {
00309   int tos = IPDSFIELD_DSCP_DEFAULT << 2;
00310 
00311   if (set_network_priority)
00312     {
00313       TAO_Protocols_Hooks *tph =
00314         this->orb_core ()->get_protocols_hooks ();
00315 
00316       if (tph != 0 )
00317         {
00318           CORBA::Long codepoint =
00319             tph->get_dscp_codepoint ();
00320 
00321           tos = static_cast<int> (codepoint) << 2;
00322           this->set_tos (tos);
00323         }
00324     }
00325 
00326   return 0;
00327 }
00328 
00329 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 16:22:31 2008 for TAO_PortableGroup by doxygen 1.3.6