diff options
author | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-01-27 05:28:30 +0000 |
---|---|---|
committer | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-01-27 05:28:30 +0000 |
commit | e839c96e78c4442bcf5ccfc09fde2e24bf8e7192 (patch) | |
tree | f2d874edbf243c4e449c548b627386887f3da979 | |
parent | 3787e34faa53b74d17c69940a6baa717388ff11a (diff) | |
download | ATCD-e839c96e78c4442bcf5ccfc09fde2e24bf8e7192.tar.gz |
*** empty log message ***
-rw-r--r-- | TAO/tao/SHMIOP_Acceptor.cpp | 390 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Acceptor.h | 115 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Acceptor.i | 8 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Connect.cpp | 506 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Connect.h | 177 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Connect.i | 14 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Connector.cpp | 716 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Connector.h | 205 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Factory.cpp | 85 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Factory.h | 63 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Profile.cpp | 471 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Profile.h | 184 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Profile.i | 69 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Transport.cpp | 377 | ||||
-rw-r--r-- | TAO/tao/SHMIOP_Transport.h | 166 | ||||
-rw-r--r-- | TAO/tao/TAO.dsp | 152 | ||||
-rw-r--r-- | TAO/tao/TAO_Static.dsp | 60 | ||||
-rw-r--r-- | TAO/tao/corbafwd.h | 2 | ||||
-rw-r--r-- | ace/OS.h | 14 |
19 files changed, 3770 insertions, 4 deletions
diff --git a/TAO/tao/SHMIOP_Acceptor.cpp b/TAO/tao/SHMIOP_Acceptor.cpp new file mode 100644 index 00000000000..ca4b144b969 --- /dev/null +++ b/TAO/tao/SHMIOP_Acceptor.cpp @@ -0,0 +1,390 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +#include "tao/SHMIOP_Acceptor.h" +#include "tao/SHMIOP_Profile.h" +#include "tao/MProfile.h" +#include "tao/ORB_Core.h" +#include "tao/Server_Strategy_Factory.h" +#include "tao/GIOP.h" +#include "tao/debug.h" + +#if !defined(__ACE_INLINE__) +#include "tao/SHMIOP_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao, SHMIOP_Acceptor, "$Id$") + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Acceptor<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR>; +template class ACE_Strategy_Acceptor<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR>; +template class ACE_Accept_Strategy<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR>; +template class ACE_Creation_Strategy<TAO_SHMIOP_Server_Connection_Handler>; +template class ACE_Concurrency_Strategy<TAO_SHMIOP_Server_Connection_Handler>; +template class ACE_Scheduling_Strategy<TAO_SHMIOP_Server_Connection_Handler>; +template class TAO_Creation_Strategy<TAO_SHMIOP_Server_Connection_Handler>; +template class TAO_Concurrency_Strategy<TAO_SHMIOP_Server_Connection_Handler>; +template class TAO_Accept_Strategy<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Acceptor<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> +#pragma instantiate ACE_Strategy_Acceptor<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> +#pragma instantiate ACE_Accept_Strategy<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> +#pragma instantiate ACE_Creation_Strategy<TAO_SHMIOP_Server_Connection_Handler> +#pragma instantiate ACE_Concurrency_Strategy<TAO_SHMIOP_Server_Connection_Handler> +#pragma instantiate ACE_Scheduling_Strategy<TAO_SHMIOP_Server_Connection_Handler> +#pragma instantiate TAO_Creation_Strategy<TAO_SHMIOP_Server_Connection_Handler> +#pragma instantiate TAO_Concurrency_Strategy<TAO_SHMIOP_Server_Connection_Handler> +#pragma instantiate TAO_Accept_Strategy<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +TAO_SHMIOP_Acceptor::TAO_SHMIOP_Acceptor (void) + : TAO_Acceptor (TAO_TAG_SHMEM_PROFILE), + version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), + orb_core_ (0), + base_acceptor_ (), + creation_strategy_ (0), + concurrency_strategy_ (0), + accept_strategy_ (0) +{ +} + +TAO_SHMIOP_Acceptor::~TAO_SHMIOP_Acceptor (void) +{ + delete this->creation_strategy_; + delete this->concurrency_strategy_; + delete this->accept_strategy_; +} + +// TODO = +// 2) For V1.[1,2] there are tagged components +// 3) Create multiple profiles for wild carded endpoints (may be multiple +// interfaces over which we can receive requests. Thus a profile +// must be made for each one. + +int +TAO_SHMIOP_Acceptor::create_mprofile (const TAO_ObjectKey &object_key, + TAO_MProfile &mprofile) +{ + // @@ we only make one for now + int count = mprofile.profile_count (); + if ((mprofile.size () - count) < 1 + && mprofile.grow (count + 1) == -1) + return -1; + + TAO_SHMIOP_Profile *pfile = 0; + ACE_NEW_RETURN (pfile, + TAO_SHMIOP_Profile (this->host_.c_str (), + this->address_.get_port_number (), + object_key, + this->address_, + this->version_, + this->orb_core_), + -1); + + if (mprofile.give_profile (pfile) == -1) + { + pfile->_decr_refcnt (); + pfile = 0; + return -1; + } + + if (this->orb_core_->orb_params ()->std_profile_components () == 0) + return 0; + + pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE); + + CONV_FRAME::CodeSetComponentInfo code_set_info; + code_set_info.ForCharData.native_code_set = + TAO_DEFAULT_CHAR_CODESET_ID; + code_set_info.ForWcharData.native_code_set = + TAO_DEFAULT_WCHAR_CODESET_ID; + pfile->tagged_components ().set_code_sets (code_set_info); + + pfile->tagged_components ().set_tao_priority (this->priority ()); + + return 0; +} + +int +TAO_SHMIOP_Acceptor::is_collocated (const TAO_Profile *pfile) +{ + const TAO_SHMIOP_Profile *profile = + ACE_dynamic_cast(const TAO_SHMIOP_Profile *, + pfile); + + // compare the port and sin_addr (numeric host address) + return profile->object_addr () == this->address_; +} + +int +TAO_SHMIOP_Acceptor::close (void) +{ + return this->base_acceptor_.close (); +} + +int +TAO_SHMIOP_Acceptor::open (TAO_ORB_Core *orb_core, + int major, + int minor, + const char *address, + const char *options) +{ + if (address == 0) + return -1; + + if (major >=0 && minor >= 0) + this->version_.set_version (ACE_static_cast (CORBA::Octet, + major), + ACE_static_cast (CORBA::Octet, + minor)); + // Parse options + if (this->parse_options (options) == -1) + return -1; + + ACE_INET_Addr addr; + + if (ACE_OS::strchr (address, ':') == address) + { + // The address is a port number or port name, and obtain the + // fully qualified domain name. No hostname was specified. + + char buffer[MAXHOSTNAMELEN + 1]; + if (addr.get_host_name (buffer, + sizeof (buffer)) != 0) + return -1; + + // First convert the port into a usable form. + if (addr.set (address + sizeof (':')) != 0) + return -1; + + // Now reset the port and set the host. + if (addr.set (addr.get_port_number (), + buffer, + 1) != 0) + return -1; + } + else if (ACE_OS::strchr (address, ':') == 0) + { + // The address is a hostname. No port was specified, so assume + // port zero (port will be chosen for us). + if (addr.set ((unsigned short) 0, address) != 0) + return -1; + } + else if (addr.set (address) != 0) + // Host and port were specified. + return -1; + + return this->open_i (orb_core, addr); +} + +int +TAO_SHMIOP_Acceptor::open_default (TAO_ORB_Core *orb_core, + const char *options) +{ + // Parse options + if (this->parse_options (options) == -1) + return -1; + + // @@ Until we can support multihomed machines correctly we must + // pick the "default interface" and only listen on that IP + // address. + + ACE_INET_Addr addr; + char buffer[MAXHOSTNAMELEN + 1]; + if (addr.get_host_name (buffer, + sizeof (buffer)) != 0) + return -1; + + if (addr.set (u_short(0), + buffer, + 1) != 0) + return -1; + + this->host_ = buffer; + + return this->open_i (orb_core, + addr); +} + +int +TAO_SHMIOP_Acceptor::open_i (TAO_ORB_Core* orb_core, + const ACE_INET_Addr& addr) +{ + this->orb_core_ = orb_core; + + ACE_NEW_RETURN (this->creation_strategy_, + TAO_SHMIOP_CREATION_STRATEGY (this->orb_core_), + -1); + + ACE_NEW_RETURN (this->concurrency_strategy_, + TAO_SHMIOP_CONCURRENCY_STRATEGY (this->orb_core_), + -1); + + ACE_NEW_RETURN (this->accept_strategy_, + TAO_SHMIOP_ACCEPT_STRATEGY (this->orb_core_), + -1); + + // We only accept connection on localhost. + // ACE_INET_Addr local_addr (addr.get_port_number (), ASYS_TEXT ("localhost")); + if (this->base_acceptor_.open (addr, + this->orb_core_->reactor (this), + this->creation_strategy_, + this->accept_strategy_, + this->concurrency_strategy_) == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("\n\nTAO (%P|%t) SHMIOP_Acceptor::open_i - %p\n\n"), + ASYS_TEXT ("cannot open acceptor"))); + return -1; + } + + // @@ Should this be a catastrophic error??? + if (this->base_acceptor_.acceptor ().get_local_addr (this->address_) != 0) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("\n\nTAO (%P|%t) SHMIOP_Acceptor::open_i - %p\n\n"), + ASYS_TEXT ("cannot get local addr"))); + return -1; + } + + // This will be the actualy host name of the original endpoint. + char tmp_host[MAXHOSTNAMELEN+1]; + if (addr.get_host_name (tmp_host, + sizeof tmp_host) != 0) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("\n\nTAO (%P|%t) SHMIOP_Acceptor::open_i - %p\n\n"), + ASYS_TEXT ("cannot cache hostname"))); + return -1; + } + this->host_ = tmp_host; + + if (TAO_debug_level > 5) + { + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("\nTAO (%P|%t) SHMIOP_Acceptor::open_i - ") + ASYS_TEXT ("listening on %s using: <localhost:%u>\n"), + this->host_.c_str (), + this->address_.get_port_number ())); + } + return 0; +} + +CORBA::ULong +TAO_SHMIOP_Acceptor::endpoint_count (void) +{ + // @@ for now just assume one! + // we should take a look at the local address, if it is zero then + // get the list of available IP interfaces and return this number. + return 1; +} + +int +TAO_SHMIOP_Acceptor::parse_options (const char *str) +{ + if (str == 0) + return 0; // No options to parse. Not a problem. + + // Use an option format similar to the one used for CGI scripts in + // HTTP URLs. + // e.g.: option1=foo&option2=bar + + ACE_CString options (str); + + size_t len = options.length (); + + const char option_delimiter = '&'; + + // Count the number of options. + + CORBA::ULong option_count = 1; + // Number of endpoints in the string (initialized to 1). + + // Only check for endpoints after the protocol specification and + // before the object key. + for (size_t i = 0; i < len; ++i) + if (options[i] == option_delimiter) + option_count++; + + // The idea behind the following loop is to split the options into + // (option, name) pairs. + // For example, + // `option1=foo&option2=bar' + // will be parsed into: + // `option1=foo' + // `option2=bar' + + int begin = 0; + int end = -1; + + for (CORBA::ULong j = 0; j < option_count; ++j) + { + begin += end + 1; + + if (j < option_count - 1) + end = options.find (option_delimiter, begin); + else + end = len - begin; // Handle last endpoint differently + + if (end == begin) + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) Zero length IIOP option.\n")), + -1); + else if (end != ACE_CString::npos) + { + ACE_CString opt = options.substring (begin, end); + + int slot = opt.find ("="); + + if (slot == ACE_static_cast (int, len - 1) + || slot == ACE_CString::npos) + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) IIOP option <%s> is ") + ASYS_TEXT ("missing a value.\n"), + opt.c_str ()), + -1); + + ACE_CString name = opt.substring (0, slot); + ACE_CString value = opt.substring (slot + 1); + + if (name.length () == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) Zero length IIOP ") + ASYS_TEXT ("option name.\n")), + -1); + + if (name == "priority") + { + CORBA::Short corba_priority = + ACE_static_cast (CORBA::Short, + ACE_OS::atoi (value.c_str ())); + + if (corba_priority >= 0 + /* && corba_priority < 32768 */) + // priority_ and corba_priority will always be less + // than 32768 since CORBA::Short is a signed 16 bit + // integer. + this->priority_ = corba_priority; + else + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) Invalid IIOP endpoint ") + ASYS_TEXT ("priority: <%s>\n"), + value.c_str ()), + -1); + } + else + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) Invalid IIOP option: <%s>\n"), + name.c_str ()), + -1); + } + } + return 0; +} diff --git a/TAO/tao/SHMIOP_Acceptor.h b/TAO/tao/SHMIOP_Acceptor.h new file mode 100644 index 00000000000..5b4e0833e67 --- /dev/null +++ b/TAO/tao/SHMIOP_Acceptor.h @@ -0,0 +1,115 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Acceptor.h +// +// = DESCRIPTION +// SHMIOP specific acceptor processing +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef TAO_SHMIOP_ACCEPTOR_H +#define TAO_SHMIOP_ACCEPTOR_H + +#include "tao/Pluggable.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/SHMIOP_Connect.h" +#include "tao/Acceptor_Impl.h" + +#include "ace/Acceptor.h" +#include "ace/MEM_Acceptor.h" + +// TAO SHMIOP_Acceptor concrete call defination + +class TAO_Export TAO_SHMIOP_Acceptor : public TAO_Acceptor +{ + // = TITLE + // TAO_SHMIOP_Acceptor + // + // = DESCRIPTION + // The IIOP-specific bridge class for the concrete acceptor. + // +public: + TAO_SHMIOP_Acceptor (void); + // Constructor. + + ~TAO_SHMIOP_Acceptor (void); + // Destructor. + + const ACE_INET_Addr& address (void) const; + // @@ Helper method for the implementation repository, should go + // away + + typedef ACE_Strategy_Acceptor<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> TAO_SHMIOP_BASE_ACCEPTOR; + typedef TAO_Creation_Strategy<TAO_SHMIOP_Server_Connection_Handler> TAO_SHMIOP_CREATION_STRATEGY; + typedef TAO_Concurrency_Strategy<TAO_SHMIOP_Server_Connection_Handler> TAO_SHMIOP_CONCURRENCY_STRATEGY; + typedef TAO_Accept_Strategy<TAO_SHMIOP_Server_Connection_Handler, ACE_MEM_ACCEPTOR> TAO_SHMIOP_ACCEPT_STRATEGY; + + // = The TAO_Acceptor methods, check the documentation in + // Pluggable.h for details. + virtual int open (TAO_ORB_Core *orb_core, + int version_major, + int version_minor, + const char *address, + const char *options = 0); + virtual int open_default (TAO_ORB_Core *orb_core, + const char *options = 0); + virtual int close (void); + virtual int create_mprofile (const TAO_ObjectKey &object_key, + TAO_MProfile &mprofile); + virtual int is_collocated (const TAO_Profile* profile); + virtual CORBA::ULong endpoint_count (void); + +private: + int open_i (TAO_ORB_Core* orb_core, + const ACE_INET_Addr& addr); + // Implement the common part of the open*() methods. + + virtual int parse_options (const char *options); + // Parse protocol specific options. + +protected: + ACE_INET_Addr address_; + ACE_CString host_; + // Cache the information about the endpoint serviced by this + // acceptor. + // @@ TODO there may in fact be multiple hostnames for this + // endpoint. For example it the IP address is INADDR_ANY + // (0.0.0.0) then there will be possibly a different hostname for + // each interface. + + TAO_GIOP_Version version_; + // The GIOP version for this endpoint + + TAO_ORB_Core *orb_core_; + // ORB Core. + +private: + TAO_SHMIOP_BASE_ACCEPTOR base_acceptor_; + // the concrete acceptor, as a pointer to it's base class. + + TAO_SHMIOP_CREATION_STRATEGY *creation_strategy_; + TAO_SHMIOP_CONCURRENCY_STRATEGY *concurrency_strategy_; + TAO_SHMIOP_ACCEPT_STRATEGY *accept_strategy_; + // Acceptor strategies. + +}; + +#if defined(__ACE_INLINE__) +#include "tao/SHMIOP_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* TAO_SHMIOP_ACCEPTOR_H */ diff --git a/TAO/tao/SHMIOP_Acceptor.i b/TAO/tao/SHMIOP_Acceptor.i new file mode 100644 index 00000000000..6c9ad6709f6 --- /dev/null +++ b/TAO/tao/SHMIOP_Acceptor.i @@ -0,0 +1,8 @@ +// -*- C++ -*- +// $Id$ + +ACE_INLINE const ACE_INET_Addr& +TAO_SHMIOP_Acceptor::address (void) const +{ + return this->address_; +} diff --git a/TAO/tao/SHMIOP_Connect.cpp b/TAO/tao/SHMIOP_Connect.cpp new file mode 100644 index 00000000000..29171acfcc4 --- /dev/null +++ b/TAO/tao/SHMIOP_Connect.cpp @@ -0,0 +1,506 @@ +// $Id$ + +#include "tao/SHMIOP_Connect.h" +#include "tao/Timeprobe.h" +#include "tao/debug.h" +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "tao/CDR.h" +#include "tao/GIOP.h" + +#if !defined (__ACE_INLINE__) +# include "tao/SHMIOP_Connect.i" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID(tao, SHMIOP_Connect, "$Id$") + +#if defined (ACE_ENABLE_TIMEPROBES) + +static const char *TAO_SHMIOP_Connect_Timeprobe_Description[] = +{ + "SHMIOP_Server_Connection_Handler::handle_input - start", + "SHMIOP_Server_Connection_Handler::handle_input - end", + + "SHMIOP_Server_Connection_Handler::handle_locate - start", + "SHMIOP_Server_Connection_Handler::handle_locate - end", + + "SHMIOP_Server_Connection_Handler::receive_request - end", + + "SHMIOP_Client_Connection_Handler::send_request - start", + "SHMIOP_Client_Connection_Handler::send_request - end"}; + +enum +{ + // Timeprobe description table start key + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_START = 300, + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_END, + + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_HANDLE_LOCATE_START, + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_HANDLE_LOCATE_END, + + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_RECEIVE_REQUEST_END, + + TAO_SHMIOP_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_START, + TAO_SHMIOP_CLIENT_CONNECTION_HANDLER_SEND_REQUEST_END +}; + +// Setup Timeprobes +ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_SHMIOP_Connect_Timeprobe_Description, + TAO_SHMIOP_SERVER_CONNECTION_HANDLER_HANDLE_INPUT_START); + +#endif /* ACE_ENABLE_TIMEPROBES */ + +TAO_SHMIOP_Handler_Base::TAO_SHMIOP_Handler_Base (TAO_ORB_Core *orb_core) + : TAO_SVC_HANDLER (orb_core->thr_mgr (), 0, 0) +{ +} + +TAO_SHMIOP_Handler_Base::TAO_SHMIOP_Handler_Base (ACE_Thread_Manager *t) + : TAO_SVC_HANDLER (t, 0, 0) +{ +} + +// **************************************************************** + +TAO_SHMIOP_Server_Connection_Handler::TAO_SHMIOP_Server_Connection_Handler (ACE_Thread_Manager *t) + : TAO_SHMIOP_Handler_Base (t), + transport_ (this, 0), + orb_core_ (0), + tss_resources_ (0), + refcount_ (1) + +{ + // 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_SHMIOP_Server_Connection_Handler::TAO_SHMIOP_Server_Connection_Handler (TAO_ORB_Core *orb_core) + : TAO_SHMIOP_Handler_Base (orb_core), + transport_ (this, orb_core), + orb_core_ (orb_core), + tss_resources_ (orb_core->get_tss_resources ()), + refcount_ (1) +{ +} + +TAO_SHMIOP_Server_Connection_Handler::~TAO_SHMIOP_Server_Connection_Handler (void) +{ +} + +int +TAO_SHMIOP_Server_Connection_Handler::open (void*) +{ +#if !defined (ACE_LACKS_SOCKET_BUFSIZ) + int sndbufsize = + this->orb_core_->orb_params ()->sock_sndbuf_size (); + int rcvbufsize = + this->orb_core_->orb_params ()->sock_rcvbuf_size (); + + if (this->peer ().set_option (SOL_SOCKET, + SO_SNDBUF, + (void *) &sndbufsize, + sizeof (sndbufsize)) == -1 + && errno != ENOTSUP) + return -1; + else if (this->peer ().set_option (SOL_SOCKET, + SO_RCVBUF, + (void *) &rcvbufsize, + sizeof (rcvbufsize)) == -1 + && errno != ENOTSUP) + return -1; +#endif /* !ACE_LACKS_SOCKET_BUFSIZ */ + +#if defined (TCP_NODELAY) + int nodelay = + this->orb_core_->orb_params ()->nodelay (); + + if (this->peer ().set_option (ACE_IPPROTO_TCP, + TCP_NODELAY, + (void *) &nodelay, + sizeof (nodelay)) == -1) + return -1; +#endif /* TCP_NODELAY */ + + (void) this->peer ().enable (ACE_CLOEXEC); + // 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). + + // Called by the <Strategy_Acceptor> when the handler is completely + // connected. + ACE_INET_Addr addr; + + if (this->peer ().get_remote_addr (addr) == -1) + return -1; + + char client[MAXHOSTNAMELEN + 16]; + (void) addr.addr_to_string (client, sizeof (client)); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) IIOP connection from client <%s> on %d\n"), + client, this->peer ().get_handle ())); + + return 0; +} + +int +TAO_SHMIOP_Server_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_orbdebug) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Server_Connection_Handler::activate %d ") + ASYS_TEXT ("threads, flags = %d\n"), + n_threads, + flags, + THR_BOUND)); + + return TAO_SVC_HANDLER::activate (flags, + n_threads, + force_active, + priority, + grp_id, + task, + thread_handles, + stack, + stack_size, + thread_names); +} + +int +TAO_SHMIOP_Server_Connection_Handler::handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask rm) +{ + if (TAO_orbdebug) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Server_Connection_Handler::handle_close ") + ASYS_TEXT ("(%d, %d)\n"), + handle, + rm)); + + --this->refcount_; + if (this->refcount_ == 0) + return TAO_SVC_HANDLER::handle_close (handle, rm); + + return 0; +} + +int +TAO_SHMIOP_Server_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". + int result = 0; + + // Inheriting the ORB_Core tss stuff from the parent thread. + this->orb_core_->inherit_from_parent_thread (this->tss_resources_); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Server_Connection_Handler::svc 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; + } + + while (!this->orb_core_->has_shutdown () + && result >= 0) + { + result = handle_input_i (ACE_INVALID_HANDLE, max_wait_time); + if (result == -1 && errno == ETIME) + { + // Ignore timeouts, they are only used to wake up and + // shutdown. + result = 0; + } + current_timeout = timeout; + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Server_Connection_Handler::svc - ") + ASYS_TEXT ("loop <%d>\n"), current_timeout.msec ())); + } + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Server_Connection_Handler::svc end\n"))); + + return result; +} + +int +TAO_SHMIOP_Server_Connection_Handler::handle_input (ACE_HANDLE h) +{ + return this->handle_input_i (h); +} + +int +TAO_SHMIOP_Server_Connection_Handler::handle_input_i (ACE_HANDLE, + ACE_Time_Value *max_wait_time) +{ + this->refcount_++; + + int result = TAO_GIOP::handle_input (this->transport (), + this->orb_core_, + this->transport_.message_state_, + max_wait_time); + + if (result == -1 && TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) - %p\n"), + ASYS_TEXT ("SHMIOP_Server_Connection_Handler::handle_input, ") + ASYS_TEXT ("handle_input"))); + } + + if (result == 0 || result == -1) + { + --this->refcount_; + if (this->refcount_ == 0) + this->TAO_SVC_HANDLER::handle_close (); + return result; + } + + // + // Take out all the information from the <message_state> and reset + // it so that nested upcall on the same transport can be handled. + // + + // Notice that the message_state is only modified in one thread at a + // time because the reactor does not call handle_input() for the + // same Event_Handler in two threads at the same time. + + // Copy message type. + TAO_GIOP_Message_State &ms = this->transport_.message_state_; + CORBA::Octet message_type = ms.message_type; + + // Copy version. + TAO_GIOP_Version giop_version = ms.giop_version; + + // Steal the input CDR from the message state. + TAO_InputCDR input_cdr (ACE_InputCDR::Transfer_Contents (ms.cdr), + this->orb_core_); + + // Reset the message state. + this->transport_.message_state_.reset (0); + + result = TAO_GIOP::process_server_message (this->transport (), + this->orb_core_, + input_cdr, + message_type, + giop_version); + if (result != -1) + result = 0; + + --this->refcount_; + if (this->refcount_ == 0) + this->TAO_SVC_HANDLER::handle_close (); + + return result; +} + +// **************************************************************** + +// transport obj. +TAO_SHMIOP_Client_Connection_Handler:: +TAO_SHMIOP_Client_Connection_Handler (ACE_Thread_Manager *t, + TAO_ORB_Core* orb_core) + : TAO_SHMIOP_Handler_Base (t), + transport_ (this, orb_core), + orb_core_ (orb_core) +{ +} + +TAO_SHMIOP_Client_Connection_Handler::~TAO_SHMIOP_Client_Connection_Handler (void) +{ +} + +int +TAO_SHMIOP_Client_Connection_Handler::open (void *) +{ + // @@ TODO: This flags should be set using the RT CORBA policies... + + // Here is where we could enable all sorts of things such as + // nonblock I/O, sock buf sizes, TCP no-delay, etc. + +#if !defined (ACE_LACKS_SOCKET_BUFSIZ) + int sndbufsize = + this->orb_core_->orb_params ()->sock_sndbuf_size (); + int rcvbufsize = + this->orb_core_->orb_params ()->sock_rcvbuf_size (); + + if (this->peer ().set_option (SOL_SOCKET, + SO_SNDBUF, + ACE_reinterpret_cast (void *, &sndbufsize), + sizeof (sndbufsize)) == -1 + && errno != ENOTSUP) + return -1; + else if (this->peer ().set_option (SOL_SOCKET, + SO_RCVBUF, + ACE_reinterpret_cast (void *, &rcvbufsize), + sizeof (rcvbufsize)) == -1 + && errno != ENOTSUP) + return -1; +#endif /* ACE_LACKS_SOCKET_BUFSIZ */ + +#if defined (TCP_NODELAY) + int nodelay = + this->orb_core_->orb_params ()->nodelay (); + if (this->peer ().set_option (ACE_IPPROTO_TCP, + TCP_NODELAY, + (void *) &nodelay, + sizeof (nodelay)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("NODELAY failed\n")), + -1); +#endif /* TCP_NODELAY */ + + (void) this->peer ().enable (ACE_CLOEXEC); + // 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). + + // Called by the <Strategy_Acceptor> when the handler is completely + // connected. + ACE_INET_Addr addr; + + if (this->peer ().get_remote_addr (addr) == -1) + return -1; + + char server[MAXHOSTNAMELEN + 16]; + + (void) addr.addr_to_string (server, sizeof (server)); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) IIOP connection to server <%s> on %d\n"), + server, this->peer ().get_handle ())); + + // Register the handler with the Reactor if necessary. + return this->transport ()->wait_strategy ()->register_handler (); +} + +int +TAO_SHMIOP_Client_Connection_Handler::close (u_long) +{ + this->destroy (); + + return 0; +} + +int +TAO_SHMIOP_Client_Connection_Handler::handle_input (ACE_HANDLE) +{ + // Call the waiter to handle the input. + return this->transport ()->wait_strategy ()->handle_input (); +} + +int +TAO_SHMIOP_Client_Connection_Handler::handle_timeout (const ACE_Time_Value &, + const void *) +{ + // + // This method is called when buffering timer expires. + // + + // Cannot deal with errors, and therefore they are ignored. + this->transport ()->send_buffered_messages (); + + return 0; +} + +int +TAO_SHMIOP_Client_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 > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Client_Connection_Handler::") + ASYS_TEXT ("handle_close (%d, %d)\n"), handle, rm)); + + if (this->recycler ()) + this->recycler ()->mark_as_closed (this->recycling_act ()); + + // Deregister this handler with the ACE_Reactor. + return this->handle_cleanup (); +} + +int +TAO_SHMIOP_Client_Connection_Handler::handle_close_i (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 > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Client_Connection_Handler::") + ASYS_TEXT ("handle_close_i (%d, %d)\n"), handle, rm)); + + if (this->recycler ()) + this->recycler ()->mark_as_closed_i (this->recycling_act ()); + + return this->handle_cleanup (); +} + +int +TAO_SHMIOP_Client_Connection_Handler::handle_cleanup (void) +{ + // Deregister this handler with the ACE_Reactor. + if (this->reactor ()) + { + ACE_Reactor_Mask mask = + ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL; + + // Make sure there are no timers. + this->reactor ()->cancel_timer (this); + + // Remove self from reactor. + this->reactor ()->remove_handler (this, mask); + } + + this->peer ().close (); + + return 0; +} + +// **************************************************************** + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/tao/SHMIOP_Connect.h b/TAO/tao/SHMIOP_Connect.h new file mode 100644 index 00000000000..70853ef77f8 --- /dev/null +++ b/TAO/tao/SHMIOP_Connect.h @@ -0,0 +1,177 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Connect.h +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_SHMIOP_CONNECT_H +#define TAO_SHMIOP_CONNECT_H + +#include "ace/Reactor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Acceptor.h" +#include "ace/MEM_Acceptor.h" +#include "ace/Synch.h" +#include "ace/Svc_Handler.h" + +#include "tao/corbafwd.h" +#include "tao/Wait_Strategy.h" + +#include "tao/SHMIOP_Transport.h" + +// Forward Decls +class TAO_ORB_Core; +class TAO_ORB_Core_TSS_Resources; + + +typedef ACE_Svc_Handler<ACE_MEM_STREAM, ACE_NULL_SYNCH> + TAO_SVC_HANDLER; + +// **************************************************************** + +class TAO_SHMIOP_Handler_Base : public TAO_SVC_HANDLER +{ +public: + TAO_SHMIOP_Handler_Base (ACE_Thread_Manager *t); + TAO_SHMIOP_Handler_Base (TAO_ORB_Core *orb_core); + + virtual TAO_Transport *transport (void) = 0; +}; + +class TAO_Export TAO_SHMIOP_Client_Connection_Handler : public TAO_SHMIOP_Handler_Base +{ + // = TITLE + // <Svc_Handler> used on the client side and returned by the + // <TAO_CONNECTOR>. +public: + // = Intialization method. + TAO_SHMIOP_Client_Connection_Handler (ACE_Thread_Manager *t = 0, + TAO_ORB_Core* orb_core = 0); + + virtual ~TAO_SHMIOP_Client_Connection_Handler (void); + + // = <Connector> hook. + virtual int open (void *); + // Activation template method. + + // = Event Handler overloads + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + // Called when a response from a twoway invocation is available. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + // Called when buffering timer expires. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Perform appropriate closing. + + virtual int handle_close_i (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Perform appropriate closing but without grabbing any locks. + + virtual int close (u_long flags = 0); + // Object termination hook. + + virtual TAO_Transport *transport (void); + // Return the transport objects + +protected: + int handle_cleanup (void); + // This method deregisters the handler from the reactor and closes it. + + TAO_SHMIOP_Client_Transport transport_; + // Reference to the transport object, it is owned by this class. + + TAO_ORB_Core *orb_core_; + // Cached ORB Core. +}; + +// **************************************************************** + +class TAO_Export TAO_SHMIOP_Server_Connection_Handler : public TAO_SHMIOP_Handler_Base +{ + // = TITLE + // Handles requests on a single connection in a server. + +public: + TAO_SHMIOP_Server_Connection_Handler (ACE_Thread_Manager* t = 0); + TAO_SHMIOP_Server_Connection_Handler (TAO_ORB_Core *orb_core); + ~TAO_SHMIOP_Server_Connection_Handler (void); + // Constructor. + + virtual int open (void *); + // Called by the <Strategy_Acceptor> when the handler is completely + // connected. Argument is unused. + + // = Active object activation method. + virtual int activate (long flags = THR_NEW_LWP, + int n_threads = 1, + int force_active = 0, + long priority = ACE_DEFAULT_THREAD_PRIORITY, + int grp_id = -1, + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0, + void *stack[] = 0, + size_t stack_size[] = 0, + ACE_thread_t thread_names[] = 0); + + virtual int svc (void); + // Only used when the handler is turned into an active object by + // calling <activate>. This serves as the event loop in such cases. + + // = Template Methods Called by <handle_input> + + TAO_Transport *transport (void); + +protected: + + // = Event Handler overloads + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + virtual int handle_input_i (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Time_Value *max_wait_time = 0); + // Reads a message from the <peer()>, dispatching and servicing it + // appropriately. + // handle_input() just delegates on handle_input_i() which timeouts + // after <max_wait_time>, this is used in thread-per-connection to + // ensure that server threads eventually exit. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Perform appropriate closing. + +protected: + TAO_SHMIOP_Server_Transport transport_; + // @@ New transport object reference. + + TAO_ORB_Core *orb_core_; + // Cached ORB Core. + + TAO_ORB_Core_TSS_Resources *tss_resources_; + // Cached tss resources of the ORB that activated this object. + + u_long refcount_; + // Reference count, to avoid early deletes... +}; + +#if defined (__ACE_INLINE__) +#include "tao/SHMIOP_Connect.i" +#endif /* __ACE_INLINE__ */ + +#endif /* TAO_SHMIOP_CONNECT_H */ diff --git a/TAO/tao/SHMIOP_Connect.i b/TAO/tao/SHMIOP_Connect.i new file mode 100644 index 00000000000..919f4fed84b --- /dev/null +++ b/TAO/tao/SHMIOP_Connect.i @@ -0,0 +1,14 @@ +// -*- C++ -*- +// $Id$ + +ACE_INLINE TAO_Transport * +TAO_SHMIOP_Server_Connection_Handler::transport (void) +{ + return &(this->transport_); +} + +ACE_INLINE TAO_Transport * +TAO_SHMIOP_Client_Connection_Handler::transport (void) +{ + return &(this->transport_); +} diff --git a/TAO/tao/SHMIOP_Connector.cpp b/TAO/tao/SHMIOP_Connector.cpp new file mode 100644 index 00000000000..e87e9d62541 --- /dev/null +++ b/TAO/tao/SHMIOP_Connector.cpp @@ -0,0 +1,716 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +#include "tao/SHMIOP_Connector.h" +#include "tao/SHMIOP_Profile.h" +#include "tao/GIOP.h" +#include "tao/debug.h" +#include "tao/ORB_Core.h" +#include "tao/Client_Strategy_Factory.h" +#include "tao/Environment.h" +#include "ace/Auto_Ptr.h" + +ACE_RCSID(tao, SHMIOP_Connector, "$Id$") + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) +int +TAO_SHMIOP_Connector::purge_connections (void) +{ + return this->cached_connect_strategy_->purge_connections (); +} + +#define TAO_HANDLER TAO_SHMIOP_Client_Connection_Handler +#define TAO_SVC_TUPLE ACE_Svc_Tuple<TAO_HANDLER> +#define TAO_ADDR TAO_SHMIOP_Connector::TAO_IADDR +#define TAO_HASH_KEY TAO_SHMIOP_Connector::TAO_HASH_KEY +#define TAO_COMPARE_KEYS TAO_SHMIOP_Connector::TAO_COMPARE_KEYS +#define TAO_ATTRIBUTES TAO_SHMIOP_Connector::TAO_ATTRIBUTES +#define TAO_CACHED_HANDLER TAO_SHMIOP_Connector::TAO_CACHED_HANDLER +#define TAO_HASH_MAP TAO_SHMIOP_Connector::TAO_HASH_MAP +#define TAO_HASH_MAP_ITERATOR TAO_SHMIOP_Connector::TAO_HASH_MAP_ITERATOR +#define TAO_HASH_MAP_REVERSE_ITERATOR TAO_SHMIOP_Connector::TAO_HASH_MAP_REVERSE_ITERATOR +#define TAO_CACHING_UTILITY TAO_SHMIOP_Connector::TAO_CACHING_UTILITY +#define TAO_CACHING_STRATEGY TAO_SHMIOP_Connector::TAO_CACHING_STRATEGY +#define TAO_CACHED_CONNECT_STRATEGY TAO_SHMIOP_Connector::TAO_CACHED_CONNECT_STRATEGY + +typedef ACE_LRU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + TAO_SHMIOP_LRU_CACHING_STRATEGY; + +#if defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) +typedef TAO_SHMIOP_LRU_CACHING_STRATEGY + TAO_SHMIOP_CACHING_STRATEGY; +#else +typedef ACE_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + TAO_SHMIOP_CACHING_STRATEGY; +typedef ACE_LFU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + TAO_SHMIOP_LFU_CACHING_STRATEGY; +typedef ACE_FIFO_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + TAO_SHMIOP_FIFO_CACHING_STRATEGY; +typedef ACE_Null_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + TAO_SHMIOP_NULL_CACHING_STRATEGY; +typedef ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LRU_CACHING_STRATEGY> + TAO_SHMIOP_LRU_CACHING_STRATEGY_ADAPTER; +typedef ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LFU_CACHING_STRATEGY> + TAO_SHMIOP_LFU_CACHING_STRATEGY_ADAPTER; +typedef ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_FIFO_CACHING_STRATEGY> + TAO_SHMIOP_FIFO_CACHING_STRATEGY_ADAPTER; +typedef ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_NULL_CACHING_STRATEGY> + TAO_SHMIOP_NULL_CACHING_STRATEGY_ADAPTER; +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + +int +TAO_SHMIOP_Connector::make_caching_strategy (void) +{ + TAO_Resource_Factory *resource_factory = + this->orb_core_->resource_factory (); + +#if defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) + ACE_NEW_RETURN (this->caching_strategy_, + TAO_SHMIOP_CACHING_STRATEGY, + -1); +#else + switch (resource_factory->connection_caching_strategy_type ()) + { + case TAO_Resource_Factory::NOOP: + ACE_NEW_RETURN (this->caching_strategy_, + TAO_SHMIOP_NULL_CACHING_STRATEGY_ADAPTER, + -1); + break; + + default: + case TAO_Resource_Factory::LRU: + ACE_NEW_RETURN (this->caching_strategy_, + TAO_SHMIOP_LRU_CACHING_STRATEGY_ADAPTER, + -1); + break; + + case TAO_Resource_Factory::LFU: + ACE_NEW_RETURN (this->caching_strategy_, + TAO_SHMIOP_LFU_CACHING_STRATEGY_ADAPTER, + -1); + break; + + case TAO_Resource_Factory::FIFO: + ACE_NEW_RETURN (this->caching_strategy_, + TAO_SHMIOP_FIFO_CACHING_STRATEGY_ADAPTER, + -1); + break; + } + +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + + this->caching_strategy_->purge_percent (resource_factory->purge_percentage ()); + return 0; +} +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +// The TAO_Cached_Connector_Lock template instantiations are in +// Resource_Factory.cpp. + +#if !defined (TAO_USES_ROBUST_CONNECTION_MGMT) +#define TAO_SVC_TUPLE ACE_Svc_Tuple<TAO_SHMIOP_Client_Connection_Handler> +#define CACHED_CONNECT_STRATEGY ACE_Cached_Connect_Strategy<TAO_SHMIOP_Client_Connection_Handler, ACE_MEM_CONNECTOR, TAO_Cached_Connector_Lock> +#define TAO_ADDR ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> +#define TAO_HANDLER TAO_SHMIOP_Client_Connection_Handler +#define TAO_HASH_KEY ACE_Hash<TAO_ADDR> +#define TAO_COMPARE_KEYS ACE_Equal_To<TAO_ADDR> +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) || \ + defined (ACE_HAS_GNU_REPO) + +template class ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr>; +template class ACE_Auto_Basic_Array_Ptr<TAO_SHMIOP_Client_Connection_Handler*>; +template class auto_ptr<TAO_SHMIOP_Connect_Creation_Strategy>; +template class ACE_Auto_Basic_Ptr<TAO_SHMIOP_Connect_Creation_Strategy>; + +template class ACE_Node<ACE_INET_Addr>; +template class ACE_Unbounded_Stack<ACE_INET_Addr>; +template class ACE_Unbounded_Stack_Iterator<ACE_INET_Addr>; + +#if !defined (TAO_USES_ROBUST_CONNECTION_MGMT) +template class CACHED_CONNECT_STRATEGY; +template class TAO_ADDR; +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +template class ACE_Svc_Handler<ACE_MEM_STREAM, ACE_NULL_SYNCH>; +template class ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr>; +template class ACE_NOOP_Creation_Strategy<TAO_HANDLER>; +template class ACE_Concurrency_Strategy<TAO_HANDLER>; +template class ACE_Connect_Strategy<TAO_HANDLER, ACE_MEM_CONNECTOR>; +template class ACE_Connector<TAO_HANDLER, ACE_MEM_CONNECTOR>; +template class ACE_Creation_Strategy<TAO_HANDLER>; +template class ACE_Hash_Map_Entry<TAO_ADDR, TAO_HANDLER *>; +template class ACE_Hash<ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> >; +template class ACE_Equal_To<ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> >; +template class ACE_Map_Entry<ACE_HANDLE, TAO_SVC_TUPLE *>; +template class ACE_Map_Manager<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Iterator_Base<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Iterator<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX>; +template class ACE_Map_Reverse_Iterator<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX>; +template class ACE_NOOP_Concurrency_Strategy<TAO_HANDLER>; +template class ACE_Recycling_Strategy<TAO_HANDLER>; +template class ACE_Strategy_Connector<TAO_HANDLER, ACE_MEM_CONNECTOR>; +template class TAO_SVC_TUPLE; + +template class ACE_Hash_Map_Manager<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex>; +template class ACE_Hash_Map_Manager_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Bucket_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) +template class ACE_Pair<TAO_HANDLER *, TAO_ATTRIBUTES>; +template class ACE_Reference_Pair<TAO_ADDR, TAO_HANDLER *>; +template class ACE_Hash_Map_Entry<TAO_ADDR, TAO_CACHED_HANDLER>; + +template class ACE_Hash_Map_Manager<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex>; +template class ACE_Hash_Map_Manager_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Iterator_Base_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; +template class ACE_Hash_Map_Bucket_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex>; + +// = Caching_Strategy +template class ACE_Hash_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES>; + +template class ACE_LRU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY>; + +#if !defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) + +template class ACE_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY>; +template class ACE_LFU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY>; +template class ACE_FIFO_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY>; +template class ACE_Null_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY>; + +template class ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LRU_CACHING_STRATEGY>; +template class ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LFU_CACHING_STRATEGY>; +template class ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_FIFO_CACHING_STRATEGY>; +template class ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_NULL_CACHING_STRATEGY>; + +template class ACE_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP, TAO_HASH_MAP_ITERATOR, TAO_HASH_MAP_REVERSE_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES>; +template class ACE_Cache_Map_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES>; +template class ACE_Cache_Map_Reverse_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP_REVERSE_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES>; + +#else + +template class ACE_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES>; + +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + +template class ACE_Cached_Connect_Strategy_Ex<TAO_HANDLER, ACE_MEM_CONNECTOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES, TAO_Cached_Connector_Lock>; +template class ACE_Cached_Connect_Strategy<TAO_HANDLER, ACE_MEM_CONNECTOR, TAO_Cached_Connector_Lock>; + +template class ACE_Cleanup_Strategy<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP>; +template class ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP>; +template class ACE_Refcounted_Recyclable_Handler_Caching_Utility<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP, TAO_HASH_MAP_ITERATOR, TAO_ATTRIBUTES>; +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> +#pragma instantiate ACE_Auto_Basic_Array_Ptr<TAO_SHMIOP_Client_Connection_Handler*> +#pragma instantiate auto_ptr<TAO_SHMIOP_Connect_Creation_Strategy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_SHMIOP_Connect_Creation_Strategy> + +#pragma instantiate ACE_Node<ACE_INET_Addr> +#pragma instantiate ACE_Unbounded_Stack<ACE_INET_Addr> +#pragma instantiate ACE_Unbounded_Stack_Iterator<ACE_INET_Addr> + +#if !defined (TAO_USES_ROBUST_CONNECTION_MGMT) +#pragma instantiate CACHED_CONNECT_STRATEGY +#pragma instantiate TAO_ADDR +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +#pragma instantiate ACE_Svc_Handler<ACE_MEM_STREAM, ACE_NULL_SYNCH> +#pragma instantiate ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> +#pragma instantiate ACE_NOOP_Creation_Strategy<TAO_HANDLER> +#pragma instantiate ACE_Concurrency_Strategy<TAO_HANDLER> +#pragma instantiate ACE_Connect_Strategy<TAO_HANDLER, ACE_MEM_CONNECTOR> +#pragma instantiate ACE_Connector<TAO_HANDLER, ACE_MEM_CONNECTOR> +#pragma instantiate ACE_Creation_Strategy<TAO_HANDLER> +#pragma instantiate ACE_Hash_Map_Entry<TAO_ADDR, TAO_HANDLER *> +#pragma instantiate ACE_Hash<ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> > +#pragma instantiate ACE_Equal_To<ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> > +#pragma instantiate ACE_Map_Entry<ACE_HANDLE, TAO_SVC_TUPLE *> +#pragma instantiate ACE_Map_Manager<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Iterator<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE, TAO_SVC_TUPLE *, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_NOOP_Concurrency_Strategy<TAO_HANDLER> +#pragma instantiate ACE_Recycling_Strategy<TAO_HANDLER> +#pragma instantiate ACE_Strategy_Connector<TAO_HANDLER, ACE_MEM_CONNECTOR> +#pragma instantiate TAO_SVC_TUPLE + +#pragma instantiate ACE_Hash_Map_Manager<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_ADDR, TAO_HANDLER *, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Bucket_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) +#pragma instantiate ACE_Pair<TAO_HANDLER *, TAO_ATTRIBUTES> +#pragma instantiate ACE_Reference_Pair<TAO_ADDR, TAO_HANDLER *> +#pragma instantiate ACE_Hash_Map_Entry<TAO_ADDR, TAO_CACHED_HANDLER> + +#pragma instantiate ACE_Hash_Map_Manager<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Manager_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> +#pragma instantiate ACE_Hash_Map_Bucket_Iterator<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_KEY, TAO_COMPARE_KEYS, ACE_Null_Mutex> + +// = Caching_Strategy +#pragma instantiate ACE_Hash_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_KEY, TAO_COMPARE_KEYS, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES> + +#pragma instantiate ACE_LRU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + +#if !defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) + +#pragma instantiate ACE_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> +#pragma instantiate ACE_LFU_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> +#pragma instantiate ACE_FIFO_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> +#pragma instantiate ACE_Null_Caching_Strategy<TAO_ATTRIBUTES, TAO_CACHING_UTILITY> + +#pragma instantiate ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LRU_CACHING_STRATEGY> +#pragma instantiate ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_LFU_CACHING_STRATEGY> +#pragma instantiate ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_FIFO_CACHING_STRATEGY> +#pragma instantiate ACE_Caching_Strategy_Adapter<TAO_ATTRIBUTES, TAO_CACHING_UTILITY, TAO_SHMIOP_NULL_CACHING_STRATEGY> + +#pragma instantiate ACE_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP, TAO_HASH_MAP_ITERATOR, TAO_HASH_MAP_REVERSE_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES> +#pragma instantiate ACE_Cache_Map_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES> +#pragma instantiate ACE_Cache_Map_Reverse_Iterator<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP_REVERSE_ITERATOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES> + +#else + +#pragma instantiate ACE_Cache_Map_Manager<TAO_ADDR, TAO_HANDLER *, TAO_HASH_MAP, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES> + +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + +#pragma instantiate ACE_Cached_Connect_Strategy_Ex<TAO_HANDLER, ACE_MEM_CONNECTOR, TAO_CACHING_STRATEGY, TAO_ATTRIBUTES, TAO_Cached_Connector_Lock> +#pragma instantiate ACE_Cached_Connect_Strategy<TAO_HANDLER, ACE_MEM_CONNECTOR, TAO_Cached_Connector_Lock> + +#pragma instantiate ACE_Cleanup_Strategy<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP> +#pragma instantiate ACE_Refcounted_Recyclable_Handler_Cleanup_Strategy<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP> +#pragma instantiate ACE_Refcounted_Recyclable_Handler_Caching_Utility<TAO_ADDR, TAO_CACHED_HANDLER, TAO_HASH_MAP, TAO_HASH_MAP_ITERATOR, TAO_ATTRIBUTES> +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +TAO_SHMIOP_Connect_Creation_Strategy:: + TAO_SHMIOP_Connect_Creation_Strategy (ACE_Thread_Manager* t, + TAO_ORB_Core *orb_core) + : ACE_Creation_Strategy<TAO_SHMIOP_Client_Connection_Handler> (t), + orb_core_ (orb_core) +{ +} + +int +TAO_SHMIOP_Connect_Creation_Strategy::make_svc_handler + (TAO_SHMIOP_Client_Connection_Handler *&sh) +{ + if (sh == 0) + ACE_NEW_RETURN (sh, + TAO_SHMIOP_Client_Connection_Handler + (this->orb_core_->thr_mgr (), + this->orb_core_), + -1); + return 0; +} + +// **************************************************************** + +#if !defined (TAO_USES_ROBUST_CONNECTION_MGMT) +typedef ACE_Cached_Connect_Strategy<TAO_SHMIOP_Client_Connection_Handler, + ACE_MEM_CONNECTOR, + TAO_Cached_Connector_Lock> + TAO_CACHED_CONNECT_STRATEGY; +#endif /* ! TAO_USES_ROBUST_CONNECTION_MGMT */ + +TAO_SHMIOP_Connector::TAO_SHMIOP_Connector (void) + : TAO_Connector (TAO_TAG_SHMEM_PROFILE), + orb_core_ (0), + base_connector_ () +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + , + cached_connect_strategy_ (0), + caching_strategy_ (0) +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ +{ +} + +int +TAO_SHMIOP_Connector::open (TAO_ORB_Core *orb_core) +{ + this->orb_core_ = orb_core; + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + if (this->make_caching_strategy () == -1) + return -1; +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + + TAO_SHMIOP_Connect_Creation_Strategy *connect_creation_strategy = 0; + + ACE_NEW_RETURN (connect_creation_strategy, + TAO_SHMIOP_Connect_Creation_Strategy + (this->orb_core_->thr_mgr (), + this->orb_core_), + -1); + + auto_ptr<TAO_SHMIOP_Connect_Creation_Strategy> + new_connect_creation_strategy (connect_creation_strategy); + + TAO_Cached_Connector_Lock *connector_lock = 0; + ACE_NEW_RETURN (connector_lock, + TAO_Cached_Connector_Lock (this->orb_core_), + -1); + + auto_ptr<TAO_Cached_Connector_Lock> new_connector_lock (connector_lock); + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + ACE_NEW_RETURN (this->cached_connect_strategy_, + TAO_CACHED_CONNECT_STRATEGY (*this->caching_strategy_, + new_connect_creation_strategy.get (), + 0, + 0, + new_connector_lock.get (), + 1), + -1); +#else /* TAO_USES_ROBUST_CONNECTION_MGMT */ + TAO_CACHED_CONNECT_STRATEGY *cached_connect_strategy = 0; + ACE_NEW_RETURN (cached_connect_strategy, + TAO_CACHED_CONNECT_STRATEGY + (new_connect_creation_strategy.get (), + 0, + 0, + new_connector_lock.get (), + 1), + -1); +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + + // Finally everything is fine. Make sure to take ownership away + // from the auto pointer. + connect_creation_strategy = + new_connect_creation_strategy.release (); + connector_lock = + new_connector_lock.release (); + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + return this->base_connector_.open (this->orb_core_->reactor (), + &this->null_creation_strategy_, + this->cached_connect_strategy_, + &this->null_activation_strategy_); +#else /* TAO_USES_ROBUST_CONNECTION_MGMT */ + return this->base_connector_.open (this->orb_core_->reactor (), + &this->null_creation_strategy_, + cached_connect_strategy, + &this->null_activation_strategy_); +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ +} + +int +TAO_SHMIOP_Connector::close (void) +{ + this->base_connector_.close (); + + // Zap the creation strategy that we created earlier +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + delete this->cached_connect_strategy_->creation_strategy (); + delete this->cached_connect_strategy_; + delete this->caching_strategy_; +#else /* TAO_USES_ROBUST_CONNECTION_MGMT */ + TAO_CACHED_CONNECT_STRATEGY *cached_connect_strategy = + ACE_dynamic_cast (TAO_CACHED_CONNECT_STRATEGY *, + this->base_connector_.connect_strategy ()); + + delete cached_connect_strategy->creation_strategy (); + delete cached_connect_strategy; +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + + return 0; +} + +int +TAO_SHMIOP_Connector::connect (TAO_Profile *profile, + TAO_Transport *&transport, + ACE_Time_Value *max_wait_time) +{ + if (profile->tag () != TAO_TAG_SHMEM_PROFILE) + return -1; + + TAO_SHMIOP_Profile *shmiop_profile = + ACE_dynamic_cast (TAO_SHMIOP_Profile *, + profile); + if (shmiop_profile == 0) + return -1; + + const ACE_INET_Addr &oa = + shmiop_profile->object_addr (); + + ACE_Synch_Options synch_options; + if (max_wait_time != 0) + synch_options.set (ACE_Synch_Options::USE_TIMEOUT, + *max_wait_time); + + TAO_SHMIOP_Client_Connection_Handler* result; + + // The connect call will set the hint () stored in the Profile + // object; but we obtain the transport in the <result> + // variable. Other threads may modify the hint, but we are not + // affected. + if (this->base_connector_.connect (shmiop_profile->hint (), + result, + oa, + synch_options) == -1) + { // Give users a clue to the problem. + if (TAO_orbdebug) + { + char buffer [MAXNAMELEN * 2]; + profile->addr_to_string (buffer, + (MAXNAMELEN * 2) - 1); + ACE_DEBUG ((LM_ERROR, + ASYS_TEXT ("(%P|%t) %s:%u, connection to ") + ASYS_TEXT ("%s failed (%p)\n"), + __FILE__, + __LINE__, + buffer, + "errno")); + } + return -1; + } + + transport = result->transport (); + return 0; +} + +int +TAO_SHMIOP_Connector::preconnect (const char *preconnects) +{ + // Check for the proper protocol prefix. + if (this->check_prefix (preconnects) != 0) + return 0; // Failure: zero successful preconnections + + const char *protocol_removed = + ACE_OS::strstr (preconnects, + "://") + 3; + // "+ 3" since strlen of "://" is 3. + + char *preconnections = + ACE_OS::strdup (protocol_removed); + + int successes = 0; + if (preconnections) + { + ACE_INET_Addr dest; + ACE_Unbounded_Stack<ACE_INET_Addr> dests; + + size_t num_connections; + + char *nextptr = 0; + char *where = 0; + for (where = ACE::strsplit_r (preconnections, ",", nextptr); + where != 0; + where = ACE::strsplit_r (0, ",", nextptr)) + { + int version_offset = 0; + // Additional offset to remove version from preconnect, if it exists. + + if (isdigit (where[0]) && + where[1] == '.' && + isdigit (where[2]) && + where[3] == '@') + version_offset = 4; + + // @@ For now, we just drop the version prefix. However, at + // some point in the future the version may become useful. + + char *tport = 0; + char *thost = where + version_offset; + char *sep = ACE_OS::strchr (where, ':'); + + if (sep) + { + *sep = '\0'; + tport = sep + 1; + + dest.set ((u_short) ACE_OS::atoi (tport), thost); + dests.push (dest); + } + else + { + // No port was specified so assume that the port will be the + // IANA assigned port for IIOP. + // + // IIOP: 683 + // IIOP over SSL: 684 + + dest.set (683, thost); + dests.push (dest); + + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) No port specified for <%s>. ") + ASYS_TEXT ("Using <%d> as default port.\n"), + where, + dest.get_port_number ())); + } + } + } + + // Create an array of addresses from the stack, as well as an + // array of eventual handlers. + num_connections = dests.size (); + ACE_INET_Addr *remote_addrs = 0; + TAO_SHMIOP_Client_Connection_Handler **handlers = 0; + char *failures = 0; + + ACE_NEW_RETURN (remote_addrs, + ACE_INET_Addr[num_connections], + -1); + + ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_remote_addrs (remote_addrs); + + ACE_NEW_RETURN (handlers, + TAO_SHMIOP_Client_Connection_Handler *[num_connections], + -1); + + ACE_Auto_Basic_Array_Ptr<TAO_SHMIOP_Client_Connection_Handler*> + safe_handlers (handlers); + + ACE_NEW_RETURN (failures, + char[num_connections], + -1); + + // No longer need to worry about exception safety at this point. + remote_addrs = safe_remote_addrs.release (); + handlers = safe_handlers.release (); + + size_t slot = 0; + + // Fill in the remote address array + while (dests.pop (remote_addrs[slot]) == 0) + handlers[slot++] = 0; + + // Finally, try to connect. + this->base_connector_.connect_n (num_connections, + handlers, + remote_addrs, + failures); + // Loop over all the failures and set the handlers that + // succeeded to idle state. + for (slot = 0; + slot < num_connections; + slot++) + { + if (!failures[slot]) + { + handlers[slot]->idle (); + successes++; + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) Preconnection <%s:%d> ") + ASYS_TEXT ("succeeded.\n"), + remote_addrs[slot].get_host_name (), + remote_addrs[slot].get_port_number ())); + } + else if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) Preconnection <%s:%d> failed.\n"), + remote_addrs[slot].get_host_name (), + remote_addrs[slot].get_port_number ())); + } + + ACE_OS::free (preconnections); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) IIOP preconnections: %d successes and ") + ASYS_TEXT ("%d failures.\n"), + successes, + num_connections - successes)); + } + return successes; +} + +TAO_Profile * +TAO_SHMIOP_Connector::create_profile (TAO_InputCDR& cdr) +{ + TAO_Profile *pfile; + ACE_NEW_RETURN (pfile, + TAO_SHMIOP_Profile (this->orb_core_), + 0); + + int r = pfile->decode (cdr); + if (r == -1) + { + pfile->_decr_refcnt (); + pfile = 0; + } + + return pfile; +} + +void +TAO_SHMIOP_Connector::make_profile (const char *endpoint, + TAO_Profile *&profile, + CORBA::Environment &ACE_TRY_ENV) +{ + // The endpoint should be of the form: + // N.n@host:port/object_key + // or: + // host:port/object_key + + ACE_NEW_THROW_EX (profile, + TAO_SHMIOP_Profile (endpoint, + this->orb_core_, + ACE_TRY_ENV), + CORBA::NO_MEMORY ()); + + ACE_CHECK; +} + +int +TAO_SHMIOP_Connector::check_prefix (const char *endpoint) +{ + // Check for a valid string + if (!endpoint || !*endpoint) + return -1; // Failure + + const char *protocol[] = { "shmiop", "shmioploc" }; + + size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint; + + size_t len0 = ACE_OS::strlen (protocol[0]); + size_t len1 = ACE_OS::strlen (protocol[1]); + + // Check for the proper prefix in the IOR. If the proper prefix + // isn't in the IOR then it is not an IOR we can use. + if (slot == len0 + && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0) + return 0; + else if (slot == len1 + && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0) + return 0; + + return -1; + // Failure: not an IIOP IOR + // DO NOT throw an exception here. +} + +char +TAO_SHMIOP_Connector::object_key_delimiter (void) const +{ + return TAO_SHMIOP_Profile::object_key_delimiter; +} diff --git a/TAO/tao/SHMIOP_Connector.h b/TAO/tao/SHMIOP_Connector.h new file mode 100644 index 00000000000..7b1d5d9e9fe --- /dev/null +++ b/TAO/tao/SHMIOP_Connector.h @@ -0,0 +1,205 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Connector.h +// +// = DESCRIPTION +// IIOP specific connector processing +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_SHMIOP_CONNECTOR_H +#define TAO_SHMIOP_CONNECTOR_H + +#include "ace/Connector.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/MEM_Connector.h" +#include "tao/Pluggable.h" +#include "tao/SHMIOP_Connect.h" +#include "tao/Resource_Factory.h" + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) +#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 8 +#define ACE_HAS_BROKEN_EXTENDED_TEMPLATES +#endif /* __GNUC__ */ + +#include "ace/Cached_Connect_Strategy_T.h" +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +typedef ACE_Strategy_Connector<TAO_SHMIOP_Client_Connection_Handler, + ACE_MEM_CONNECTOR> + TAO_SHMIOP_BASE_CONNECTOR; + +// **************************************************************** + +class TAO_Export TAO_SHMIOP_Connect_Creation_Strategy : public ACE_Creation_Strategy<TAO_SHMIOP_Client_Connection_Handler> +{ + // = TITLE + // Helper creation strategy + // + // = DESCRIPTION + // Creates UIOP_Client_Connection_Handler objects but satisfies + // the interface required by the + // ACE_Creation_Strategy<TAO_SHMIOP_Client_Connection_Handler> + // +public: + TAO_SHMIOP_Connect_Creation_Strategy (ACE_Thread_Manager * = 0, + TAO_ORB_Core* orb_core = 0); + + virtual int make_svc_handler (TAO_SHMIOP_Client_Connection_Handler *&sh); + // Makes TAO_SHMIOP_Client_Connection_Handlers + +private: + TAO_ORB_Core* orb_core_; + // The ORB +}; + +// **************************************************************** + +class TAO_Export TAO_SHMIOP_Connector : public TAO_Connector +{ + // = TITLE + // IIOP-specific Connector bridge for pluggable protocols. + // + // = DESCRIPTION + // Concrete instance of the TAO_Connector class. Responsible + // for establishing a connection with a server and is called from the + // Connector_Registory. + // +public: + // = Initialization and termination methods. + TAO_SHMIOP_Connector (void); + // Constructor. + + // = The TAO_Connector methods, please check the documentation on + // Pluggable.h + int open (TAO_ORB_Core *orb_core); + int close (void); + int connect (TAO_Profile *profile, + TAO_Transport *&transport, + ACE_Time_Value *max_wait_time); + int preconnect (const char *preconnections); + TAO_Profile *create_profile (TAO_InputCDR& cdr); + + virtual int check_prefix (const char *endpoint); + + virtual char object_key_delimiter (void) const; + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + virtual int purge_connections (void); + // Purge "old" connections. +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +protected: + // = More TAO_Connector methods, please check the documentation on + // Pluggable.h + virtual void make_profile (const char *endpoint, + TAO_Profile *&, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()); + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + virtual int make_caching_strategy (void); + // According to the option specified, create the appropriate caching + // strategy used for purging unused connections from the connection + // cache. +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +public: + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + // = Connection Caching Strategy. + typedef size_t TAO_ATTRIBUTES; + typedef ACE_Pair<TAO_SHMIOP_Client_Connection_Handler *, + TAO_ATTRIBUTES> + TAO_CACHED_HANDLER; + typedef ACE_Refcounted_Hash_Recyclable<ACE_INET_Addr> + TAO_IADDR; + typedef ACE_Hash<TAO_IADDR> TAO_HASH_KEY; + typedef ACE_Equal_To<TAO_IADDR> TAO_COMPARE_KEYS; + + typedef ACE_Hash_Map_Manager_Ex<TAO_IADDR, + TAO_CACHED_HANDLER, + TAO_HASH_KEY, + TAO_COMPARE_KEYS, + ACE_Null_Mutex> + TAO_HASH_MAP; + typedef ACE_Hash_Map_Iterator_Ex<TAO_IADDR, + TAO_CACHED_HANDLER, + TAO_HASH_KEY, + TAO_COMPARE_KEYS, + ACE_Null_Mutex> + TAO_HASH_MAP_ITERATOR; + typedef ACE_Hash_Map_Reverse_Iterator_Ex<TAO_IADDR, + TAO_CACHED_HANDLER, + TAO_HASH_KEY, + TAO_COMPARE_KEYS, + ACE_Null_Mutex> + TAO_HASH_MAP_REVERSE_ITERATOR; + + typedef ACE_Refcounted_Recyclable_Handler_Caching_Utility<TAO_IADDR, + TAO_CACHED_HANDLER, + TAO_HASH_MAP, + TAO_HASH_MAP_ITERATOR, + TAO_ATTRIBUTES> + TAO_CACHING_UTILITY; + +#if defined (ACE_HAS_BROKEN_EXTENDED_TEMPLATES) + typedef ACE_LRU_Caching_Strategy<TAO_ATTRIBUTES, + TAO_CACHING_UTILITY> + TAO_CACHING_STRATEGY; +#else + typedef ACE_Caching_Strategy<TAO_ATTRIBUTES, + TAO_CACHING_UTILITY> + TAO_CACHING_STRATEGY; +#endif /* ACE_HAS_BROKEN_EXTENDED_TEMPLATES */ + + typedef ACE_Cached_Connect_Strategy_Ex<TAO_SHMIOP_Client_Connection_Handler, + ACE_MEM_CONNECTOR, + TAO_CACHING_STRATEGY, + TAO_ATTRIBUTES, + TAO_Cached_Connector_Lock> + TAO_CACHED_CONNECT_STRATEGY; +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + + typedef ACE_NOOP_Concurrency_Strategy<TAO_SHMIOP_Client_Connection_Handler> + TAO_NULL_ACTIVATION_STRATEGY; + + typedef ACE_NOOP_Creation_Strategy<TAO_SHMIOP_Client_Connection_Handler> + TAO_NULL_CREATION_STRATEGY; + +protected: + TAO_ORB_Core *orb_core_; + // ORB Core. + +private: + TAO_NULL_ACTIVATION_STRATEGY null_activation_strategy_; + TAO_NULL_CREATION_STRATEGY null_creation_strategy_; + + TAO_SHMIOP_BASE_CONNECTOR base_connector_; + // The connector initiating connection requests for IIOP. + +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) + TAO_CACHED_CONNECT_STRATEGY *cached_connect_strategy_; + // Cached connect strategy. + + TAO_CACHING_STRATEGY *caching_strategy_; + // Caching strategy which decides the order of removal of entries + // from the connection cache. +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ + +}; + +#endif /* TAO_SHMIOP_CONNECTOR_H */ diff --git a/TAO/tao/SHMIOP_Factory.cpp b/TAO/tao/SHMIOP_Factory.cpp new file mode 100644 index 00000000000..7a804da806c --- /dev/null +++ b/TAO/tao/SHMIOP_Factory.cpp @@ -0,0 +1,85 @@ +// $Id$ + +#include "tao/SHMIOP_Factory.h" +#include "tao/SHMIOP_Acceptor.h" +#include "tao/SHMIOP_Connector.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID(tao, SHMIOP_Factory, "$Id$") + +static const char prefix_[] = "shmiop"; + +TAO_SHMIOP_Protocol_Factory::TAO_SHMIOP_Protocol_Factory (void) + : major_ (TAO_DEF_GIOP_MAJOR), + minor_ (TAO_DEF_GIOP_MINOR) +{ +} + +TAO_SHMIOP_Protocol_Factory::~TAO_SHMIOP_Protocol_Factory (void) +{ +} + +int +TAO_SHMIOP_Protocol_Factory::match_prefix (const ACE_CString &prefix) +{ + // Check for the proper prefix for this protocol. + return (ACE_OS::strcasecmp (prefix.c_str (), ::prefix_) == 0); +} + +const char * +TAO_SHMIOP_Protocol_Factory::prefix (void) const +{ + return ::prefix_; +} + +char +TAO_SHMIOP_Protocol_Factory::options_delimiter (void) const +{ + return '/'; +} + +TAO_Acceptor * +TAO_SHMIOP_Protocol_Factory::make_acceptor (void) +{ + TAO_Acceptor *acceptor = 0; + + ACE_NEW_RETURN (acceptor, + TAO_SHMIOP_Acceptor, + 0); + + return acceptor; +} + +int +TAO_SHMIOP_Protocol_Factory::init (int /* argc */, + char* /* argv */ []) +{ + return 0; +} + +TAO_Connector * +TAO_SHMIOP_Protocol_Factory::make_connector (void) +{ + TAO_Connector *connector = 0; + + ACE_NEW_RETURN (connector, + TAO_SHMIOP_Connector, + 0); + return connector; +} + +int +TAO_SHMIOP_Protocol_Factory::requires_explicit_endpoint (void) const +{ + return 0; +} + +ACE_STATIC_SVC_DEFINE (TAO_SHMIOP_Protocol_Factory, + ASYS_TEXT ("SHMIOP_Factory"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (TAO_SHMIOP_Protocol_Factory), + ACE_Service_Type::DELETE_THIS | + ACE_Service_Type::DELETE_OBJ, + 0) + +ACE_FACTORY_DEFINE (TAO, TAO_SHMIOP_Protocol_Factory) diff --git a/TAO/tao/SHMIOP_Factory.h b/TAO/tao/SHMIOP_Factory.h new file mode 100644 index 00000000000..17abcc04dbb --- /dev/null +++ b/TAO/tao/SHMIOP_Factory.h @@ -0,0 +1,63 @@ +// -*- C++ -*- +// $Id$ +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Factory.h +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_SHMIOP_FACTORY_H +#define TAO_SHMIOP_FACTORY_H + +#include "tao/Protocol_Factory.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_Acceptor; +class TAO_Connector; + +class TAO_Export TAO_SHMIOP_Protocol_Factory : public TAO_Protocol_Factory +{ +public: + TAO_SHMIOP_Protocol_Factory (void); + virtual ~TAO_SHMIOP_Protocol_Factory (void); + + // = Service Configurator hooks. + virtual int init (int argc, char* argv[]); + // Dynamic linking hook + + virtual int match_prefix (const ACE_CString &prefix); + // Verify prefix is a match + + virtual const char *prefix (void) const; + // Returns the prefix used by the protocol. + + virtual char options_delimiter (void) const; + // Return the character used to mark where an endpoint ends and + // where its options begin. + + // = Check Protocol_Factory.h for a description of these methods. + virtual TAO_Acceptor *make_acceptor (void); + virtual TAO_Connector *make_connector (void); + virtual int requires_explicit_endpoint (void) const; + +private: + int major_; + int minor_; + // Changing the version number can be used to provide backwards + // compatibility with old clients. +}; + +ACE_STATIC_SVC_DECLARE (TAO_SHMIOP_Protocol_Factory) +ACE_FACTORY_DECLARE (TAO, TAO_SHMIOP_Protocol_Factory) + +#endif /* TAO_SHMIOP_FACTORY_H */ diff --git a/TAO/tao/SHMIOP_Profile.cpp b/TAO/tao/SHMIOP_Profile.cpp new file mode 100644 index 00000000000..fa40cc9efc7 --- /dev/null +++ b/TAO/tao/SHMIOP_Profile.cpp @@ -0,0 +1,471 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + + + +#include "tao/SHMIOP_Profile.h" +#include "tao/SHMIOP_Connect.h" +#include "tao/GIOP.h" +#include "tao/CDR.h" +#include "tao/Environment.h" +#include "tao/ORB.h" +#include "tao/ORB_Core.h" +#include "tao/POA.h" +#include "tao/debug.h" + +ACE_RCSID(tao, SHMIOP_Profile, "$Id$") + +#if !defined (__ACE_INLINE__) +# include "tao/SHMIOP_Profile.i" +#endif /* __ACE_INLINE__ */ + +static const char prefix_[] = "shmiop"; + +const char TAO_SHMIOP_Profile::object_key_delimiter = '/'; + +TAO_SHMIOP_Profile::TAO_SHMIOP_Profile (const ACE_INET_Addr &addr, + const TAO_ObjectKey &object_key, + const TAO_GIOP_Version &version, + TAO_ORB_Core *orb_core) + : TAO_Profile (TAO_TAG_SHMEM_PROFILE), + host_ (), + port_ (0), + version_ (version), + object_key_ (object_key), + object_addr_ (addr), + hint_ (0), + orb_core_ (orb_core) +{ + this->set (addr); +} + +TAO_SHMIOP_Profile::TAO_SHMIOP_Profile (const char* host, + CORBA::UShort port, + const TAO_ObjectKey &object_key, + const ACE_INET_Addr &addr, + const TAO_GIOP_Version &version, + TAO_ORB_Core *orb_core) + : TAO_Profile (TAO_TAG_SHMEM_PROFILE), + host_ (), + port_ (port), + version_ (version), + object_key_ (object_key), + object_addr_ (addr), + hint_ (0), + orb_core_ (orb_core) +{ + if (host != 0) + this->host_ = host; +} + +TAO_SHMIOP_Profile::TAO_SHMIOP_Profile (const TAO_SHMIOP_Profile &pfile) + : TAO_Profile (pfile.tag ()), + host_ (pfile.host_), + port_ (pfile.port_), + version_ (pfile.version_), + object_key_ (pfile.object_key_), + object_addr_ (pfile.object_addr_), + hint_ (pfile.hint_), + orb_core_ (pfile.orb_core_) +{ +} + +TAO_SHMIOP_Profile::TAO_SHMIOP_Profile (const char *string, + TAO_ORB_Core *orb_core, + CORBA::Environment &ACE_TRY_ENV) + : TAO_Profile (TAO_TAG_SHMEM_PROFILE), + host_ (), + port_ (0), + version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), + object_key_ (), + object_addr_ (), + hint_ (0), + orb_core_ (orb_core) +{ + parse_string (string, ACE_TRY_ENV); + ACE_CHECK; +} + +TAO_SHMIOP_Profile::TAO_SHMIOP_Profile (TAO_ORB_Core *orb_core) + : TAO_Profile (TAO_TAG_SHMEM_PROFILE), + host_ (), + port_ (0), + version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), + object_key_ (), + object_addr_ (), + hint_ (0), + orb_core_ (orb_core) +{ +} + +int +TAO_SHMIOP_Profile::set (const ACE_INET_Addr &addr) +{ + this->port_ = addr.get_port_number(); + + if (this->orb_core_->orb_params ()->use_dotted_decimal_addresses ()) + { + const char *temp = addr.get_host_addr (); + if (temp == 0) + return -1; + else + this->host_ = temp; + } + else + { + char temphost[MAXHOSTNAMELEN + 1]; + + if (addr.get_host_name (temphost, + sizeof temphost) != 0) + return -1; + + this->host_ = CORBA::string_dup (temphost); + } + + return 0; +} + +TAO_SHMIOP_Profile::~TAO_SHMIOP_Profile (void) +{ +} + +// return codes: +// -1 -> error +// 0 -> can't understand this version +// 1 -> success. +int +TAO_SHMIOP_Profile::decode (TAO_InputCDR& cdr) +{ + CORBA::ULong encap_len = cdr.length (); + + // Read and verify major, minor versions, ignoring SHMIOP + // profiles whose versions we don't understand. + // + if (!(cdr.read_octet (this->version_.major) + && this->version_.major == TAO_DEF_GIOP_MAJOR + && cdr.read_octet (this->version_.minor) + && this->version_.minor <= TAO_DEF_GIOP_MINOR)) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Profile::decode - v%d.%d\n"), + this->version_.major, + this->version_.minor)); + } + } + + // Get host and port + if (cdr.read_string (this->host_.out ()) == 0 + || cdr.read_ushort (this->port_) == 0) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Profile::decode - ") + ASYS_TEXT ("error while decoding host/port"))); + } + return -1; + } + + this->object_addr_.set (this->port_, this->host_.in ()); + + // ... and object key. + + if ((cdr >> this->object_key_) == 0) + return -1; + + // Tagged Components *only* exist after version 1.0! + // For GIOP 1.2, IIOP and GIOP have same version numbers! + if (this->version_.major > 1 + || this->version_.minor > 0) + if (this->tagged_components_.decode (cdr) == 0) + return -1; + + if (cdr.length () != 0 && TAO_debug_level) + { + // If there is extra data in the profile we are supposed to + // ignore it, but print a warning just in case... + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("%d bytes out of %d left after IIOP profile data\n"), + cdr.length (), + encap_len)); + } + + if (cdr.good_bit ()) + return 1; + + return -1; +} + +int +TAO_SHMIOP_Profile::parse_string (const char *string, + CORBA::Environment &ACE_TRY_ENV) +{ + if (!string || !*string) + { + ACE_THROW_RETURN (CORBA::INV_OBJREF ( + CORBA_SystemException::_tao_minor_code ( + TAO_NULL_POINTER_MINOR_CODE, + 0), + CORBA::COMPLETED_NO), + -1); + } + + // Remove the "N.n@" version prefix, if it exists, and verify the + // version is one that we accept. + + // Check for version + if (isdigit (string [0]) && + string[1] == '.' && + isdigit (string [2]) && + string[3] == '@') + { + // @@ This may fail for non-ascii character sets [but take that + // with a grain of salt] + this->version_.set_version ((char) (string [0] - '0'), + (char) (string [2] - '0')); + string += 4; + // Skip over the "N.n@" + } + + if (this->version_.major != TAO_DEF_GIOP_MAJOR || + this->version_.minor > TAO_DEF_GIOP_MINOR) + { + ACE_THROW_RETURN (CORBA::INV_OBJREF (), -1); + } + + // Pull off the "hostname:port/" part of the objref + // Copy the string because we are going to modify it... + CORBA::String_var copy (string); + + char *start = copy.inout (); + char *cp = ACE_OS::strchr (start, ':'); // Look for a port + + if (cp == 0) + { + // No host/port delimiter! + ACE_THROW_RETURN (CORBA::INV_OBJREF ( + CORBA_SystemException::_tao_minor_code ( + TAO_NULL_POINTER_MINOR_CODE, + 0), + CORBA::COMPLETED_NO), + -1); + } + + char *okd = ACE_OS::strchr (start, this->object_key_delimiter); + + if (okd == 0) + { + // No object key delimiter! + ACE_THROW_RETURN (CORBA::INV_OBJREF ( + CORBA_SystemException::_tao_minor_code ( + TAO_NULL_POINTER_MINOR_CODE, + 0), + CORBA::COMPLETED_NO), + -1); + } + + // Don't increment the pointer 'cp' directly since we still need + // to use it immediately after this block. + + CORBA::ULong length = okd - (cp + 1); + // Don't allocate space for the colon ':'. + + CORBA::String_var tmp = CORBA::string_alloc (length); + + ACE_OS::strncpy (tmp.inout (), cp + 1, length); + tmp[length] = '\0'; + + this->port_ = (CORBA::UShort) ACE_OS::atoi (tmp.in ()); + + length = cp - start; + + tmp = CORBA::string_alloc (length); + + ACE_OS::strncpy (tmp.inout (), start, length); + tmp[length] = '\0'; + + this->host_ = tmp._retn (); + + this->object_addr_.set (this->port_, this->host_.in ()); + + start = ++okd; // increment past the object key separator + + TAO_POA::decode_string_to_sequence (this->object_key_, start); + + return 1; +} + +CORBA::Boolean +TAO_SHMIOP_Profile::is_equivalent (const TAO_Profile *other_profile) +{ + + if (other_profile->tag () != TAO_TAG_SHMEM_PROFILE) + return 0; + + const TAO_SHMIOP_Profile *op = + ACE_dynamic_cast (const TAO_SHMIOP_Profile *, other_profile); + + ACE_ASSERT (op->object_key_.length () < UINT_MAX); + + return this->port_ == op->port_ + && this->object_key_ == op->object_key_ + && ACE_OS::strcmp (this->host_.in (), op->host_.in ()) == 0 + && this->version_ == op->version_; +} + +CORBA::ULong +TAO_SHMIOP_Profile::hash (CORBA::ULong max, + CORBA::Environment &) +{ + CORBA::ULong hashval; + + // Just grab a bunch of convenient bytes and hash them; could do + // more (hostname, full key, exponential hashing) but no real need + // to do so except if performance requires a more costly hash. + + hashval = this->object_key_.length () * this->port_; + hashval += this->version_.minor; + + if (this->object_key_.length () >= 4) + { + hashval += this->object_key_ [1]; + hashval += this->object_key_ [3]; + } + + return hashval % max; +} + +int +TAO_SHMIOP_Profile::addr_to_string (char *buffer, size_t length) +{ + size_t actual_len = + ACE_OS::strlen (this->host_.in ()) // chars in host name + + sizeof (':') // delimiter + + ACE_OS::strlen ("65536") // max port + + sizeof ('\0'); + + if (length < actual_len) + return -1; + + ACE_OS::sprintf (buffer, "%s:%d", + this->host_.in (), this->port_); + + return 0; +} + +const char * +TAO_SHMIOP_Profile::host (const char *h) +{ + this->host_ = h; + + return this->host_.in (); +} + +void +TAO_SHMIOP_Profile::reset_hint (void) +{ + if (this->hint_) + this->hint_->cleanup_hint ((void **) &this->hint_); +} + +TAO_SHMIOP_Profile & +TAO_SHMIOP_Profile::operator= (const TAO_SHMIOP_Profile &src) +{ + this->version_ = src.version_; + + this->object_key_ = src.object_key_; + + this->object_addr_.set (src.object_addr_); + + this->port_ = src.port_; + + this->host_ = src.host_; + + return *this; +} + +char * +TAO_SHMIOP_Profile::to_string (CORBA::Environment &) +{ + CORBA::String_var key; + TAO_POA::encode_sequence_to_string (key.inout(), + this->object_key ()); + + u_int buflen = (ACE_OS::strlen (::prefix_) + + 3 /* "loc" */ + + 1 /* colon separator */ + + 2 /* double-slash separator */ + + 1 /* major version */ + + 1 /* decimal point */ + + 1 /* minor version */ + + 1 /* `@' character */ + + ACE_OS::strlen (this->host_.in ()) + + 1 /* colon separator */ + + 5 /* port number */ + + 1 /* object key separator */ + + ACE_OS::strlen (key.in ())); + + char * buf = CORBA::string_alloc (buflen); + + static const char digits [] = "0123456789"; + + ACE_OS::sprintf (buf, + "%sloc://%c.%c@%s:%d%c%s", + ::prefix_, + digits [this->version_.major], + digits [this->version_.minor], + this->host_.in (), + this->port_, + this->object_key_delimiter, + key.in ()); + return buf; +} + +const char * +TAO_SHMIOP_Profile::prefix (void) +{ + return ::prefix_; +} + +int +TAO_SHMIOP_Profile::encode (TAO_OutputCDR &stream) const +{ + // UNSIGNED LONG, protocol tag + stream.write_ulong (this->tag ()); + + // Create the encapsulation.... + TAO_OutputCDR encap (ACE_CDR::DEFAULT_BUFSIZE, + TAO_ENCAP_BYTE_ORDER, + this->orb_core_->output_cdr_buffer_allocator (), + this->orb_core_->output_cdr_dblock_allocator (), + this->orb_core_->orb_params ()->cdr_memcpy_tradeoff (), + this->orb_core_->to_iso8859 (), + this->orb_core_->to_unicode ()); + + encap.write_octet (TAO_ENCAP_BYTE_ORDER); + + // The GIOP version + encap.write_octet (this->version_.major); + encap.write_octet (this->version_.minor); + + // STRING hostname from profile + encap.write_string (this->host_.in ()); + + // UNSIGNED SHORT port number + encap.write_ushort (this->port_); + + // OCTET SEQUENCE for object key + encap << this->object_key_; + + if (this->version_.major > 1 + || this->version_.minor > 0) + this->tagged_components ().encode (encap); + + // write the encapsulation as an octet sequence... + stream << CORBA::ULong (encap.total_length ()); + stream.write_octet_array_mb (encap.begin ()); + + return 1; +} diff --git a/TAO/tao/SHMIOP_Profile.h b/TAO/tao/SHMIOP_Profile.h new file mode 100644 index 00000000000..56da8c14d58 --- /dev/null +++ b/TAO/tao/SHMIOP_Profile.h @@ -0,0 +1,184 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Profile.h +// +// = DESCRIPTION +// SHMIOP profile specific processing +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_SHMIOP_PROFILE_H +#define TAO_SHMIOP_PROFILE_H + +#include "tao/Profile.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/ORB.h" +#include "tao/Object_KeyC.h" +#include "tao/GIOP.h" + +#include "ace/Synch.h" +#include "ace/INET_Addr.h" + +class TAO_SHMIOP_Client_Connection_Handler; + +// TAO SHMIOP_Profile concrete Profile definitions +class TAO_Export TAO_SHMIOP_Profile : public TAO_Profile +{ + // = TITLE + // This class defines the protocol specific attributes required + // for locating local ORBs over local IPC mechanism to use the + // shared memory transport. + // = DESCRIPTION + // This class defines the SHMIOP profile. +public: + static const char object_key_delimiter; + virtual const char get_object_key_delimiter (void); + // The object key delimiter that SHMIOP uses or expects. + + static const char *prefix (void); + // Return the char string prefix. + + TAO_SHMIOP_Profile (const ACE_INET_Addr &addr, + const TAO_ObjectKey &object_key, + const TAO_GIOP_Version &version, + TAO_ORB_Core *orb_core); + // Profile constructor, same as above except the object_key has + // already been marshaled. + + TAO_SHMIOP_Profile (const char *host, + CORBA::UShort port, + const TAO_ObjectKey &object_key, + const ACE_INET_Addr &addr, + const TAO_GIOP_Version &version, + TAO_ORB_Core *orb_core); + // Profile constructor, this is the most efficient since it + // doesn't require any address resolution processing. + + TAO_SHMIOP_Profile (const char *string, + TAO_ORB_Core *orb_core, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()); + // Create object using a string ior. + + TAO_SHMIOP_Profile (const TAO_SHMIOP_Profile &pfile); + // Profile copy constructor + + TAO_SHMIOP_Profile &operator= (const TAO_SHMIOP_Profile &src); + // Copy operator. + + TAO_SHMIOP_Profile (TAO_ORB_Core *orb_core); + // Profile constructor, default. + + ~TAO_SHMIOP_Profile (void); + // Destructor is to be called only through <_decr_refcnt>. + + int parse_string (const char *string, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()); + // Initialize this object using the given input string. + + char * to_string (CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()); + // Return a string representation for this profile. + // client must deallocate memory. + + int decode (TAO_InputCDR& cdr); + // Initialize this object using the given CDR octet string. + + virtual int encode (TAO_OutputCDR &stream) const; + // Encode this profile in a stream, i.e. marshal it. + + const TAO_ObjectKey &object_key (void) const; + // @@ deprecated, return a reference to the Object Key. + + TAO_ObjectKey &object_key (TAO_ObjectKey& objkey); + // @@ deprecated. set the Object Key. + + TAO_ObjectKey *_key (void) const; + // Return a pointer to the Object Key. + + CORBA::Boolean is_equivalent (const TAO_Profile *other_profile); + // Return true if this profile is equivalent to other_profile. Two + // profiles are equivalent iff their key, port, host, object_key and + // version are the same. + + CORBA::ULong hash (CORBA::ULong max, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()); + // Return a hash value for this object. + + int addr_to_string (char *buffer, size_t length); + // Return a string representation for the address. + + const ACE_INET_Addr &object_addr (void) const; + // return a reference to the object_addr. + + const char *host (void); + // Return a pointer to the host string. This object maintains + // ownership of this string. + + const char *host (const char *h); + // Copy the string h into host and return the resulting pointer. + // This object maintains ownership of this string. + + CORBA::UShort port (void); + // Return the port number. + + CORBA::UShort port (CORBA::UShort p); + // Set the port number. + + const TAO_GIOP_Version& version (void) const; + // Return a pointer to this profile's version. This object + // maintains ownership. + + TAO_SHMIOP_Client_Connection_Handler *&hint (void); + // This is a hint for which connection handler to use. + + void reset_hint (void); + // Reset the hint's value. + +private: + int set (const ACE_INET_Addr &addr); + // helper method to set the INET_Addr. + +private: + + CORBA::String_var host_; + // String representing the hosts name. + + CORBA::UShort port_; + // TCP port number + + TAO_GIOP_Version version_; + // GIOP version number. + + TAO_ObjectKey object_key_; + // object_key associated with this profile. + + ACE_INET_Addr object_addr_; + // Cached instance of <ACE_INET_Addr> for use in making + // invocations, etc. + + TAO_SHMIOP_Client_Connection_Handler *hint_; + // Pointer to a connection handler which we successfully used + // already. + + TAO_ORB_Core *orb_core_; + // ORB Core. +}; + +#if defined (__ACE_INLINE__) +# include "tao/SHMIOP_Profile.i" +#endif /* __ACE_INLINE__ */ + +#endif /* TAO_SHMIOP_PROFILE_H */ diff --git a/TAO/tao/SHMIOP_Profile.i b/TAO/tao/SHMIOP_Profile.i new file mode 100644 index 00000000000..612a042b8dc --- /dev/null +++ b/TAO/tao/SHMIOP_Profile.i @@ -0,0 +1,69 @@ +// -*- C++ -*- +// $Id$ + +ACE_INLINE const char +TAO_SHMIOP_Profile::get_object_key_delimiter (void) +{ + return TAO_SHMIOP_Profile::object_key_delimiter; +} + +ACE_INLINE const TAO_ObjectKey & +TAO_SHMIOP_Profile::object_key (void) const +{ + return this->object_key_; +} + +ACE_INLINE TAO_ObjectKey & +TAO_SHMIOP_Profile::object_key (TAO_ObjectKey& objkey) +{ + this->object_key_ = objkey; + return this->object_key_; +} + +ACE_INLINE TAO_ObjectKey * +TAO_SHMIOP_Profile::_key (void) const +{ + TAO_ObjectKey *key = 0; + + ACE_NEW_RETURN (key, + TAO_ObjectKey (this->object_key_), + 0); + + return key; +} + +ACE_INLINE const ACE_INET_Addr& +TAO_SHMIOP_Profile::object_addr (void) const +{ + return this->object_addr_; +} + +ACE_INLINE const char * +TAO_SHMIOP_Profile::host (void) +{ + return this->host_.in (); +} + +ACE_INLINE CORBA::UShort +TAO_SHMIOP_Profile::port (void) +{ + return this->port_; +} + +ACE_INLINE CORBA::UShort +TAO_SHMIOP_Profile::port (CORBA::UShort p) +{ + return this->port_ = p; +} + +ACE_INLINE const TAO_GIOP_Version & +TAO_SHMIOP_Profile::version (void) const +{ + return this->version_; +} + +ACE_INLINE TAO_SHMIOP_Client_Connection_Handler *& +TAO_SHMIOP_Profile::hint(void) +{ + return this->hint_; +} diff --git a/TAO/tao/SHMIOP_Transport.cpp b/TAO/tao/SHMIOP_Transport.cpp new file mode 100644 index 00000000000..520e1775fbe --- /dev/null +++ b/TAO/tao/SHMIOP_Transport.cpp @@ -0,0 +1,377 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +#include "tao/SHMIOP_Transport.h" +#include "tao/SHMIOP_Connect.h" +#include "tao/SHMIOP_Profile.h" +#include "tao/Timeprobe.h" +#include "tao/CDR.h" +#include "tao/Transport_Mux_Strategy.h" +#include "tao/Wait_Strategy.h" +#include "tao/Sync_Strategies.h" +#include "tao/Stub.h" +#include "tao/ORB_Core.h" +#include "tao/debug.h" + +#if defined (ACE_ENABLE_TIMEPROBES) + +static const char *TAO_Transport_Timeprobe_Description[] = + { + "SHMIOP_Transport::send - start", + "SHMIOP_Transport::send - end", + + "SHMIOP_Transport::receive - start", + "SHMIOP_Transport::receive - end", + + "SHMIOP_Client_Transport::start_request - start", + "SHMIOP_Client_Transport::start_request - end" + }; + +enum + { + TAO_SHMIOP_TRANSPORT_SEND_START = 1200, + TAO_SHMIOP_TRANSPORT_SEND_END, + + TAO_SHMIOP_TRANSPORT_RECEIVE_START, + TAO_SHMIOP_TRANSPORT_RECEIVE_END, + + TAO_SHMIOP_CLIENT_TRANSPORT_START_REQUEST_START, + TAO_SHMIOP_CLIENT_TRANSPORT_START_REQUEST_END + }; + + +// Setup Timeprobes +ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Transport_Timeprobe_Description, + TAO_SHMIOP_TRANSPORT_SEND_START); + +#endif /* ACE_ENABLE_TIMEPROBES */ + +TAO_SHMIOP_Transport::TAO_SHMIOP_Transport (TAO_SHMIOP_Handler_Base *handler, + TAO_ORB_Core *orb_core) + : TAO_Transport (TAO_TAG_SHMEM_PROFILE, + orb_core), + handler_ (handler) +{ +} + +TAO_SHMIOP_Transport::~TAO_SHMIOP_Transport (void) +{ + // Cannot deal with errors, and therefore they are ignored. + this->send_buffered_messages (); + + // Note that it also doesn't matter how much of the data was + // actually sent. + this->dequeue_all (); +} + +TAO_SHMIOP_Handler_Base *& +TAO_SHMIOP_Transport::handler (void) +{ + return this->handler_; +} + +int +TAO_SHMIOP_Transport::idle (void) +{ + return this->handler_->idle(); +} + +void +TAO_SHMIOP_Transport::close_connection (void) +{ + this->handler_->handle_close (); +} + +ACE_HANDLE +TAO_SHMIOP_Transport::handle (void) +{ + return this->handler_->get_handle (); +} + +ACE_Event_Handler * +TAO_SHMIOP_Transport::event_handler (void) +{ + return this->handler_; +} + +// **************************************************************** + +TAO_SHMIOP_Server_Transport:: + TAO_SHMIOP_Server_Transport (TAO_SHMIOP_Server_Connection_Handler *handler, + TAO_ORB_Core* orb_core) + : TAO_SHMIOP_Transport (handler, orb_core), + server_handler_ (handler), + message_state_ (orb_core) +{ +} + +TAO_SHMIOP_Server_Transport::~TAO_SHMIOP_Server_Transport (void) +{ +} + +// **************************************************************** + +TAO_SHMIOP_Client_Transport:: + TAO_SHMIOP_Client_Transport (TAO_SHMIOP_Client_Connection_Handler *handler, + TAO_ORB_Core *orb_core) + : TAO_SHMIOP_Transport (handler, + orb_core), + client_handler_ (handler) +{ +} + +TAO_SHMIOP_Client_Transport::~TAO_SHMIOP_Client_Transport (void) +{ +} + +TAO_SHMIOP_Client_Connection_Handler * +TAO_SHMIOP_Client_Transport::client_handler (void) +{ + return this->client_handler_; +} + +void +TAO_SHMIOP_Client_Transport::start_request (TAO_ORB_Core *orb_core, + const TAO_Profile* pfile, + TAO_OutputCDR &output, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TAO_FUNCTION_PP_TIMEPROBE (TAO_SHMIOP_CLIENT_TRANSPORT_START_REQUEST_START); + + const TAO_SHMIOP_Profile* profile = + ACE_dynamic_cast(const TAO_SHMIOP_Profile*, pfile); + + // @@ This should be implemented in the transport object, which + // would query the profile to obtain the version... + if (TAO_GIOP::start_message (profile->version (), + TAO_GIOP::Request, + output, + orb_core) == 0) + ACE_THROW (CORBA::MARSHAL ()); +} + +void +TAO_SHMIOP_Client_Transport::start_locate (TAO_ORB_Core *orb_core, + const TAO_Profile* pfile, + CORBA::ULong request_id, + TAO_OutputCDR &output, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + const TAO_SHMIOP_Profile* profile = + ACE_dynamic_cast(const TAO_SHMIOP_Profile*, pfile); + + // Obtain object key. + const TAO_ObjectKey& key = profile->object_key (); + + // @@ This should be implemented in the transport object, which + // would query the profile to obtain the version... + if (TAO_GIOP::start_message (profile->version (), + TAO_GIOP::LocateRequest, + output, + orb_core) == 0) + ACE_THROW (CORBA::MARSHAL ()); + + + if (TAO_GIOP::write_locate_request_header (request_id, + key, + output) == 0) + ACE_THROW (CORBA::MARSHAL ()); +} + +int +TAO_SHMIOP_Client_Transport::send_request (TAO_Stub *stub, + TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int two_way, + ACE_Time_Value *max_wait_time) +{ + if (this->ws_->sending_request (orb_core, + two_way) == -1) + return -1; + + if (TAO_GIOP::send_message (this, + stream, + orb_core, + max_wait_time, + stub) == -1) + return -1; + + return this->idle_after_send (); +} + +// Return 0, when the reply is not read fully, 1 if it is read fully. +// @@ This code should go in the TAO_Transport class is repeated for +// each transport!! +int +TAO_SHMIOP_Client_Transport::handle_client_input (int /* block */, + ACE_Time_Value *max_wait_time) +{ + + // Notice that the message_state is only modified in one thread at a + // time because the reactor does not call handle_input() for the + // same Event_Handler in two threads at the same time. + + // Get the message state from the Transport Mux Strategy. + TAO_GIOP_Message_State* message_state = + this->tms_->get_message_state (); + + if (message_state == 0) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) SHMIOP_Transport::handle_client_input -") + ASYS_TEXT (" nil message state\n"))); + return -1; + } + + int result = TAO_GIOP::handle_input (this, + this->orb_core_, + *message_state, + max_wait_time); + if (result == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) - %p\n"), + ASYS_TEXT ("SHMIOP_Transport::handle_client_input, handle_input"))); + return -1; + } + if (result == 0) + return result; + + // OK, the complete message is here... + + IOP::ServiceContextList reply_ctx; + CORBA::ULong request_id; + CORBA::ULong reply_status; + + result = TAO_GIOP::parse_reply (this, + this->orb_core_, + *message_state, + reply_ctx, + request_id, + reply_status); + if (result == -1) + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + ASYS_TEXT ("TAO (%P|%t) - %p\n"), + ASYS_TEXT ("SHMIOP_Transport::handle_client_input, parse reply"))); + message_state->reset (); + return -1; + } + + result = + this->tms_->dispatch_reply (request_id, + reply_status, + message_state->giop_version, + reply_ctx, + message_state); + + if (result == -1) + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + ASYS_TEXT ("TAO (%P|%t) : SHMIOP_Client_Transport::") + ASYS_TEXT ("handle_client_input - ") + ASYS_TEXT ("dispatch reply failed\n"))); + message_state->reset (); + return -1; + } + + if (result == 0) + { + message_state->reset (); + return 0; + } + + // This is a NOOP for the Exclusive request case, but it actually + // destroys the stream in the muxed case. + this->tms_->destroy_message_state (message_state); + + return result; +} + +int +TAO_SHMIOP_Client_Transport::register_handler (void) +{ + // @@ It seems like this method should go away, the right reactor is + // picked at object creation time. + ACE_Reactor *r = this->orb_core ()->reactor (); + if (r == this->client_handler ()->reactor ()) + return 0; + + return r->register_handler (this->client_handler (), + ACE_Event_Handler::READ_MASK); +} + +// ********************************************************************* + +ssize_t +TAO_SHMIOP_Transport::send (TAO_Stub *stub, + const ACE_Message_Block *message_block, + const ACE_Time_Value *max_wait_time) +{ + if (stub == 0) + { + return this->send (message_block, + max_wait_time); + } + else + { + TAO_Sync_Strategy &sync_strategy = stub->sync_strategy (); + + return sync_strategy.send (*this, + *stub, + message_block, + max_wait_time); + } +} + +ssize_t +TAO_SHMIOP_Transport::send (const ACE_Message_Block *message_block, + const ACE_Time_Value *max_wait_time) +{ + TAO_FUNCTION_PP_TIMEPROBE (TAO_SHMIOP_TRANSPORT_SEND_START); + + return ACE::send_n (this->handle (), + message_block, + max_wait_time); +} + +ssize_t +TAO_SHMIOP_Transport::send (const u_char *buf, + size_t len, + const ACE_Time_Value *max_wait_time) +{ + TAO_FUNCTION_PP_TIMEPROBE (TAO_SHMIOP_TRANSPORT_SEND_START); + + return this->handler_->peer ().send_n (buf, + len, + max_wait_time); +} + +ssize_t +TAO_SHMIOP_Transport::recv (char *buf, + size_t len, + const ACE_Time_Value *max_wait_time) +{ + TAO_FUNCTION_PP_TIMEPROBE (TAO_SHMIOP_TRANSPORT_RECEIVE_START); + + return this->handler_->peer ().recv_n (buf, + len, + max_wait_time); +} + +// Default action to be taken for send request. +int +TAO_SHMIOP_Transport::send_request (TAO_Stub *, + TAO_ORB_Core * /* orb_core */, + TAO_OutputCDR & /* stream */, + int /* twoway */, + ACE_Time_Value * /* max_wait_time */) +{ + return -1; +} diff --git a/TAO/tao/SHMIOP_Transport.h b/TAO/tao/SHMIOP_Transport.h new file mode 100644 index 00000000000..f5a8fbabf18 --- /dev/null +++ b/TAO/tao/SHMIOP_Transport.h @@ -0,0 +1,166 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// SHMIOP_Transport.h +// +// = DESCRIPTION +// IIOP Transport specific processing +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_SHMIOP_TRANSPORT_H +#define TAO_SHMIOP_TRANSPORT_H + +#include "tao/Pluggable.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/GIOP.h" + +// Forward decls. +class TAO_SHMIOP_Handler_Base; +class TAO_SHMIOP_Client_Connection_Handler; +class TAO_SHMIOP_Server_Connection_Handler; +class TAO_ORB_Core; + +class TAO_Export TAO_SHMIOP_Transport : public TAO_Transport +{ + // = TITLE + // This class acts as a bridge class to the transport specific + // connection handler (handler_). + // + // = DESCRIPTION + // Specialization of the base TAO_Transport class to handle the IIOP + // protocol. This class in turn will be further specialized for + // the client and server side. +public: + TAO_SHMIOP_Transport (TAO_SHMIOP_Handler_Base *handler, + TAO_ORB_Core *orb_core); + // Base object's creator method. + + ~TAO_SHMIOP_Transport (void); + // Default destructor. + + TAO_SHMIOP_Handler_Base *&handler (void); + // Return a reference to the corresponding connection handler. + + // = The TAO_Transport methods, please check the documentation in + // "tao/Pluggable.h" for more details. + virtual void close_connection (void); + virtual int idle (void); + virtual ACE_HANDLE handle (void); + virtual ACE_Event_Handler *event_handler (void); + virtual ssize_t send (TAO_Stub *stub, + const ACE_Message_Block *mblk, + const ACE_Time_Value *s = 0); + virtual ssize_t send (const ACE_Message_Block *mblk, + const ACE_Time_Value *s = 0); + virtual ssize_t send (const u_char *buf, + size_t len, + const ACE_Time_Value *s = 0); + virtual ssize_t recv (char *buf, + size_t len, + const ACE_Time_Value *s = 0); + virtual int send_request (TAO_Stub *stub, + TAO_ORB_Core *orb_core , + TAO_OutputCDR &stream, + int twoway, + ACE_Time_Value *max_wait_time); + +protected: + TAO_SHMIOP_Handler_Base *handler_; + // the connection service handler used for accessing lower layer + // communication protocols. +}; + +class TAO_Export TAO_SHMIOP_Client_Transport : public TAO_SHMIOP_Transport +{ + // = TITLE + // The Transport class used for Client side communication with a + // server. + // + // = DESCRIPTION + // Specialization of the TAO_SHMIOP_Transport class for client + // side. Methods related to sending one and two way requests + // lives here. +public: + TAO_SHMIOP_Client_Transport (TAO_SHMIOP_Client_Connection_Handler *handler, + TAO_ORB_Core *orb_core); + // Constructor. Note, TAO_SHMIOP_Handler_Base is the base class for + // both TAO_SHMIOP_Client_Connection_Handler and + // TAO_SHMIOP_Server_Connection_Handler. + + ~TAO_SHMIOP_Client_Transport (void); + // destructor + + TAO_SHMIOP_Client_Connection_Handler *client_handler (void); + // return a pointer to the client's connection handler. + + // = The TAO_Transport methods, please check the documentation in + // "tao/Pluggable.h" for more details. + virtual void start_request (TAO_ORB_Core *orb_core, + const TAO_Profile *profile, + TAO_OutputCDR &output, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void start_locate (TAO_ORB_Core *orb_core, + const TAO_Profile *profile, + CORBA::ULong request_id, + TAO_OutputCDR &output, + CORBA::Environment &ACE_TRY_ENV = TAO_default_environment ()) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual int send_request (TAO_Stub *stub, + TAO_ORB_Core *orb_core, + TAO_OutputCDR &stream, + int twoway, + ACE_Time_Value *max_wait_time); + virtual int handle_client_input (int block = 0, + ACE_Time_Value *max_time_value = 0); + virtual int register_handler (void); + +private: + TAO_SHMIOP_Client_Connection_Handler *client_handler_; + // pointer to the corresponding client side connection handler. +}; + +// **************************************************************** + +class TAO_Export TAO_SHMIOP_Server_Transport : public TAO_SHMIOP_Transport +{ + // = TITLE + // The Transport class used for server communication with a + // connected client. + // + // = DESCRIPTION + // Specialization of the TAO_SHMIOP_Transport class for the server side. + // methods for reading messages (requests) and sending replies live + // here. +public: + + TAO_SHMIOP_Server_Transport (TAO_SHMIOP_Server_Connection_Handler *handler, + TAO_ORB_Core *orb_core); + // Default creator method. + + ~TAO_SHMIOP_Server_Transport (void); + // Default destructor + + TAO_SHMIOP_Server_Connection_Handler *server_handler_; + // Pointer to the corresponding connection handler. + + TAO_GIOP_Message_State message_state_; + // This keep the state of the current message, to enable + // non-blocking reads, fragment reassembly, etc. +}; + +#endif /* TAO_SHMIOP_TRANSPORT_H */ diff --git a/TAO/tao/TAO.dsp b/TAO/tao/TAO.dsp index 6d07a464b35..9dd92c0fc3d 100644 --- a/TAO/tao/TAO.dsp +++ b/TAO/tao/TAO.dsp @@ -2266,6 +2266,120 @@ SOURCE=.\Services.cpp # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connector.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Factory.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Transport.cpp
+
+!IF "$(CFG)" == "TAO DLL - Win32 Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Release"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 Alpha Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Debug"
+
+!ELSEIF "$(CFG)" == "TAO DLL - Win32 MFC Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.cpp
!IF "$(CFG)" == "TAO DLL - Win32 Release"
@@ -3192,6 +3306,30 @@ SOURCE=.\Services.h # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connector.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Factory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Transport.h
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.h
# End Source File
# Begin Source File
@@ -3289,7 +3427,7 @@ SOURCE=.\WrongTransactionC.h # End Group
# Begin Group "Inline Files"
-# PROP Default_Filter "*.i"
+# PROP Default_Filter "i"
# Begin Source File
SOURCE=.\Acceptor_Registry.i
@@ -3560,6 +3698,18 @@ SOURCE=.\Services.i # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.i
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.i
# End Source File
# Begin Source File
diff --git a/TAO/tao/TAO_Static.dsp b/TAO/tao/TAO_Static.dsp index 3974778253c..665650578f7 100644 --- a/TAO/tao/TAO_Static.dsp +++ b/TAO/tao/TAO_Static.dsp @@ -502,6 +502,30 @@ SOURCE=.\Services.cpp # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Factory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Transport.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.cpp
# End Source File
# Begin Source File
@@ -1026,6 +1050,30 @@ SOURCE=.\Services.h # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connector.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Factory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Transport.h
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.h
# End Source File
# Begin Source File
@@ -1378,6 +1426,18 @@ SOURCE=.\Services.i # End Source File
# Begin Source File
+SOURCE=.\SHMIOP_Acceptor.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Connect.i
+# End Source File
+# Begin Source File
+
+SOURCE=.\SHMIOP_Profile.i
+# End Source File
+# Begin Source File
+
SOURCE=.\Single_Reactor.i
# End Source File
# Begin Source File
diff --git a/TAO/tao/corbafwd.h b/TAO/tao/corbafwd.h index 0c4b93b126e..de893b9307c 100644 --- a/TAO/tao/corbafwd.h +++ b/TAO/tao/corbafwd.h @@ -1705,7 +1705,7 @@ TAO_NAMESPACE_CLOSE // end of class (namespace) CORBA // @@ The values below are suggestions for some of the protocols // we have thought of, subject to change at any point // #define TAO_TAG_AIOP_PROFILE 0x54414f01U /* ATM/AAL5 */ -// #define TAO_TAG_SHMEM_PROFILE 0x54414f02U /* Shared memory */ +#define TAO_TAG_SHMEM_PROFILE 0x54414f02U /* Shared memory */ // #define TAO_TAG_MSGQ_PROFILE 0x54414f03U /* Message Queue */ // #define TAO_TAG_UDP_PROFILE 0x54414f04U /* UDP */ // #define TAO_TAG_MCAST_PROFILE 0x54414f05U /* IP/Multicast */ @@ -1632,6 +1632,11 @@ private: ACE_Time_Value *max_wait_time_; # define ACE_SOCK_CONNECTOR ACE_SOCK_Connector # define ACE_SOCK_STREAM ACE_SOCK_Stream +// Handle ACE_SOCK_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor +# define ACE_MEM_CONNECTOR ACE_MEM_Connector +# define ACE_MEM_STREAM ACE_MEM_Stream + // Handle ACE_LSOCK_* # define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor # define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector @@ -1708,6 +1713,11 @@ private: ACE_Time_Value *max_wait_time_; # define ACE_SOCK_CONNECTOR ACE_SOCK_Connector, ACE_INET_Addr # define ACE_SOCK_STREAM ACE_SOCK_Stream, ACE_INET_Addr +// Handle ACE_SOCK_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor, ACE_INET_Addr +# define ACE_MEM_CONNECTOR ACE_MEM_Connector, ACE_INET_Addr +# define ACE_MEM_STREAM ACE_MEM_Stream, ACE_INET_Addr + // Handle ACE_LSOCK_* # define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor, ACE_UNIX_Addr # define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector, ACE_UNIX_Addr @@ -5332,11 +5342,11 @@ public: // = Get/set the provider specific information. iovec provider_specific (void) const; void provider_specific (const iovec &ps); - + #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) #else private: - + ACE_Flow_Spec sending_flowspec_; ACE_Flow_Spec receiving_flowspec_; #endif |