summaryrefslogtreecommitdiff
path: root/TAO/tao/Strategies
diff options
context:
space:
mode:
authorfhunleth <fhunleth@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-07-03 23:53:23 +0000
committerfhunleth <fhunleth@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-07-03 23:53:23 +0000
commit90b1277ac1378475a80fdc189fc590204250defc (patch)
tree0e2aaed80c78b3013593d0465f5963e2100d404f /TAO/tao/Strategies
parentc36a729e5ea2409d1ef6344c45699cc1d95a7ab9 (diff)
downloadATCD-90b1277ac1378475a80fdc189fc590204250defc.tar.gz
ChangeLogTag:Tue Jul 3 18:25:41 2001 Frank Hunleth <fhunleth@cs.wustl.edu>
Diffstat (limited to 'TAO/tao/Strategies')
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.cpp760
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.h186
-rw-r--r--TAO/tao/Strategies/DIOP_Acceptor.i23
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.cpp402
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.h194
-rw-r--r--TAO/tao/Strategies/DIOP_Connection_Handler.i3
-rw-r--r--TAO/tao/Strategies/DIOP_Connector.cpp276
-rw-r--r--TAO/tao/Strategies/DIOP_Connector.h103
-rw-r--r--TAO/tao/Strategies/DIOP_Endpoint.cpp192
-rw-r--r--TAO/tao/Strategies/DIOP_Endpoint.h144
-rw-r--r--TAO/tao/Strategies/DIOP_Endpoint.i52
-rw-r--r--TAO/tao/Strategies/DIOP_Factory.cpp90
-rw-r--r--TAO/tao/Strategies/DIOP_Factory.h72
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.cpp677
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.h206
-rw-r--r--TAO/tao/Strategies/DIOP_Profile.i24
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.cpp546
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.h148
-rw-r--r--TAO/tao/Strategies/DIOP_Transport.i2
-rw-r--r--TAO/tao/Strategies/Makefile7
-rw-r--r--TAO/tao/Strategies/Makefile.bor7
-rw-r--r--TAO/tao/Strategies/TAO_Strategies_Internal.cpp7
-rw-r--r--TAO/tao/Strategies/advanced_resource.cpp72
23 files changed, 4191 insertions, 2 deletions
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.cpp b/TAO/tao/Strategies/DIOP_Acceptor.cpp
new file mode 100644
index 00000000000..0cb8f29f33d
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Acceptor.cpp
@@ -0,0 +1,760 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+#include "DIOP_Acceptor.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "DIOP_Profile.h"
+#include "tao/MProfile.h"
+#include "tao/ORB_Core.h"
+#include "tao/debug.h"
+#include "tao/Protocols_Hooks.h"
+
+#include "ace/Auto_Ptr.h"
+
+#if !defined(__ACE_INLINE__)
+#include "DIOP_Acceptor.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(tao, DIOP_Acceptor, "$Id$")
+
+
+TAO_DIOP_Acceptor::TAO_DIOP_Acceptor (CORBA::Boolean flag)
+ : TAO_Acceptor (TAO_TAG_UDP_PROFILE),
+ addrs_ (0),
+ hosts_ (0),
+ endpoint_count_ (0),
+ version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
+ orb_core_ (0),
+ lite_flag_ (flag),
+ connection_handler_ (0)
+{
+}
+
+TAO_DIOP_Acceptor::~TAO_DIOP_Acceptor (void)
+{
+ // Make sure we are closed before we start destroying the
+ // strategies.
+ this->close ();
+
+ delete [] this->addrs_;
+
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ CORBA::string_free (this->hosts_[i]);
+
+ delete [] this->hosts_;
+}
+
+// TODO =
+// 2) For V1.[1,2] there are tagged components
+
+int
+TAO_DIOP_Acceptor::create_mprofile (const TAO_ObjectKey & object_key,
+ TAO_MProfile &mprofile,
+ CORBA::Boolean share_profile)
+{
+ // Sanity check.
+ if (this->endpoint_count_ == 0)
+ return -1;
+
+ // Check if multiple endpoints should be put in one profile or
+ // if they should be spread across multiple profiles.
+ if (share_profile == 1)
+ return this->create_shared_profile (object_key,
+ mprofile);
+ else
+ return this->create_new_profiles (object_key,
+ mprofile);
+}
+
+int
+TAO_DIOP_Acceptor::create_new_profiles (const TAO_ObjectKey &object_key,
+ TAO_MProfile &mprofile)
+{
+ // Adding this->endpoint_count_ to the TAO_MProfile.
+ int count = mprofile.profile_count ();
+ if ((mprofile.size () - count) < this->endpoint_count_
+ && mprofile.grow (count + this->endpoint_count_) == -1)
+ return -1;
+
+ // Create a profile for each acceptor endpoint.
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ TAO_DIOP_Profile *pfile = 0;
+ ACE_NEW_RETURN (pfile,
+ TAO_DIOP_Profile (this->hosts_[i],
+ this->addrs_[i].get_port_number (),
+ object_key,
+ this->addrs_[i],
+ 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)
+ continue;
+
+ 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);
+ }
+
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::create_shared_profile (const TAO_ObjectKey &object_key,
+ TAO_MProfile &mprofile)
+{
+ size_t index = 0;
+ TAO_Profile *pfile = 0;
+ TAO_DIOP_Profile *iiop_profile = 0;
+
+ // First see if <mprofile> already contains a DIOP profile.
+ for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
+ {
+ pfile = mprofile.get_profile (i);
+ if (pfile->tag () == TAO_TAG_UDP_PROFILE)
+ {
+ iiop_profile = ACE_dynamic_cast (TAO_DIOP_Profile *,
+ pfile);
+ break;
+ }
+ }
+
+ // If <mprofile> doesn't contain a DIOP_Profile, we need to create
+ // one.
+ if (iiop_profile == 0)
+ {
+ ACE_NEW_RETURN (iiop_profile,
+ TAO_DIOP_Profile (this->hosts_[0],
+ this->addrs_[0].get_port_number (),
+ object_key,
+ this->addrs_[0],
+ this->version_,
+ this->orb_core_),
+ -1);
+ iiop_profile->endpoint ()->priority (this->priority ());
+
+ if (mprofile.give_profile (iiop_profile) == -1)
+ {
+ iiop_profile->_decr_refcnt ();
+ iiop_profile = 0;
+ return -1;
+ }
+
+ if (this->orb_core_->orb_params ()->std_profile_components () != 0)
+ {
+ iiop_profile->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;
+ iiop_profile->tagged_components ().set_code_sets (code_set_info);
+ }
+
+ index = 1;
+ }
+
+ // Add any remaining acceptor endpoints to the DIOP_Profile.
+ for (;
+ index < this->endpoint_count_;
+ ++index)
+ {
+ TAO_DIOP_Endpoint *endpoint = 0;
+ ACE_NEW_RETURN (endpoint,
+ TAO_DIOP_Endpoint (this->hosts_[index],
+ this->addrs_[index].get_port_number (),
+ this->addrs_[index]),
+ -1);
+ endpoint->priority (this->priority_);
+ iiop_profile->add_endpoint (endpoint);
+ }
+
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
+{
+ const TAO_DIOP_Endpoint *endp =
+ ACE_dynamic_cast (const TAO_DIOP_Endpoint *, endpoint);
+
+ // Make sure the dynamically cast pointer is valid.
+ if (endp == 0)
+ return 0;
+
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ // compare the port and sin_addr (numeric host address)
+ if (endp->object_addr () == this->addrs_[i])
+ return 1; // Collocated
+ }
+
+ return 0; // Not collocated
+}
+
+int
+TAO_DIOP_Acceptor::close (void)
+{
+ if (this->connection_handler_)
+ {
+ // Remove the connection handler from the reactor in the case
+ // of a valid handle, or close it yourself, if the handle is invalid.
+ // Either way it will cause the connection handler to be destructed.
+ if (this->connection_handler_->get_handle () != ACE_INVALID_HANDLE)
+ {
+ this->orb_core_->reactor ()->remove_handler (this->connection_handler_,
+ ACE_Event_Handler::READ_MASK);
+ }
+ else
+ {
+ this->connection_handler_->handle_close ();
+ }
+ this->connection_handler_ = 0;
+ }
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::open (TAO_ORB_Core *orb_core,
+ int major,
+ int minor,
+ const char *address,
+ const char *options)
+{
+ this->orb_core_ = orb_core;
+
+ if (this->init_tcp_properties () != 0)
+ return -1;
+
+ if (this->hosts_ != 0)
+ {
+ // The hostname cache has already been set!
+ // This is bad mojo, i.e. an internal TAO error.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Acceptor::open - "),
+ ACE_TEXT ("hostname already set\n\n")),
+ -1);
+ }
+
+ 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;
+
+ const char *port_separator_loc = ACE_OS::strchr (address, ':');
+ const char *specified_hostname = 0;
+ char tmp_host[MAXHOSTNAMELEN + 1];
+
+ if (port_separator_loc == address)
+ {
+ // The address is a port number or port name. No hostname was
+ // specified. The hostname for each network interface and the
+ // fully qualified domain name must be obtained.
+
+ // Check for multiple network interfaces.
+ if (this->probe_interfaces (orb_core) == -1)
+ 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 (),
+ ACE_static_cast (ACE_UINT32, INADDR_ANY),
+ 1) != 0)
+ return -1;
+ else
+ return this->open_i (addr);
+ }
+ else if (port_separator_loc == 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;
+
+ specified_hostname = address;
+ }
+ else
+ {
+ // Host and port were specified.
+ if (addr.set (address) != 0)
+ return -1;
+
+ // Extract out just the host part of the address.
+ size_t len = port_separator_loc - address;
+ ACE_OS::memcpy (tmp_host, address, len);
+ tmp_host[len] = '\0';
+
+ specified_hostname = tmp_host;
+ }
+
+ this->endpoint_count_ = 1; // Only one hostname to store
+
+ ACE_NEW_RETURN (this->addrs_,
+ ACE_INET_Addr[this->endpoint_count_],
+ -1);
+
+ ACE_NEW_RETURN (this->hosts_,
+ char *[this->endpoint_count_],
+ -1);
+
+ if (this->hostname (orb_core,
+ addr,
+ this->hosts_[0],
+ specified_hostname) != 0)
+ return -1;
+
+ // Copy the addr. The port is (re)set in
+ // TAO_DIOP_Acceptor::open_i().
+ if (this->addrs_[0].set (addr) != 0)
+ return -1;
+
+ return this->open_i (addr);
+}
+
+int
+TAO_DIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
+ int major,
+ int minor,
+ const char *options)
+{
+ this->orb_core_ = orb_core;
+
+ if (this->init_tcp_properties () != 0)
+ return -1;
+
+ if (this->hosts_ != 0)
+ {
+ // The hostname cache has already been set!
+ // This is bad mojo, i.e. an internal TAO error.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Acceptor::open_default - "),
+ ACE_TEXT ("hostname already set\n\n")),
+ -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;
+
+ // Check for multiple network interfaces.
+ if (this->probe_interfaces (orb_core) == -1)
+ return -1;
+
+ // Now that each network interface's hostname has been cached, open
+ // an endpoint on each network interface using the INADDR_ANY
+ // address.
+ ACE_INET_Addr addr;
+
+ // @@ Michael: The following needs to be verified.
+ if (addr.set (ACE_DEFAULT_SERVER_PORT, // old: ACE_static_cast(u_short, 0),
+ ACE_static_cast(ACE_UINT32, INADDR_ANY),
+ 1) != 0)
+ return -1;
+
+ return this->open_i (addr);
+}
+
+int
+TAO_DIOP_Acceptor::open_i (const ACE_INET_Addr& addr)
+{
+ // @@ Michael: UDP changes ---------------
+
+ ACE_NEW_RETURN (this->connection_handler_,
+ TAO_DIOP_Connection_Handler (this->orb_core_,
+ this->lite_flag_,
+ 0 /* TAO_DIOP_Properties */),
+ -1);
+
+ this->connection_handler_->local_addr (addr);
+ this->connection_handler_->open_server ();
+
+ // Register only with a valid handle
+ if (this->connection_handler_->get_handle () != ACE_INVALID_HANDLE)
+ {
+ this->orb_core_->reactor ()->register_handler (this->connection_handler_,
+ ACE_Event_Handler::READ_MASK);
+ }
+ // ------------------------------------
+
+
+ // Set the port for each addr. If there is more than one network
+ // interface then the endpoint created on each interface will be on
+ // the same port. This is how a wildcard socket bind() is supposed
+ // to work.
+ u_short port = addr.get_port_number ();
+ for (size_t j = 0; j < this->endpoint_count_; ++j)
+ this->addrs_[j].set_port_number (port, 1);
+
+ if (TAO_debug_level > 5)
+ {
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\nTAO (%P|%t) DIOP_Acceptor::open_i - ")
+ ACE_TEXT ("listening on: <%s:%u>\n"),
+ this->hosts_[i],
+ this->addrs_[i].get_port_number ()));
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::hostname (TAO_ORB_Core *orb_core,
+ ACE_INET_Addr &addr,
+ char *&host,
+ const char *specified_hostname)
+{
+ if (orb_core->orb_params ()->use_dotted_decimal_addresses ())
+ {
+ // If dotted decimal addresses are enabled,
+ // just return ours.
+ return this->dotted_decimal_address (addr, host);
+ }
+ else
+ if (specified_hostname != 0)
+ {
+ // If the user specified a hostname, pass it back
+ // blindly as it overrides our choice of hostname.
+ host = CORBA::string_dup (specified_hostname);
+ }
+ else
+ {
+ char tmp_host[MAXHOSTNAMELEN + 1];
+
+ // Get the hostname associated with our address
+ if (addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
+ {
+ // On failure, just return the decimal address.
+ return this->dotted_decimal_address (addr, host);
+ }
+ else
+ {
+ host = CORBA::string_dup (tmp_host);
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::dotted_decimal_address (ACE_INET_Addr &addr,
+ char *&host)
+{
+ const char *tmp = addr.get_host_addr ();
+ if (tmp == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Acceptor::dotted_decimal_address ")
+ ACE_TEXT ("- %p\n\n"),
+ ACE_TEXT ("cannot determine hostname")));
+ return -1;
+ }
+
+ host = CORBA::string_dup (tmp);
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::probe_interfaces (TAO_ORB_Core *orb_core)
+{
+ // Extract the hostname for each network interface, and then cache
+ // it. The hostnames will then be used when creating a
+ // TAO_DIOP_Profile for each endpoint setup on the probed
+ // network interfaces.
+ ACE_INET_Addr *if_addrs = 0;
+ size_t if_cnt = 0;
+
+ if (ACE::get_ip_interfaces (if_cnt,
+ if_addrs) != 0
+ && errno != ENOTSUP)
+ {
+ // In the case where errno == ENOTSUP, if_cnt and if_addrs will
+ // not be modified, and will each remain equal to zero. This
+ // causes the default interface to be used.
+ return -1;
+ }
+
+ if (if_cnt == 0 || if_addrs == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_WARNING,
+ ACE_TEXT ("TAO (%P|%t) Unable to probe network ")
+ ACE_TEXT ("interfaces. Using default.")));
+ }
+
+ if_cnt = 1; // Force the network interface count to be one.
+ delete [] if_addrs;
+ ACE_NEW_RETURN (if_addrs,
+ ACE_INET_Addr[if_cnt],
+ -1);
+ }
+
+ // Scan for the loopback interface since it shouldn't be included in
+ // the list of cached hostnames unless it is the only interface.
+ size_t lo_cnt = 0; // Loopback interface count
+ for (size_t j = 0; j < if_cnt; ++j)
+ if (if_addrs[j].get_ip_address () == INADDR_LOOPBACK)
+ lo_cnt++;
+
+ // The instantiation for this template is in
+ // tao/DIOP_Connector.cpp.
+ ACE_Auto_Basic_Array_Ptr<ACE_INET_Addr> safe_if_addrs (if_addrs);
+
+ // If the loopback interface is the only interface then include it
+ // in the list of interfaces to query for a hostname, otherwise
+ // exclude it from the list.
+ if (if_cnt == lo_cnt)
+ this->endpoint_count_ = if_cnt;
+ else
+ this->endpoint_count_ = if_cnt - lo_cnt;
+
+ ACE_NEW_RETURN (this->addrs_,
+ ACE_INET_Addr[this->endpoint_count_],
+ -1);
+
+ ACE_NEW_RETURN (this->hosts_,
+ char *[this->endpoint_count_],
+ -1);
+
+ // The number of hosts/interfaces we want to cache may not be the
+ // same as the number of detected interfaces so keep a separate
+ // count.
+ size_t host_cnt = 0;
+
+ for (size_t i = 0; i < if_cnt; ++i)
+ {
+ // Ignore any loopback interface if there are other
+ // non-loopback interfaces.
+ if (if_cnt != lo_cnt &&
+ if_addrs[i].get_ip_address() == INADDR_LOOPBACK)
+ continue;
+
+ if (this->hostname (orb_core,
+ if_addrs[i],
+ this->hosts_[host_cnt]) != 0)
+ return -1;
+
+ // Copy the addr. The port is (re)set in
+ // TAO_DIOP_Acceptor::open_i().
+ if (this->addrs_[host_cnt].set (if_addrs[i]) != 0)
+ return -1;
+
+ host_cnt++;
+ }
+
+ return 0;
+}
+
+CORBA::ULong
+TAO_DIOP_Acceptor::endpoint_count (void)
+{
+ return this->endpoint_count_;
+}
+
+int
+TAO_DIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
+ TAO_ObjectKey &object_key)
+{
+ // Create the decoding stream from the encapsulation in the buffer,
+#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
+ TAO_InputCDR cdr (profile.profile_data.mb ());
+#else
+ TAO_InputCDR cdr (ACE_reinterpret_cast(char*,profile.profile_data.get_buffer ()),
+ profile.profile_data.length ());
+#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
+
+ CORBA::Octet major, minor;
+
+ // Read the version. We just read it here. We don't*do any*
+ // processing.
+ if (!(cdr.read_octet (major)
+ && cdr.read_octet (minor)))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) DIOP_Profile::decode - v%d.%d\n"),
+ major,
+ minor));
+ }
+ return -1;
+ }
+
+ CORBA::String_var host;
+ CORBA::UShort port = 0;
+
+ // Get host and port. No processing here too..
+ if (cdr.read_string (host.out ()) == 0
+ || cdr.read_ushort (port) == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) TAO_Tagged_Profile::decode - ")
+ ACE_TEXT ("error while decoding host/port")));
+ }
+ return -1;
+ }
+
+ // ... and object key.
+ if ((cdr >> object_key) == 0)
+ return -1;
+
+ // We are NOT bothered about the rest.
+
+ return 1;
+}
+
+
+int
+TAO_DIOP_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,
+ ACE_TEXT ("TAO (%P|%t) Zero length DIOP 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,
+ ACE_TEXT ("TAO (%P|%t) DIOP option <%s> is ")
+ ACE_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,
+ ACE_TEXT ("TAO (%P|%t) Zero length DIOP ")
+ ACE_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,
+ ACE_TEXT ("TAO (%P|%t) Invalid DIOP endpoint ")
+ ACE_TEXT ("priority: <%s>\n"),
+ value.c_str ()),
+ -1);
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) Invalid DIOP option: <%s>\n"),
+ name.c_str ()),
+ -1);
+ }
+ }
+ return 0;
+}
+
+int
+TAO_DIOP_Acceptor::init_tcp_properties (void)
+{
+ // @@ Michael: We use UDP, so we do not set TCP settings.
+ return 0;
+}
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.h b/TAO/tao/Strategies/DIOP_Acceptor.h
new file mode 100644
index 00000000000..326c6d0e1d0
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Acceptor.h
@@ -0,0 +1,186 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DIOP_Acceptor.h
+ *
+ * $Id$
+ *
+ * DIOP specific acceptor processing
+ *
+ * @author Michael Kircher
+ */
+//=============================================================================
+
+
+#ifndef TAO_DIOP_ACCEPTOR_H
+#define TAO_DIOP_ACCEPTOR_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Pluggable.h"
+#include "DIOP_Connection_Handler.h"
+#include "tao/Acceptor_Impl.h"
+
+#include "tao/GIOP_Message_Version.h"
+
+// TAO DIOP_Acceptor concrete call defination
+
+/**
+ * @class TAO_DIOP_Acceptor
+ *
+ * @brief TAO_DIOP_Acceptor
+ *
+ * The DIOP-specific bridge class for the concrete acceptor.
+ */
+class TAO_Strategies_Export TAO_DIOP_Acceptor : public TAO_Acceptor
+{
+public:
+ /// Constructor.
+ TAO_DIOP_Acceptor (CORBA::Boolean flag = 0);
+
+ /// Destructor.
+ ~TAO_DIOP_Acceptor (void);
+
+ /// @@ Helper method for the implementation repository, should go
+ /// away
+ const ACE_INET_Addr& address (void) const;
+
+ /// Returns the array of endpoints in this acceptor
+ const ACE_INET_Addr *endpoints (void);
+
+ /**
+ * 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,
+ int version_major,
+ int version_minor,
+ const char *options = 0);
+ virtual int close (void);
+ virtual int create_mprofile (const TAO_ObjectKey &object_key,
+ TAO_MProfile &mprofile,
+ CORBA::Boolean share_profile);
+
+ virtual int is_collocated (const TAO_Endpoint *endpoint);
+ virtual CORBA::ULong endpoint_count (void);
+
+ virtual int object_key (IOP::TaggedProfile &profile,
+ TAO_ObjectKey &key);
+
+ /**
+ * Set the host name for the given addr.
+ * A hostname may be forced by using specified_hostname. This
+ * is useful if the given address corresponds to more than one
+ * hostname and the desired one cannot be determined in any
+ * other way.
+ */
+ int hostname (TAO_ORB_Core *orb_core,
+ ACE_INET_Addr &addr,
+ char *&host,
+ const char *specified_hostname = 0);
+
+ /**
+ * Set the host name for the given address using the dotted decimal
+ * format.
+ */
+ int dotted_decimal_address (ACE_INET_Addr &addr,
+ char *&host);
+
+protected:
+
+ /**
+ * Implement the common part of the open*() methods. This method is
+ * virtual to allow a derived class implementation to be invoked
+ * instead.
+ */
+ virtual int open_i (const ACE_INET_Addr &addr);
+
+ /**
+ * Probe the system for available network interfaces, and initialize
+ * the <addrs_> array with an ACE_INET_Addr for each network
+ * interface. The port for each initialized ACE_INET_Addr will be
+ * set in the open_i() method. This method only gets invoked when
+ * no explicit hostname is provided in the specified endpoint.
+ */
+ int probe_interfaces (TAO_ORB_Core *orb_core);
+
+ /// Parse protocol specific options.
+ virtual int parse_options (const char *options);
+
+ /// Obtain tcp properties that must be used by this acceptor, i.e.,
+ /// initialize <tcp_properties_>.
+ int init_tcp_properties (void);
+
+ /// Helper method to add a new profile to the mprofile for
+ /// each endpoint.
+ int create_new_profiles (const TAO_ObjectKey &object_key,
+ TAO_MProfile &mprofile);
+
+ /// Helper method to create a profile that contains all of
+ /// our endpoints.
+ int create_shared_profile (const TAO_ObjectKey &object_key,
+ TAO_MProfile &mprofile);
+
+protected:
+
+ /// Array of ACE_INET_Addr instances, each one corresponding to a
+ /// given network interface.
+ ACE_INET_Addr *addrs_;
+
+ /**
+ * Cache the information about the endpoints serviced by this
+ * acceptor.
+ * There may in fact be multiple hostnames for this endpoint. For
+ * example, if the IP address is INADDR_ANY (0.0.0.0) then there
+ * will be possibly a different hostname for each interface.
+ */
+ char **hosts_;
+
+ /// The number of host names cached in the hosts_ array (equivalent
+ /// to the number of endpoints opened by this Acceptor).
+ size_t endpoint_count_;
+
+ /**
+ * The GIOP version for this endpoint
+ * @@ Theoretically they shouldn't be here!! We need to look at a
+ * way to move this out
+ */
+ TAO_GIOP_Message_Version version_;
+
+ /// ORB Core.
+ TAO_ORB_Core *orb_core_;
+
+ /// TCP configuration properties to be used for all
+ /// connections opened by this acceptor.
+ TAO_DIOP_Properties tcp_properties_;
+
+ /// Should we use GIOP lite??
+ CORBA::Boolean lite_flag_;
+
+private:
+ // @@ Frank: From DIOP_Acceptor.h
+ TAO_DIOP_Connection_Handler *connection_handler_;
+
+};
+
+#if defined(__ACE_INLINE__)
+#include "DIOP_Acceptor.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_ACCEPTOR_H */
diff --git a/TAO/tao/Strategies/DIOP_Acceptor.i b/TAO/tao/Strategies/DIOP_Acceptor.i
new file mode 100644
index 00000000000..9aaf71a3d41
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Acceptor.i
@@ -0,0 +1,23 @@
+// -*- C++ -*-
+// $Id$
+
+ACE_INLINE const ACE_INET_Addr&
+TAO_DIOP_Acceptor::address (void) const
+{
+ ACE_ASSERT (this->addrs_ != 0);
+
+ // @@ This is busted.
+ // The Implementation Repository will have to start supporting
+ // IORs with multiple profiles. For now, we just return the
+ // first addr.
+ // -Ossama
+ return this->addrs_[0];
+}
+
+ACE_INLINE const ACE_INET_Addr *
+TAO_DIOP_Acceptor::endpoints (void)
+{
+ ACE_ASSERT (this->addrs_ != 0);
+
+ return this->addrs_;
+}
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
new file mode 100644
index 00000000000..9b95deeea56
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp
@@ -0,0 +1,402 @@
+// $Id$
+
+
+#include "DIOP_Connection_Handler.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Timeprobe.h"
+#include "tao/debug.h"
+#include "tao/ORB_Core.h"
+#include "tao/ORB.h"
+#include "tao/CDR.h"
+#include "tao/Messaging_Policy_i.h"
+#include "tao/Server_Strategy_Factory.h"
+#include "tao/Transport_Cache_Manager.h"
+#include "tao/Base_Transport_Property.h"
+
+#include "DIOP_Transport.h"
+#include "DIOP_Endpoint.h"
+
+#if !defined (__ACE_INLINE__)
+# include "DIOP_Connection_Handler.i"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_RCSID(tao, DIOP_Connect, "$Id$")
+
+
+
+TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (ACE_Thread_Manager *t)
+ : TAO_DIOP_SVC_HANDLER (t, 0 , 0),
+ TAO_Connection_Handler (0),
+ pending_upcalls_ (1),
+ tcp_properties_ (0)
+{
+ // This constructor should *never* get called, it is just here to
+ // make the compiler happy: the default implementation of the
+ // Creation_Strategy requires a constructor with that signature, we
+ // don't use that implementation, but some (most?) compilers
+ // instantiate it anyway.
+ ACE_ASSERT (this->orb_core () != 0);
+}
+
+
+TAO_DIOP_Connection_Handler::TAO_DIOP_Connection_Handler (TAO_ORB_Core *orb_core,
+ CORBA::Boolean /* flag*/,
+ void *arg)
+ : TAO_DIOP_SVC_HANDLER (orb_core->thr_mgr (), 0, 0),
+ TAO_Connection_Handler (orb_core),
+ pending_upcalls_ (1),
+ tcp_properties_ (ACE_static_cast
+ (TAO_DIOP_Properties *, arg))
+{
+ TAO_DIOP_Transport* specific_transport = 0;
+ ACE_NEW(specific_transport,
+ TAO_DIOP_Transport(this, orb_core, 0));
+
+ // store this pointer (indirectly increment ref count)
+ this->transport(specific_transport);
+ TAO_Transport::release (specific_transport);
+}
+
+
+TAO_DIOP_Connection_Handler::~TAO_DIOP_Connection_Handler (void)
+{
+ this->udp_socket_.close ();
+}
+
+// DIOP Additions - Begin
+ACE_HANDLE
+TAO_DIOP_Connection_Handler::get_handle (void) const
+{
+ return this->udp_socket_.get_handle ();
+}
+
+
+const ACE_INET_Addr &
+TAO_DIOP_Connection_Handler::addr (void)
+{
+ return this->addr_;
+}
+
+
+void
+TAO_DIOP_Connection_Handler::addr (const ACE_INET_Addr &addr)
+{
+ this->addr_ = addr;
+}
+
+
+const ACE_INET_Addr &
+TAO_DIOP_Connection_Handler::local_addr (void)
+{
+ return local_addr_;
+}
+
+
+void
+TAO_DIOP_Connection_Handler::local_addr (const ACE_INET_Addr &addr)
+{
+ local_addr_ = addr;
+}
+
+
+const ACE_SOCK_Dgram &
+TAO_DIOP_Connection_Handler::dgram (void)
+{
+ return this->udp_socket_;
+}
+// DIOP Additions - End
+
+
+int
+TAO_DIOP_Connection_Handler::open (void*)
+{
+ this->udp_socket_.open (this->local_addr_);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Opened connector on %s:%d\n",
+ this->local_addr_.get_host_name (),
+ this->local_addr_.get_port_number ()));
+
+ // Set the id in the transport now that we're active.
+ this->transport ()->id ((int) this->get_handle ());
+
+ return 0;
+}
+
+int
+TAO_DIOP_Connection_Handler::open_server (void)
+{
+ this->udp_socket_.open (this->local_addr_);
+ ACE_DEBUG ((LM_DEBUG,
+ "Opened acceptor on %s:%d\n",
+ this->local_addr_.get_host_name (),
+ this->local_addr_.get_port_number ()));
+
+ this->transport ()->id ((int) this->get_handle ());
+
+ return 0;
+}
+
+int
+TAO_DIOP_Connection_Handler::activate (long flags,
+ int n_threads,
+ int force_active,
+ long priority,
+ int grp_id,
+ ACE_Task_Base *task,
+ ACE_hthread_t thread_handles[],
+ void *stack[],
+ size_t stack_size[],
+ ACE_thread_t thread_names[])
+{
+ if (TAO_debug_level)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) DIOP_Connection_Handler::activate %d ")
+ ACE_TEXT ("threads, flags = %d\n"),
+ n_threads,
+ flags,
+ THR_BOUND));
+ // @@ Michael: I believe we do not need active service handlers right now.
+ // @@ Frank: Not disabled yet...
+
+ // Set the id in the transport now that we're active.
+ this->transport ()->id ((int) this->get_handle ());
+
+ return TAO_DIOP_SVC_HANDLER::activate (flags,
+ n_threads,
+ force_active,
+ priority,
+ grp_id,
+ task,
+ thread_handles,
+ stack,
+ stack_size,
+ thread_names);
+}
+
+int
+TAO_DIOP_Connection_Handler::svc (void)
+{
+ // @@ Michael: I believe we do not need active service handlers right now.
+ // @@ Frank: Not yet...
+
+ // 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".
+
+ // Clear the non-blocking mode here
+ ACE_Flag_Manip::clr_flags (this->get_handle (),
+ ACE_NONBLOCK);
+
+ // Call the implementation here
+ return this->svc_i ();
+}
+
+
+int
+TAO_DIOP_Connection_Handler::handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask rm)
+{
+ // @@ Alex: we need to figure out if the transport decides to close
+ // us or something else. If it is something else (for example
+ // the cached connector trying to make room for other
+ // connections) then we should let the transport know, so it can
+ // in turn take appropiate action (such as sending exceptions to
+ // all waiting reply handlers).
+ if (TAO_debug_level)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Connection_Handler::handle_close ")
+ ACE_TEXT ("(%d, %d)\n"),
+ handle,
+ rm));
+
+ --this->pending_upcalls_;
+ if (this->pending_upcalls_ <= 0)
+ {
+ // @@ Why are we doing checks for is_registered flags here if the
+ // handlers are not registered with the reactor? - Bala
+ if (this->transport ()->wait_strategy ()->is_registered ())
+ {
+ // @@ Frank: Added reactor check. not sure if this is right?
+ if (this->reactor ())
+ {
+ // Make sure there are no timers.
+ this->reactor ()->cancel_timer (this);
+ }
+
+ // Set the flag to indicate that it is no longer registered with
+ // the reactor, so that it isn't included in the set that is
+ // passed to the reactor on ORB destruction.
+ this->transport ()->wait_strategy()->is_registered (0);
+ }
+
+ // Close the handle..
+ if (this->get_handle () != ACE_INVALID_HANDLE)
+ {
+ // Purge the entry too
+ this->transport ()->mark_invalid ();
+
+ // Signal the transport that we will no longer have
+ // a reference to it. This will eventually call
+ // TAO_Transport::release ().
+ this->transport (0);
+ }
+
+ // Follow usual Reactor-style lifecycle semantics and commit
+ // suicide.
+ this->destroy ();
+ }
+
+ return 0;
+}
+
+ACE_HANDLE
+TAO_DIOP_Connection_Handler::fetch_handle (void)
+{
+ return this->get_handle ();
+}
+
+
+int
+TAO_DIOP_Connection_Handler::add_transport_to_cache (void)
+{
+ ACE_INET_Addr addr;
+
+ // Get the peername.
+ if (this->peer ().get_remote_addr (addr) == -1)
+ return -1;
+
+ // Construct an DIOP_Endpoint object
+ TAO_DIOP_Endpoint endpoint (addr,
+ 0);
+
+ // Construct a property object
+ TAO_Base_Transport_Property prop (&endpoint);
+
+ // Add the handler to Cache
+ return this->orb_core ()->transport_cache ()->cache_transport (&prop,
+ this->transport ());
+}
+
+// @@ Frank: Hopefully this isn't needed
+/*
+int
+TAO_DIOP_Connection_Handler::process_listen_point_list (
+ DIOP::ListenPointList &listen_list)
+{
+ // Get the size of the list
+ CORBA::ULong len = listen_list.length ();
+
+ for (CORBA::ULong i = 0; i < len; ++ i)
+ {
+ DIOP::ListenPoint listen_point = listen_list[i];
+ ACE_INET_Addr addr (listen_point.port,
+ listen_point.host.in ());
+
+
+ // Construct an DIOP_Endpoint object
+ TAO_DIOP_Endpoint endpoint (addr,
+ 0);
+
+ // Construct a property object
+ TAO_Base_Transport_Property prop (&endpoint);
+
+ // Mark the connection as bidirectional
+ prop.set_bidir_flag (1);
+
+ // The property for this handler has changed. Recache the
+ // handler with this property
+ int retval = this->transport ()->recache_transport (&prop);
+ if (retval == -1)
+ return retval;
+
+ // Make the handler idle and ready for use
+ this->transport ()->make_idle ();
+ }
+
+ return 0;
+}
+*/
+
+int
+TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h)
+{
+ return this->handle_input_i (h);
+}
+
+
+int
+TAO_DIOP_Connection_Handler::handle_input_i (ACE_HANDLE,
+ ACE_Time_Value *max_wait_time)
+{
+ this->pending_upcalls_++;
+
+ // Call the transport read the message
+ int result = this->transport ()->read_process_message (max_wait_time);
+
+ // Now the message has been read
+ if (result == -1 && TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - %p\n"),
+ ACE_TEXT ("DIOP_Connection_Handler::handle_input_i \n")));
+
+ }
+
+ // The upcall is done. Bump down the reference count
+ if (--this->pending_upcalls_ <= 0)
+ result = -1;
+
+ // @@ Michael:
+ // We always return 0, as we do not have any
+ // send errors.
+ return 0;
+}
+
+// @@ Frank: From DIOP_Connect.cpp
+int
+TAO_DIOP_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);
+ }
+
+ return 0;
+}
+
+
+
+
+// ****************************************************************
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+// Instantiated in IIOP_Connection_Handler.cpp
+//template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
+
+template class ACE_Concurrency_Strategy<TAO_DIOP_Connection_Handler>;
+template class ACE_Creation_Strategy<TAO_DIOP_Connection_Handler>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+// Instantiated in IIOP_Connection_Handler.cpp
+//#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+
+#pragma instantiate ACE_Concurrency_Strategy<TAO_DIOP_Connection_Handler>
+#pragma instantiate ACE_Creation_Strategy<TAO_DIOP_Connection_Handler>
+
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.h b/TAO/tao/Strategies/DIOP_Connection_Handler.h
new file mode 100644
index 00000000000..b0291796f43
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.h
@@ -0,0 +1,194 @@
+// This may look like C, but it's really -*- C++ -*-
+// ===================================================================
+/**
+ * @file DIOP_Connection_Handler.h
+ *
+ * $Id$
+ *
+ * @author Michael Kircher
+ */
+// ===================================================================
+
+#ifndef TAO_DIOP_CONNECTION_HANDLER_H
+#define TAO_DIOP_CONNECTION_HANDLER_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "ace/Reactor.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Acceptor.h"
+
+#include "tao/corbafwd.h"
+#include "tao/Wait_Strategy.h"
+#include "tao/Connection_Handler.h"
+#include "DIOP_Transport.h"
+//#include "tao/DIOPC.h"
+#include "ace/SOCK_Dgram.h"
+#include "strategies_export.h"
+
+// Forward Decls
+class TAO_Pluggable_Messaging;
+
+// ****************************************************************
+
+/**
+ * @class TAO_DIOP_Properties
+ *
+ * @brief TCP protocol properties specification for a set of
+ * connections.
+ *
+ */
+
+class TAO_Strategies_Export TAO_DIOP_Properties
+{
+
+public:
+ int send_buffer_size;
+ int recv_buffer_size;
+ int no_delay;
+};
+
+
+
+// ****************************************************************
+
+/**
+ * @class TAO_DIOP_Connection_Handler
+ *
+ * @brief Handles requests on a single connection.
+ *
+ * The Connection handler which is common for the Acceptor and
+ * the Connector
+ */
+
+
+class TAO_Strategies_Export TAO_DIOP_Connection_Handler : public TAO_DIOP_SVC_HANDLER,
+ public TAO_Connection_Handler
+{
+
+public:
+
+ TAO_DIOP_Connection_Handler (ACE_Thread_Manager* t = 0);
+
+ /// Constructor. <arg> parameter is used by the Acceptor to pass the
+ /// protocol configuration properties for this connection.
+ TAO_DIOP_Connection_Handler (TAO_ORB_Core *orb_core,
+ CORBA::Boolean flag,
+ void *arg);
+
+
+ /// Destructor.
+ ~TAO_DIOP_Connection_Handler (void);
+
+ /// Called by the <Strategy_Acceptor> when the handler is completely
+ /// connected. Argument is unused.
+ virtual int open (void *);
+
+ // @@ Frank: Similar to open, but called on server
+ virtual int open_server (void);
+
+ /// = 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);
+
+ /// Only used when the handler is turned into an active object by
+ /// calling <activate>. This serves as the event loop in such cases.
+ virtual int svc (void);
+
+ /// Perform appropriate closing.
+ virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK);
+
+ /// Return the underlying handle
+ virtual ACE_HANDLE fetch_handle (void);
+
+ /// Add ourselves to Cache.
+ int add_transport_to_cache (void);
+
+ // @@ Frank: Not needed
+ /*
+ /// Process the <listen_list>
+ int process_listen_point_list (DIOP::ListenPointList &listen_list);
+ */
+
+ // DIOP Additions - Begin
+ ACE_HANDLE get_handle (void) const;
+
+ const ACE_INET_Addr &addr (void);
+
+ void addr (const ACE_INET_Addr &addr);
+
+ const ACE_INET_Addr &local_addr (void);
+
+ void local_addr (const ACE_INET_Addr &addr);
+
+ const ACE_INET_Addr &server_addr (void);
+
+ void server_addr (const ACE_INET_Addr &addr);
+
+ const ACE_SOCK_Dgram &dgram (void);
+ // DIOP Additions - End
+
+protected:
+
+ /// = Event Handler overloads
+
+ /// 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_input (ACE_HANDLE = ACE_INVALID_HANDLE);
+ virtual int handle_input_i (ACE_HANDLE = ACE_INVALID_HANDLE,
+ ACE_Time_Value *max_wait_time = 0);
+
+ virtual int handle_cleanup ();
+
+ // DIOP Additions - Begin
+ ACE_SOCK_Dgram udp_socket_;
+
+ // This is always the remote address
+ ACE_INET_Addr addr_;
+
+ // This is always the local address for the connector
+ ACE_INET_Addr local_addr_;
+
+ // DIOP Additions - End
+
+private:
+
+ /// Count nested upcalls on this
+ /// svc_handler i.e., the connection can close during nested upcalls,
+ /// you should not delete the svc_handler until the stack unwinds
+ /// from the nested upcalls.
+ u_long pending_upcalls_;
+
+ /// TCP configuration for this connection.
+ TAO_DIOP_Properties *tcp_properties_;
+};
+
+
+#if defined (__ACE_INLINE__)
+#include "DIOP_Connection_Handler.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_CONNECTION_HANDLER_H */
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.i b/TAO/tao/Strategies/DIOP_Connection_Handler.i
new file mode 100644
index 00000000000..7f2b3228624
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Connection_Handler.i
@@ -0,0 +1,3 @@
+// -*- C++ -*-
+// $Id$
+
diff --git a/TAO/tao/Strategies/DIOP_Connector.cpp b/TAO/tao/Strategies/DIOP_Connector.cpp
new file mode 100644
index 00000000000..ef5e3a96665
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Connector.cpp
@@ -0,0 +1,276 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+#include "DIOP_Connector.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "ace/Connector.h"
+
+#include "tao/debug.h"
+#include "tao/ORB_Core.h"
+#include "tao/Environment.h"
+#include "tao/Base_Transport_Property.h"
+#include "tao/Protocols_Hooks.h"
+
+#include "DIOP_Profile.h"
+
+
+ACE_RCSID (DIOP,
+ DIOP_Connector,
+ "$Id$")
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+
+template class ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>;
+template class ACE_Map_Manager<int, ACE_Svc_Tuple<TAO_DIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>;
+template class ACE_Map_Iterator_Base<int, ACE_Svc_Tuple<TAO_DIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>;
+template class ACE_Map_Entry<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*>;
+
+template class ACE_Map_Entry<ACE_INET_Addr, TAO_DIOP_Connection_Handler *>;
+
+template class ACE_Map_Iterator<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>;
+template class ACE_Map_Reverse_Iterator<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>;
+template class ACE_Hash_Map_Iterator_Base_Ex < ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash < ACE_INET_Addr >, ACE_Equal_To < ACE_INET_Addr >, ACE_Null_Mutex >;
+template class ACE_Hash_Map_Iterator_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash<ACE_INET_Addr>, ACE_Equal_To<ACE_INET_Addr>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash<ACE_INET_Addr>, ACE_Equal_To<ACE_INET_Addr>, ACE_Null_Mutex>;
+
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>
+#pragma instantiate ACE_Map_Manager<int, ACE_Svc_Tuple<TAO_DIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Iterator_Base<int, ACE_Svc_Tuple<TAO_DIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Entry<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*>
+
+#pragma instantiate ACE_Map_Entry<ACE_INET_Addr, TAO_DIOP_Connection_Handler *>;
+
+#pragma instantiate ACE_Map_Iterator<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_Map_Reverse_Iterator<int,ACE_Svc_Tuple<TAO_DIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>
+
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex < ACE_INET_Addr,TAO_DIOP_Connection_Handler *, ACE_Hash < ACE_INET_Addr >, ACE_Equal_To < ACE_INET_Addr >, ACE_Null_Mutex >
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash<ACE_INET_Addr>, ACE_Equal_To<ACE_INET_Addr>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash<ACE_INET_Addr>, ACE_Equal_To<ACE_INET_Addr>, ACE_Null_Mutex>
+
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+TAO_DIOP_Connector::TAO_DIOP_Connector (CORBA::Boolean flag)
+ : TAO_Connector (TAO_TAG_UDP_PROFILE),
+ lite_flag_ (flag)
+{
+}
+
+TAO_DIOP_Connector::~TAO_DIOP_Connector (void)
+{
+}
+
+int
+TAO_DIOP_Connector::open (TAO_ORB_Core *orb_core)
+{
+ this->orb_core (orb_core);
+
+ // @@ Michael: We do not use traditional connection management.
+
+ return 0;
+}
+
+int
+TAO_DIOP_Connector::close (void)
+{
+ // @@ Michael: UDP Addition ------------------------------------
+
+ // The list of service handlers cleans itself??
+ SvcHandlerIterator iter (svc_handler_table_);
+
+ while (!iter.done ())
+ {
+ // Delete the connection handler
+ delete (*iter).int_id_;
+ iter++;
+ }
+ // -----------------------------------------------------------------
+
+ // @@ Michael: We do not use traditional connection management.
+ return 0;
+}
+
+int
+TAO_DIOP_Connector::connect (TAO_Transport_Descriptor_Interface *desc,
+ TAO_Transport *&transport,
+ ACE_Time_Value * /*max_wait_time*/,
+ CORBA::Environment &)
+{
+ TAO_Endpoint *endpoint = desc->endpoint ();
+
+ if (endpoint->tag () != TAO_TAG_UDP_PROFILE)
+ return -1;
+
+ TAO_DIOP_Endpoint *diop_endpoint =
+ ACE_dynamic_cast (TAO_DIOP_Endpoint *,
+ endpoint );
+ if (diop_endpoint == 0)
+ return -1;
+
+ const ACE_INET_Addr &remote_address =
+ diop_endpoint->object_addr ();
+
+ // Verify that the remote ACE_INET_Addr was initialized properly.
+ // Failure can occur if hostname lookup failed when initializing the
+ // remote ACE_INET_Addr.
+ if (remote_address.get_type () != AF_INET)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) DIOP connection failed.\n")
+ ACE_TEXT ("TAO (%P|%t) This is most likely ")
+ ACE_TEXT ("due to a hostname lookup ")
+ ACE_TEXT ("failure.\n")));
+ }
+
+ return -1;
+ }
+
+ TAO_DIOP_Connection_Handler *svc_handler = 0;
+
+ // @@ Michael -- UDP Additions ----------------------------
+
+ if (svc_handler_table_.find (remote_address, svc_handler) == -1)
+ {
+ TAO_DIOP_Connection_Handler *svc_handler_i = 0;
+ ACE_NEW_RETURN (svc_handler_i,
+ TAO_DIOP_Connection_Handler (this->orb_core (),
+ this->lite_flag_,
+ 0 /* TAO_DIOP_Properties */),
+ -1);
+
+ svc_handler_i->local_addr (ACE_sap_any_cast (ACE_INET_Addr &));
+ svc_handler_i->addr (remote_address);
+
+ svc_handler_i->open (0);
+
+ svc_handler_table_.bind (remote_address,
+ svc_handler_i);
+ svc_handler = svc_handler_i;
+
+ if (TAO_debug_level > 2)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) DIOP_Connector::connect - ")
+ ACE_TEXT ("new connection on HANDLE %d\n"),
+ svc_handler->get_handle ()));
+ }
+
+ // ---------------------------------------------------------
+
+ // @@ Michael: We do not use traditional connection management.
+
+ transport = TAO_Transport::_duplicate (svc_handler->transport ());
+
+ return 0;
+}
+
+int
+TAO_DIOP_Connector::preconnect (const char *)
+{
+ // @@ Michael: We do not support preconnects.
+ return 0;
+}
+
+TAO_Profile *
+TAO_DIOP_Connector::create_profile (TAO_InputCDR& cdr)
+{
+ TAO_Profile *pfile;
+ ACE_NEW_RETURN (pfile,
+ TAO_DIOP_Profile (this->orb_core ()),
+ 0);
+
+ int r = pfile->decode (cdr);
+ if (r == -1)
+ {
+ pfile->_decr_refcnt ();
+ pfile = 0;
+ }
+
+ return pfile;
+}
+
+TAO_Profile *
+TAO_DIOP_Connector::make_profile (CORBA::Environment &ACE_TRY_ENV)
+{
+ // The endpoint should be of the form:
+ // N.n@host:port/object_key
+ // or:
+ // host:port/object_key
+
+ TAO_Profile *profile = 0;
+ ACE_NEW_THROW_EX (profile,
+ TAO_DIOP_Profile (this->orb_core ()),
+ CORBA::NO_MEMORY (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_CHECK_RETURN (0);
+
+ return profile;
+}
+
+int
+TAO_DIOP_Connector::check_prefix (const char *endpoint)
+{
+ // Check for a valid string
+ if (!endpoint || !*endpoint)
+ return -1; // Failure
+
+ const char *protocol[] = { "diop", "dioploc" };
+
+ 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 DIOP IOR
+ // DO NOT throw an exception here.
+}
+
+char
+TAO_DIOP_Connector::object_key_delimiter (void) const
+{
+ return TAO_DIOP_Profile::object_key_delimiter_;
+}
+
+int
+TAO_DIOP_Connector::init_tcp_properties (void)
+{
+ // @@ Michael: We have not TCP, so we have no TCP properties.
+ return 0;
+}
+
+
+// ****************************************************************
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+
+template class ACE_Hash <ACE_INET_Addr>;
+template class ACE_Equal_To <ACE_INET_Addr>;
+template class ACE_Hash_Map_Manager_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash <ACE_INET_Addr>, ACE_Equal_To <ACE_INET_Addr>, ACE_Null_Mutex>;
+template class ACE_Hash_Map_Entry<ACE_INET_Addr, TAO_DIOP_Connection_Handler *>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate ACE_Hash <ACE_INET_Addr>;
+#pragma instantiate ACE_Equal_To <ACE_INET_Addr>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_INET_Addr, TAO_DIOP_Connection_Handler *, ACE_Hash <ACE_INET_Addr>, ACE_Equal_To <ACE_INET_Addr>, ACE_Null_Mutex>
+#pragma instantiate ACE_Hash_Map_Entry<ACE_INET_Addr, TAO_DIOP_Connection_Handler *>;
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Connector.h b/TAO/tao/Strategies/DIOP_Connector.h
new file mode 100644
index 00000000000..71b97ae529d
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Connector.h
@@ -0,0 +1,103 @@
+// This may look like C, but it's really -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DIOP_Connector.h
+ *
+ * $Id$
+ *
+ * DIOP specific connector processing
+ *
+ * @author Michael Kircher
+ */
+//=============================================================================
+
+#ifndef TAO_DIOP_CONNECTOR_H
+#define TAO_DIOP_CONNECTOR_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Pluggable.h"
+#include "DIOP_Connection_Handler.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+// ****************************************************************
+
+/**
+ * @class TAO_DIOP_Connector
+ *
+ * @brief DIOP-specific Connector bridge for pluggable protocols.
+ *
+ * Concrete instance of the TAO_Connector class. Responsible
+ * for establishing a connection with a server and is called from the
+ * Connector_Registory.
+ */
+class TAO_Strategies_Export TAO_DIOP_Connector : public TAO_Connector
+{
+public:
+ // = Initialization and termination methods.
+ /// Constructor.
+ TAO_DIOP_Connector (CORBA::Boolean flag = 0);
+
+ /// Destructor.
+ ~TAO_DIOP_Connector (void);
+
+ // = The TAO_Connector methods, please check the documentation on
+ // Pluggable.h
+ int open (TAO_ORB_Core *orb_core);
+ int close (void);
+ int connect (TAO_Transport_Descriptor_Interface *desc,
+ TAO_Transport *&transport,
+ ACE_Time_Value *max_wait_time,
+ CORBA::Environment &ACE_TRY_ENV);
+ 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;
+
+protected:
+
+ /// = More TAO_Connector methods, please check the documentation on
+ /// Pluggable.h
+ virtual TAO_Profile * make_profile (CORBA::Environment &ACE_TRY_ENV);
+
+ /// Obtain tcp properties that must be used by this connector, i.e.,
+ /// initialize <tcp_properties_>.
+ int init_tcp_properties (void);
+
+protected:
+
+ /// TCP configuration properties to be used for all
+ /// connections established by this connector.
+ TAO_DIOP_Properties tcp_properties_;
+
+ /// Do we need to use a GIOP_Lite for sending messages?
+ CORBA::Boolean lite_flag_;
+
+private:
+ // @@ Michael: UDP Addition
+ ACE_Hash_Map_Manager_Ex < ACE_INET_Addr,
+ TAO_DIOP_Connection_Handler *,
+ ACE_Hash < ACE_INET_Addr >,
+ ACE_Equal_To < ACE_INET_Addr >,
+ ACE_Null_Mutex > svc_handler_table_;
+
+ typedef ACE_Hash_Map_Iterator_Ex < ACE_INET_Addr,
+ TAO_DIOP_Connection_Handler *,
+ ACE_Hash < ACE_INET_Addr >,
+ ACE_Equal_To < ACE_INET_Addr >,
+ ACE_Null_Mutex > SvcHandlerIterator;
+};
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_CONNECTOR_H */
diff --git a/TAO/tao/Strategies/DIOP_Endpoint.cpp b/TAO/tao/Strategies/DIOP_Endpoint.cpp
new file mode 100644
index 00000000000..9f059a1ebc3
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Endpoint.cpp
@@ -0,0 +1,192 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+
+#include "DIOP_Endpoint.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "DIOP_Connection_Handler.h"
+#include "tao/debug.h"
+
+ACE_RCSID(tao, DIOP_Endpoint, "$Id$")
+
+
+#if !defined (__ACE_INLINE__)
+# include "DIOP_Endpoint.i"
+#endif /* __ACE_INLINE__ */
+
+TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const ACE_INET_Addr &addr,
+ int use_dotted_decimal_addresses)
+ : TAO_Endpoint (TAO_TAG_UDP_PROFILE),
+ host_ (),
+ port_ (0),
+ object_addr_ (addr),
+ /* hint_ (0), */
+ next_ (0)
+{
+ this->set (addr, use_dotted_decimal_addresses);
+}
+
+TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
+ CORBA::UShort port,
+ const ACE_INET_Addr &addr)
+ : TAO_Endpoint (TAO_TAG_UDP_PROFILE),
+ host_ (),
+ port_ (port),
+ object_addr_ (addr),
+ /* hint_ (0), */
+ next_ (0)
+{
+ if (host != 0)
+ this->host_ = host;
+}
+
+TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (void)
+ : TAO_Endpoint (TAO_TAG_UDP_PROFILE),
+ host_ (),
+ port_ (0),
+ object_addr_ (),
+ /* hint_ (0), */
+ next_ (0)
+{
+}
+
+TAO_DIOP_Endpoint::TAO_DIOP_Endpoint (const char *host,
+ CORBA::UShort port,
+ CORBA::Short priority)
+ : TAO_Endpoint (TAO_TAG_UDP_PROFILE),
+ host_ (),
+ port_ (port),
+ object_addr_ (),
+ /* hint_ (0),*/
+ next_ (0)
+{
+ if (host != 0)
+ this->host_ = host;
+
+ this->object_addr_.set_type (-1);
+ this->priority (priority);
+}
+
+TAO_DIOP_Endpoint::~TAO_DIOP_Endpoint (void)
+{
+
+}
+
+int
+TAO_DIOP_Endpoint::set (const ACE_INET_Addr &addr,
+ int use_dotted_decimal_addresses)
+{
+ char tmp_host[MAXHOSTNAMELEN + 1];
+
+ if (use_dotted_decimal_addresses
+ || addr.get_host_name (tmp_host, sizeof (tmp_host)) != 0)
+ {
+ const char *tmp = addr.get_host_addr ();
+ if (tmp == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Endpoint::set ")
+ ACE_TEXT ("- %p\n\n"),
+ ACE_TEXT ("cannot determine hostname")));
+ return -1;
+ }
+ else
+ this->host_ = tmp;
+ }
+ else
+ this->host_ = CORBA::string_dup (tmp_host);
+
+ this->port_ = addr.get_port_number();
+
+ return 0;
+}
+
+int
+TAO_DIOP_Endpoint::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_DIOP_Endpoint::host (const char *h)
+{
+ this->host_ = h;
+
+ return this->host_.in ();
+}
+
+void
+TAO_DIOP_Endpoint::reset_hint (void)
+{
+ // Commented out for the time being....
+ /* if (this->hint_)
+ this->hint_->cleanup_hint ((void **) &this->hint_); */
+}
+
+TAO_Endpoint *
+TAO_DIOP_Endpoint::next (void)
+{
+ return this->next_;
+}
+
+TAO_Endpoint *
+TAO_DIOP_Endpoint::duplicate (void)
+{
+ // @@ Bala, we probably need to make sure that the duplicate has the
+ // same priority as the original. Although it does not matter in
+ // the context this method is currently used, if somebody ends up
+ // using this method for some other purpose later, this will be a
+ // seed for bugs.
+
+ TAO_DIOP_Endpoint *endpoint = 0;
+
+ ACE_NEW_RETURN (endpoint,
+ TAO_DIOP_Endpoint (this->host_.in (),
+ this->port_,
+ this->object_addr_),
+ 0);
+
+ return endpoint;
+}
+
+CORBA::Boolean
+TAO_DIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
+{
+ TAO_Endpoint *endpt = ACE_const_cast (TAO_Endpoint *,
+ other_endpoint);
+
+ TAO_DIOP_Endpoint *endpoint = ACE_dynamic_cast (TAO_DIOP_Endpoint *,
+ endpt);
+ if (endpoint == 0)
+ return 0;
+
+ return
+ this->port_ == endpoint->port_
+ && ACE_OS::strcmp (this->host_.in (), endpoint->host_.in ()) == 0;
+}
+
+CORBA::ULong
+TAO_DIOP_Endpoint::hash (void)
+{
+ return
+ ACE::hash_pjw (this->host_.in ())
+ + this->port_;
+}
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Endpoint.h b/TAO/tao/Strategies/DIOP_Endpoint.h
new file mode 100644
index 00000000000..ea1a83eced3
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Endpoint.h
@@ -0,0 +1,144 @@
+// This may look like C, but it's really -*- C++ -*-
+
+
+//=============================================================================
+/**
+ * @file DIOP_Endpoint.h
+ *
+ * $Id$
+ *
+ * DIOP implementation of PP Framework Endpoint interface.
+ *
+ * @author Michael Kircher
+ */
+//=============================================================================
+
+
+#ifndef TAO_DIOP_ENDPOINT_H
+#define TAO_DIOP_ENDPOINT_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Endpoint.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/ORB.h"
+#include "ace/INET_Addr.h"
+#include "strategies_export.h"
+
+
+class TAO_DIOP_Connection_Handler;
+
+/**
+ * @class TAO_DIOP_Endpoint
+ *
+ * @brief TAO_DIOP_Endpoint
+ *
+ * DIOP-specific implementation of PP Framework Endpoint interface.
+ */
+class TAO_Strategies_Export TAO_DIOP_Endpoint : public TAO_Endpoint
+{
+public:
+
+ friend class TAO_DIOP_Profile;
+ friend class TAO_SSLIOP_Profile;
+
+ // = Initialization and termination methods.
+
+ /// Default constructor.
+ TAO_DIOP_Endpoint (void);
+
+ /// Constructor. This is the most efficient constructor since it
+ /// does not require any address resolution processing.
+ TAO_DIOP_Endpoint (const char *host,
+ CORBA::UShort port,
+ const ACE_INET_Addr &addr);
+
+ /// Constructor.
+ TAO_DIOP_Endpoint (const ACE_INET_Addr &addr,
+ int use_dotted_decimal_addresses);
+
+ /// Constructor. This constructor is used when decoding endpoints.
+ TAO_DIOP_Endpoint (const char *host,
+ CORBA::UShort port,
+ CORBA::Short priority);
+
+ /// Destructor.
+ ~TAO_DIOP_Endpoint (void);
+
+ // = Implementation of abstract TAO_Endpoint methods. See
+ // Endpoint.h for their documentation.
+
+ virtual TAO_Endpoint *next (void);
+ virtual int addr_to_string (char *buffer, size_t length);
+ virtual void reset_hint (void);
+
+ /// Makes a copy of <this>
+ virtual TAO_Endpoint *duplicate (void);
+
+ /// Return true if this endpoint is equivalent to <other_endpoint>. Two
+ /// endpoints are equivalent iff their port and host are the same.
+ CORBA::Boolean is_equivalent (const TAO_Endpoint *other_endpoint);
+
+ /// Return a hash value for this object.
+ CORBA::ULong hash (void);
+
+ // Allocates memory and returns a copy of <this>
+
+ // = DIOP_Endpoint-specific methods.
+
+ /// Return a reference to the <object_addr>.
+ const ACE_INET_Addr &object_addr (void) const;
+
+ /// Return a pointer to the host string. This object maintains
+ /// ownership of this string.
+ const char *host (void) const;
+
+ /// Copy the string <h> into <host_> and return the resulting pointer.
+ /// This object maintains ownership of this string.
+ const char *host (const char *h);
+
+ /// Return the port number.
+ CORBA::UShort port (void) const;
+
+ /// Set the port number.
+ CORBA::UShort port (CORBA::UShort p);
+
+ //TAO_DIOP_Connection_Handler *&hint (void);
+ // Access to our <hint_>.
+
+private:
+
+ /// Helper method for setting INET_Addr.
+ int set (const ACE_INET_Addr &addr,
+ int use_dotted_decimal_addresses);
+
+ /// String representing the host name.
+ CORBA::String_var host_;
+
+ /// TCP port number.
+ CORBA::UShort port_;
+
+ /// Cached instance of <ACE_INET_Addr> for use in making
+ /// invocations, etc.
+ ACE_INET_Addr object_addr_;
+
+ /// DIOP Endpoints can be stringed into a list. Return the next
+ /// endpoint in the list, if any.
+ TAO_DIOP_Endpoint *next_;
+};
+
+#if defined (__ACE_INLINE__)
+# include "DIOP_Endpoint.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_PROFILE_H */
diff --git a/TAO/tao/Strategies/DIOP_Endpoint.i b/TAO/tao/Strategies/DIOP_Endpoint.i
new file mode 100644
index 00000000000..ad9b9d97a30
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Endpoint.i
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+// $Id$
+
+ACE_INLINE const ACE_INET_Addr &
+TAO_DIOP_Endpoint::object_addr (void) const
+{
+ // The object_addr_ is initialized here, rather than at IOR decode
+ // time for several reasons:
+ // 1. A request on the object may never be invoked.
+ // 2. The DNS setup may have changed dynamically.
+ // ...etc..
+
+ // We need to modify the object_addr_ in this method. Do so using a
+ // non-const copy of the <this> pointer.
+ TAO_DIOP_Endpoint *endpoint =
+ ACE_const_cast (TAO_DIOP_Endpoint *,
+ this);
+
+ if (this->object_addr_.get_type () != AF_INET
+ && endpoint->object_addr_.set (this->port_,
+ this->host_.in ()) == -1)
+ {
+ // If this call fails, it most likely due a hostname lookup
+ // failure caused by a DNS misconfiguration. If a request is
+ // made to the object at the given host and port, then a
+ // CORBA::TRANSIENT() exception should be thrown.
+
+ // Invalidate the ACE_INET_Addr. This is used as a flag to
+ // denote that ACE_INET_Addr initialization failed.
+ endpoint->object_addr_.set_type (-1);
+ }
+
+ return this->object_addr_;
+}
+
+ACE_INLINE const char *
+TAO_DIOP_Endpoint::host (void) const
+{
+ return this->host_.in ();
+}
+
+ACE_INLINE CORBA::UShort
+TAO_DIOP_Endpoint::port (void) const
+{
+ return this->port_;
+}
+
+ACE_INLINE CORBA::UShort
+TAO_DIOP_Endpoint::port (CORBA::UShort p)
+{
+ return this->port_ = p;
+}
diff --git a/TAO/tao/Strategies/DIOP_Factory.cpp b/TAO/tao/Strategies/DIOP_Factory.cpp
new file mode 100644
index 00000000000..3d0d8cc1f7b
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Factory.cpp
@@ -0,0 +1,90 @@
+// $Id$
+
+#include "DIOP_Factory.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "DIOP_Acceptor.h"
+#include "DIOP_Connector.h"
+
+ACE_RCSID(TAO_Strategies, DIOP_Factory, "$Id$")
+
+static const char prefix_[] = "diop";
+
+TAO_DIOP_Protocol_Factory::TAO_DIOP_Protocol_Factory (void)
+ : TAO_Protocol_Factory (TAO_TAG_UDP_PROFILE),
+ major_ (TAO_DEF_GIOP_MAJOR),
+ minor_ (TAO_DEF_GIOP_MINOR)
+{
+}
+
+TAO_DIOP_Protocol_Factory::~TAO_DIOP_Protocol_Factory (void)
+{
+}
+
+int
+TAO_DIOP_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_DIOP_Protocol_Factory::prefix (void) const
+{
+ return ::prefix_;
+}
+
+char
+TAO_DIOP_Protocol_Factory::options_delimiter (void) const
+{
+ return '/';
+}
+
+TAO_Acceptor *
+TAO_DIOP_Protocol_Factory::make_acceptor (void)
+{
+ TAO_Acceptor *acceptor = 0;
+
+ ACE_NEW_RETURN (acceptor,
+ TAO_DIOP_Acceptor,
+ 0);
+
+ return acceptor;
+}
+
+int
+TAO_DIOP_Protocol_Factory::init (int /* argc */,
+ char* /* argv */ [])
+{
+ return 0;
+}
+
+TAO_Connector *
+TAO_DIOP_Protocol_Factory::make_connector (void)
+{
+ TAO_Connector *connector = 0;
+
+ ACE_NEW_RETURN (connector,
+ TAO_DIOP_Connector,
+ 0);
+ return connector;
+}
+
+int
+TAO_DIOP_Protocol_Factory::requires_explicit_endpoint (void) const
+{
+ return 0;
+}
+
+ACE_STATIC_SVC_DEFINE (TAO_DIOP_Protocol_Factory,
+ ACE_TEXT ("DIOP_Factory"),
+ ACE_SVC_OBJ_T,
+ &ACE_SVC_NAME (TAO_DIOP_Protocol_Factory),
+ ACE_Service_Type::DELETE_THIS |
+ ACE_Service_Type::DELETE_OBJ,
+ 0)
+
+ACE_FACTORY_DEFINE (TAO_Strategies, TAO_DIOP_Protocol_Factory)
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Factory.h b/TAO/tao/Strategies/DIOP_Factory.h
new file mode 100644
index 00000000000..a469c29be6e
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Factory.h
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file DIOP_Factory.h
+ *
+ * $Id$
+ *
+ * @author Michael Kircher
+ */
+//=============================================================================
+
+
+#ifndef TAO_DIOP_FACTORY_H
+#define TAO_DIOP_FACTORY_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Protocol_Factory.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Service_Config.h"
+#include "strategies_export.h"
+
+class TAO_Acceptor;
+class TAO_Connector;
+
+class TAO_Strategies_Export TAO_DIOP_Protocol_Factory : public TAO_Protocol_Factory
+{
+public:
+ TAO_DIOP_Protocol_Factory (void);
+ virtual ~TAO_DIOP_Protocol_Factory (void);
+
+ // = Service Configurator hooks.
+ /// Dynamic linking hook
+ virtual int init (int argc, char* argv[]);
+
+ /// Verify prefix is a match
+ virtual int match_prefix (const ACE_CString &prefix);
+
+ /// Returns the prefix used by the protocol.
+ virtual const char *prefix (void) const;
+
+ /// Return the character used to mark where an endpoint ends and
+ /// where its options begin.
+ virtual char options_delimiter (void) const;
+
+ // = 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:
+ /// Changing the version number can be used to provide backwards
+ /// compatibility with old clients.
+ int major_;
+ int minor_;
+};
+
+ACE_STATIC_SVC_DECLARE (TAO_DIOP_Protocol_Factory)
+ACE_FACTORY_DECLARE (TAO_Strategies, TAO_DIOP_Protocol_Factory)
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_FACTORY_H */
diff --git a/TAO/tao/Strategies/DIOP_Profile.cpp b/TAO/tao/Strategies/DIOP_Profile.cpp
new file mode 100644
index 00000000000..f13a7205458
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Profile.cpp
@@ -0,0 +1,677 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+
+#include "DIOP_Profile.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/CDR.h"
+#include "tao/Environment.h"
+#include "tao/ORB.h"
+#include "tao/ORB_Core.h"
+#include "tao/debug.h"
+#include "tao/iiop_endpoints.h"
+
+ACE_RCSID (DIOP,
+ DIOP_Profile,
+ "$Id$")
+
+#if !defined (__ACE_INLINE__)
+# include "DIOP_Profile.i"
+#endif /* __ACE_INLINE__ */
+
+static const char prefix_[] = "diop";
+
+const char TAO_DIOP_Profile::object_key_delimiter_ = '/';
+
+char
+TAO_DIOP_Profile::object_key_delimiter (void) const
+{
+ return TAO_DIOP_Profile::object_key_delimiter_;
+}
+
+
+TAO_DIOP_Profile::TAO_DIOP_Profile (const ACE_INET_Addr &addr,
+ const TAO_ObjectKey &object_key,
+ const TAO_GIOP_Message_Version &version,
+ TAO_ORB_Core *orb_core)
+ : TAO_Profile (TAO_TAG_UDP_PROFILE, orb_core, version),
+ endpoint_ (addr,
+ orb_core->orb_params ()->use_dotted_decimal_addresses ()),
+ count_ (1),
+ object_key_ (object_key),
+ tagged_profile_ ()
+{
+}
+
+TAO_DIOP_Profile::TAO_DIOP_Profile (const char* host,
+ CORBA::UShort port,
+ const TAO_ObjectKey &object_key,
+ const ACE_INET_Addr &addr,
+ const TAO_GIOP_Message_Version &version,
+ TAO_ORB_Core *orb_core)
+ : TAO_Profile (TAO_TAG_UDP_PROFILE, orb_core, version),
+ endpoint_ (host, port, addr),
+ count_ (1),
+ object_key_ (object_key),
+ tagged_profile_ ()
+{
+}
+
+TAO_DIOP_Profile::TAO_DIOP_Profile (TAO_ORB_Core *orb_core)
+ : TAO_Profile (TAO_TAG_UDP_PROFILE,
+ orb_core,
+ TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
+ endpoint_ (),
+ count_ (1),
+ object_key_ (),
+ tagged_profile_ ()
+{
+}
+
+TAO_DIOP_Profile::~TAO_DIOP_Profile (void)
+{
+ // Clean up the list of endpoints since we own it.
+ // Skip the head, since it is not dynamically allocated.
+ TAO_Endpoint *tmp = 0;
+
+ for (TAO_Endpoint *next = this->endpoint ()->next ();
+ next != 0;
+ next = tmp)
+ {
+ tmp = next->next ();
+ delete next;
+ }
+}
+
+// return codes:
+// -1 -> error
+// 0 -> can't understand this version
+// 1 -> success.
+
+int
+TAO_DIOP_Profile::decode (TAO_InputCDR& cdr)
+{
+ CORBA::ULong encap_len = cdr.length ();
+
+ // Read and verify major, minor versions, ignoring DIOP profiles
+ // whose versions we don't understand.
+ CORBA::Octet major = 0, minor = 0;
+
+ if (!(cdr.read_octet (major)
+ && major == TAO_DEF_GIOP_MAJOR
+ && cdr.read_octet (minor)))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) DIOP_Profile::decode - v%d.%d\n"),
+ major,
+ minor));
+ return -1;
+ }
+
+ this->version_.major = major;
+
+ if (minor <= TAO_DEF_GIOP_MINOR)
+ this->version_.minor = minor;
+
+ // Decode host and port into the <endpoint_>.
+ if (cdr.read_string (this->endpoint_.host_.out ()) == 0
+ || cdr.read_ushort (this->endpoint_.port_) == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) DIOP_Profile::decode - ")
+ ACE_TEXT ("error while decoding host/port")));
+ return -1;
+ }
+
+ // ... and object key.
+
+ if ((cdr >> this->object_key_) == 0)
+ return -1;
+
+ // Tagged Components *only* exist after version 1.0!
+ // For GIOP 1.2, DIOP 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,
+ ACE_TEXT ("%d bytes out of %d left after DIOP profile data\n"),
+ cdr.length (),
+ encap_len));
+
+ if (this->decode_endpoints () == -1)
+ return -1;
+
+ if (cdr.good_bit ())
+ {
+ // Invalidate the object_addr_ until first access.
+ this->endpoint_.object_addr_.set_type (-1);
+
+ return 1;
+ }
+
+ return -1;
+}
+
+void
+TAO_DIOP_Profile::parse_string (const char *string,
+ CORBA::Environment &ACE_TRY_ENV)
+{
+ if (!string || !*string)
+ {
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA_SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ // 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 (CORBA::INV_OBJREF (
+ CORBA_SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ // 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_pos = ACE_OS::strchr (start, ':'); // Look for a port
+
+ char *okd = ACE_OS::strchr (start, this->object_key_delimiter_);
+
+ if (okd == 0)
+ {
+ // No object key delimiter!
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA_SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ // The default port number.
+ const char def_port [] = ":683";
+
+ // Length of port.
+ CORBA::ULong length = 0;
+
+ // Length of host string.
+ CORBA::ULong length_host = 0;
+
+ // Length of <cp>
+ CORBA::ULong length_cp =
+ ACE_OS::strlen ((const char *)okd) + sizeof (def_port);
+
+ CORBA::String_var cp = CORBA::string_alloc (length_cp);
+
+ if (cp_pos == 0)
+ {
+ // No host/port delimiter! Dont raise an exception. Use the
+ // default port No. 683
+ ACE_OS::strcpy (cp, def_port);
+ ACE_OS::strcat (cp, okd);
+
+ length =
+ ACE_OS::strlen (cp.in ()) -
+ ACE_OS::strlen ((const char *)okd) -
+ 1;
+
+ length_host =
+ ACE_OS::strlen (start) +
+ sizeof (def_port) -
+ ACE_OS::strlen (cp.in ()) -1;
+ }
+ else
+ {
+ // The port is specified:
+ cp = (const char *)cp_pos;
+
+ length =
+ ACE_OS::strlen (cp.in ())
+ - ACE_OS::strlen ((const char *)okd) + 1;
+
+ length_host =
+ ACE_OS::strlen ((const char *)start)
+ - ACE_OS::strlen (cp.in ());
+ }
+
+ CORBA::String_var tmp = CORBA::string_alloc (length);
+
+ ACE_OS::strncpy (tmp.inout (), cp.in () + 1, length);
+ tmp[length] = '\0';
+
+ this->endpoint_.port_ = (CORBA::UShort) ACE_OS::atoi (tmp.in ());
+
+ tmp = CORBA::string_alloc (length_host);
+
+ ACE_OS::strncpy (tmp.inout (), start, length_host);
+ tmp[length_host] = '\0';
+
+ this->endpoint_.host_ = tmp._retn ();
+
+ ACE_INET_Addr host_addr;
+
+ if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
+ {
+ char tmp_host [MAXHOSTNAMELEN + 1];
+
+ // If no host is specified: assign the default host : the local host.
+ if (host_addr.get_host_name (tmp_host,
+ sizeof (tmp_host)) != 0)
+ {
+ const char *tmp = host_addr.get_host_addr ();
+ if (tmp == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("DIOP_Profile::parse_string ")
+ ACE_TEXT ("- %p\n\n"),
+ ACE_TEXT ("cannot determine hostname")));
+
+ // @@ What's the right exception to throw here?
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA_SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+ this->endpoint_.host_ = tmp;
+ }
+ else
+ {
+ this->endpoint_.host_ = (const char *) tmp_host;
+ }
+ }
+
+ if (this->endpoint_.object_addr_.set (this->endpoint_.port_,
+ this->endpoint_.host_.in ()) == -1)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("Error Occured !")
+ ACE_TEXT ("TAO (%P|%t) DIOP_Profile::parse_string - \n")
+ ACE_TEXT ("TAO (%P|%t) ACE_INET_Addr::set () failed")));
+ }
+
+ // @@ What's the right exception to throw here?
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA_SystemException::_tao_minor_code (
+ TAO_DEFAULT_MINOR_CODE,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ start = ++okd; // increment past the object key separator
+
+ TAO_ObjectKey::decode_string_to_sequence (this->object_key_, start);
+}
+
+CORBA::Boolean
+TAO_DIOP_Profile::is_equivalent (const TAO_Profile *other_profile)
+{
+
+ if (other_profile->tag () != TAO_TAG_UDP_PROFILE)
+ return 0;
+
+ const TAO_DIOP_Profile *op =
+ ACE_dynamic_cast (const TAO_DIOP_Profile *, other_profile);
+
+
+ if (!(this->object_key_ == op->object_key_
+ && this->version_ == op->version_
+ && this->count_ == op->count_))
+ return 0;
+
+ // Check endpoints equivalence.
+ const TAO_DIOP_Endpoint *other_endp = &op->endpoint_;
+ for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
+ endp != 0;
+ endp = endp->next_)
+ {
+ if (endp->is_equivalent (other_endp))
+ other_endp = other_endp->next_;
+ else
+ return 0;
+ }
+
+ return 1;
+}
+
+CORBA::ULong
+TAO_DIOP_Profile::hash (CORBA::ULong max,
+ CORBA::Environment &)
+{
+ // Get the hashvalue for all endpoints.
+ CORBA::ULong hashval = 0;
+ for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
+ endp != 0;
+ endp = endp->next_)
+ {
+ hashval += endp->hash ();
+ }
+
+ hashval += this->version_.minor;
+ hashval += this->tag ();
+
+ if (this->object_key_.length () >= 4)
+ {
+ hashval += this->object_key_ [1];
+ hashval += this->object_key_ [3];
+ }
+
+ return hashval % max;
+}
+
+TAO_Endpoint*
+TAO_DIOP_Profile::endpoint (void)
+{
+ return &this->endpoint_;
+}
+
+size_t
+TAO_DIOP_Profile::endpoint_count (void)
+{
+ return this->count_;
+}
+
+void
+TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
+{
+ endp->next_ = this->endpoint_.next_;
+ this->endpoint_.next_ = endp;
+
+ this->count_++;
+}
+
+char *
+TAO_DIOP_Profile::to_string (CORBA::Environment &)
+{
+ CORBA::String_var key;
+ TAO_ObjectKey::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->endpoint_.host ()) +
+ 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->endpoint_.host (),
+ this->endpoint_.port (),
+ this->object_key_delimiter_,
+ key.in ());
+ return buf;
+}
+
+const char *
+TAO_DIOP_Profile::prefix (void)
+{
+ return ::prefix_;
+}
+
+int
+TAO_DIOP_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 ()->output_cdr_msgblock_allocator (),
+ this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
+ TAO_DEF_GIOP_MAJOR,
+ TAO_DEF_GIOP_MINOR,
+ this->orb_core ()->to_iso8859 (),
+ this->orb_core ()->to_unicode ());
+
+
+ // Create the profile body
+ this->create_profile_body (encap);
+
+ // write the encapsulation as an octet sequence...
+
+ stream << CORBA::ULong (encap.total_length ());
+ stream.write_octet_array_mb (encap.begin ());
+
+ return 1;
+}
+
+
+IOP::TaggedProfile &
+TAO_DIOP_Profile::create_tagged_profile (void)
+{
+ // Check whether we have already created the TaggedProfile
+ if (this->tagged_profile_.profile_data.get_buffer () == 0)
+ {
+ // As we have not created we will now create the TaggedProfile
+ this->tagged_profile_.tag = TAO_TAG_UDP_PROFILE;
+
+ // 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 ()->output_cdr_msgblock_allocator (),
+ this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
+ TAO_DEF_GIOP_MAJOR,
+ TAO_DEF_GIOP_MINOR,
+ this->orb_core ()->to_iso8859 (),
+ this->orb_core ()->to_unicode ());
+
+ // Create the profile body
+ this->create_profile_body (encap);
+
+ CORBA::ULong length =
+ ACE_static_cast(CORBA::ULong,encap.total_length ());
+
+#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
+ // Place the message block in to the Sequence of Octets that we
+ // have
+ this->tagged_profile_.profile_data.replace (length,
+ encap.begin ());
+#else
+ this->tagged_profile_.profile_data.length (length);
+ CORBA::Octet *buffer =
+ this->tagged_profile_.profile_data.get_buffer ();
+ for (const ACE_Message_Block *i = encap.begin ();
+ i != encap.end ();
+ i = i->next ())
+ {
+ ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
+ buffer += i->length ();
+ }
+#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
+ }
+
+ return this->tagged_profile_;
+}
+
+void
+TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
+{
+ 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->endpoint_.host ());
+
+ // UNSIGNED SHORT port number
+ encap.write_ushort (this->endpoint_.port ());
+
+ // OCTET SEQUENCE for object key
+ encap << this->object_key_;
+
+ if (this->version_.major > 1
+ || this->version_.minor > 0)
+ this->tagged_components ().encode (encap);
+}
+
+int
+TAO_DIOP_Profile::encode_endpoints (void)
+{
+ // Create a data structure and fill it with endpoint info for wire
+ // transfer.
+ // We include information for the head of the list
+ // together with other endpoints because even though its addressing
+ // info is transmitted using standard ProfileBody components, its
+ // priority is not!
+
+ TAO_IIOPEndpointSequence endpoints;
+ endpoints.length (this->count_);
+
+ const TAO_DIOP_Endpoint *endpoint = &this->endpoint_;
+ for (size_t i = 0;
+ i < this->count_;
+ ++i)
+ {
+ endpoints[i].host = endpoint->host ();
+ endpoints[i].port = endpoint->port ();
+ endpoints[i].priority = endpoint->priority ();
+
+ endpoint = endpoint->next_;
+ }
+
+ // Encode the data structure.
+ TAO_OutputCDR out_cdr;
+ if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
+ == 0)
+ || (out_cdr << endpoints) == 0)
+ return -1;
+ CORBA::ULong length = out_cdr.total_length ();
+
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = TAO_TAG_ENDPOINTS;
+ tagged_component.component_data.length (length);
+ CORBA::Octet *buf =
+ tagged_component.component_data.get_buffer ();
+
+ for (const ACE_Message_Block *iterator = out_cdr.begin ();
+ iterator != 0;
+ iterator = iterator->cont ())
+ {
+ CORBA::ULong i_length = iterator->length ();
+ ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
+
+ buf += i_length;
+ }
+
+ // Add component with encoded endpoint data to this profile's
+ // TaggedComponents.
+ tagged_components_.set_component (tagged_component);
+
+ return 0;
+}
+
+int
+TAO_DIOP_Profile::decode_endpoints (void)
+{
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = TAO_TAG_ENDPOINTS;
+
+ if (this->tagged_components_.get_component (tagged_component))
+ {
+ const CORBA::Octet *buf =
+ tagged_component.component_data.get_buffer ();
+
+ TAO_InputCDR in_cdr (ACE_reinterpret_cast (const char*, buf),
+ tagged_component.component_data.length ());
+
+ // Extract the Byte Order.
+ CORBA::Boolean byte_order;
+ if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
+ return -1;
+ in_cdr.reset_byte_order (ACE_static_cast(int, byte_order));
+
+ // Extract endpoints sequence.
+ TAO_IIOPEndpointSequence endpoints;
+
+ if ((in_cdr >> endpoints) == 0)
+ return -1;
+
+ // Get the priority of the first endpoint (head of the list.
+ // It's other data is extracted as part of the standard profile
+ // decoding.
+ this->endpoint_.priority (endpoints[0].priority);
+
+ // Use information extracted from the tagged component to
+ // populate the profile. Skip the first endpoint, since it is
+ // always extracted through standard profile body. Also, begin
+ // from the end of the sequence to preserve endpoint order,
+ // since <add_endpoint> method reverses the order of endpoints
+ // in the list.
+ for (CORBA::ULong i = endpoints.length () - 1;
+ i > 0;
+ --i)
+ {
+ TAO_DIOP_Endpoint *endpoint = 0;
+ ACE_NEW_RETURN (endpoint,
+ TAO_DIOP_Endpoint (endpoints[i].host,
+ endpoints[i].port,
+ endpoints[i].priority),
+ -1);
+
+ this->add_endpoint (endpoint);
+ }
+ }
+
+ return 0;
+}
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Profile.h b/TAO/tao/Strategies/DIOP_Profile.h
new file mode 100644
index 00000000000..4dc557db187
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Profile.h
@@ -0,0 +1,206 @@
+// This may look like C, but it's really -*- C++ -*-
+
+
+//=============================================================================
+/**
+ * @file DIOP_Profile.h
+ *
+ * $Id$
+ *
+ * DIOP profile specific processing
+ *
+ *
+ * @author Michael Kircher
+ */
+//=============================================================================
+
+
+#ifndef TAO_DIOP_PROFILE_H
+#define TAO_DIOP_PROFILE_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Profile.h"
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Object_KeyC.h"
+#include "DIOP_Endpoint.h"
+
+#include "ace/Synch.h"
+
+
+// TAO DIOP_Profile concrete Profile definitions
+/**
+ * @class TAO_DIOP_Profile
+ *
+ * @brief This class defines the protocol specific attributes required
+ * for locating ORBs over a TCP/IP network.
+ *
+ * This class defines the DIOP profile as specified in the CORBA
+ * specification.
+ */
+class TAO_Strategies_Export TAO_DIOP_Profile : public TAO_Profile
+{
+public:
+ /// The object key delimiter that DIOP uses or expects.
+ static const char object_key_delimiter_;
+ virtual char object_key_delimiter (void) const;
+
+ /// Return the char string prefix.
+ static const char *prefix (void);
+
+ /// Profile constructor, same as above except the object_key has
+ /// already been marshaled.
+ TAO_DIOP_Profile (const ACE_INET_Addr &addr,
+ const TAO_ObjectKey &object_key,
+ const TAO_GIOP_Message_Version &version,
+ TAO_ORB_Core *orb_core);
+
+ /// Profile constructor, this is the most efficient since it
+ /// doesn't require any address resolution processing.
+ TAO_DIOP_Profile (const char *host,
+ CORBA::UShort port,
+ const TAO_ObjectKey &object_key,
+ const ACE_INET_Addr &addr,
+ const TAO_GIOP_Message_Version &version,
+ TAO_ORB_Core *orb_core);
+
+
+ /// Profile constructor, default.
+ TAO_DIOP_Profile (TAO_ORB_Core *orb_core);
+
+ /// Destructor is to be called only through <_decr_refcnt>.
+ ~TAO_DIOP_Profile (void);
+
+ /// Initialize this object using the given input string.
+ /// Url-style string contain only one endpoint.
+ virtual void parse_string (const char *string,
+ CORBA::Environment &ACE_TRY_ENV);
+
+ /**
+ * Return a string representation for this profile.
+ * client must deallocate memory.
+ * This is used to create url-style reference. Only one
+ * endpoint is included into the string.
+ */
+ virtual char * to_string (CORBA::Environment &ACE_TRY_ENV);
+
+ /// Initialize this object using the given CDR octet string.
+ virtual int decode (TAO_InputCDR& cdr);
+
+ /// Encode this profile in a stream, i.e. marshal it.
+ virtual int encode (TAO_OutputCDR &stream) const;
+
+ /**
+ * Encodes this profile's endpoints into a tagged component.
+ * This is done only if RTCORBA is enabled, since currently this is
+ * the only case when we have more than one endpoint per profile.
+ * Returns 0 on success and -1 on failure.
+ *
+ * Endpoints are transmitted using TAO-proprietory tagged component.
+ * Component tag is TAO_TAG_ENDPOINTS and component data is an
+ * encapsulation of a sequence of structs, each representing a
+ * single endpoint. Data format is specified in iiop_endpoins.pidl.
+ *
+ * Multiple TAG_ALTERNATE_DIOP_ADDRESS components can be used
+ * instead of a single proprietory component to transmit multiple
+ * endpoints. This is somewhat slower and less convenient. Also,
+ * TAG_ALTERNATE_DIOP_ADDRESS does not provide for transmission of
+ * endpoint priorities.
+ *
+ */
+ virtual int encode_endpoints (void);
+
+ /// @@ deprecated. return a reference to the Object Key.
+ virtual const TAO_ObjectKey &object_key (void) const;
+
+ /// Return a pointer to the Object Key. The caller owns the memory
+ /// allocated for the returned key.
+ virtual TAO_ObjectKey *_key (void) const;
+
+ /// Return pointer to the head of this profile's endpoints list.
+ virtual TAO_Endpoint *endpoint (void);
+
+ /// Return how many endpoints this profile contains.
+ virtual size_t endpoint_count (void);
+
+ /**
+ * Add <endp> to this profile's list of endpoints (it is inserted
+ * next to the head of the list). This profiles takes ownership of
+ * <endp>.
+ */
+ void add_endpoint (TAO_DIOP_Endpoint *endp);
+
+ /**
+ * Return true if this profile is equivalent to other_profile. Two
+ * profiles are equivalent iff their tag, object_key, version and
+ * all endpoints are the same.
+ */
+ virtual CORBA::Boolean is_equivalent (const TAO_Profile *other_profile);
+
+ /// Return a hash value for this object.
+ virtual CORBA::ULong hash (CORBA::ULong max,
+ CORBA::Environment &ACE_TRY_ENV);
+
+ /// Please refer to Profile.h for the documentation of this
+ /// function.
+ virtual IOP::TaggedProfile &create_tagged_profile (void);
+
+private:
+
+ /// Creates an encapsulation of the ProfileBody struct in the <cdr>
+ void create_profile_body (TAO_OutputCDR &cdr) const;
+
+ /**
+ * Helper for <decode>. Decodes endpoints from a tagged component.
+ * Decode only if RTCORBA is enabled. Furthermore, we may not find
+ * TAO_TAG_ENDPOINTS component, e.g., if we are talking to nonRT
+ * version of TAO or some other ORB. This is not an error, and we
+ * must proceed. Return 0 on success and -1 on failure.
+ */
+ int decode_endpoints (void);
+
+protected:
+
+ /**
+ * Head of this profile's list of endpoints. This endpoint is not
+ * dynamically allocated because a profile always contains at least
+ * one endpoint.
+ *
+ * Currently, a profile contains more than one endpoint, i.e.,
+ * list contains more than just the head, only when RTCORBA is enabled.
+ * However, in the near future, this will be used in nonRT
+ * mode as well, e.g., to support TAG_ALTERNATE_DIOP_ADDRESS
+ * feature.
+ * Addressing info of the default endpoint, i.e., head of the list,
+ * is transmitted using standard DIOP ProfileBody components. See
+ * <encode_endpoints> method documentation above for how the rest of
+ * the endpoint list is transmitted.
+ */
+ TAO_DIOP_Endpoint endpoint_;
+
+ /// Number of endpoints in the list headed by <endpoint_>.
+ size_t count_;
+
+private:
+
+ /// object_key associated with this profile.
+ TAO_ObjectKey object_key_;
+
+ /// Our tagged profile
+ IOP::TaggedProfile tagged_profile_;
+};
+
+#if defined (__ACE_INLINE__)
+# include "DIOP_Profile.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_PROFILE_H */
diff --git a/TAO/tao/Strategies/DIOP_Profile.i b/TAO/tao/Strategies/DIOP_Profile.i
new file mode 100644
index 00000000000..2c18a75ae92
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Profile.i
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+// $Id$
+
+ACE_INLINE const TAO_ObjectKey &
+TAO_DIOP_Profile::object_key (void) const
+{
+ return this->object_key_;
+}
+
+ACE_INLINE TAO_ObjectKey *
+TAO_DIOP_Profile::_key (void) const
+{
+ TAO_ObjectKey *key = 0;
+
+ ACE_NEW_RETURN (key,
+ TAO_ObjectKey (this->object_key_),
+ 0);
+
+ return key;
+}
+
+
+
+
diff --git a/TAO/tao/Strategies/DIOP_Transport.cpp b/TAO/tao/Strategies/DIOP_Transport.cpp
new file mode 100644
index 00000000000..28bfc2c927a
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Transport.cpp
@@ -0,0 +1,546 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+#include "DIOP_Transport.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "DIOP_Connection_Handler.h"
+#include "DIOP_Acceptor.h"
+#include "DIOP_Profile.h"
+#include "tao/Acceptor_Registry.h"
+#include "tao/operation_details.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"
+#include "tao/GIOP_Message_Base.h"
+#include "tao/GIOP_Message_Lite.h"
+
+#if !defined (__ACE_INLINE__)
+# include "DIOP_Transport.i"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_RCSID (tao, DIOP_Transport, "$Id$")
+
+TAO_DIOP_Transport::TAO_DIOP_Transport (TAO_DIOP_Connection_Handler *handler,
+ TAO_ORB_Core *orb_core,
+ CORBA::Boolean flag)
+ : TAO_Transport (TAO_TAG_UDP_PROFILE,
+ orb_core)
+ , connection_handler_ (handler)
+ , messaging_object_ (0)
+{
+ // @@ Michael: Set the input CDR size to ACE_MAX_DGRAM_SIZE so that
+ // we read the whole UDP packet on a single read.
+ if (flag)
+ {
+ // Use the lite version of the protocol
+ ACE_NEW (this->messaging_object_,
+ TAO_GIOP_Message_Lite (orb_core,
+ ACE_MAX_DGRAM_SIZE));
+ }
+ else
+ {
+ // Use the normal GIOP object
+ ACE_NEW (this->messaging_object_,
+ TAO_GIOP_Message_Base (orb_core,
+ ACE_MAX_DGRAM_SIZE));
+ }
+}
+
+TAO_DIOP_Transport::~TAO_DIOP_Transport (void)
+{
+ delete this->messaging_object_;
+}
+
+ACE_Event_Handler *
+TAO_DIOP_Transport::event_handler_i (void)
+{
+ return this->connection_handler_;
+}
+
+TAO_Pluggable_Messaging *
+TAO_DIOP_Transport::messaging_object (void)
+{
+ return this->messaging_object_;
+}
+
+ssize_t
+TAO_DIOP_Transport::send_i (iovec *iov, int iovcnt,
+ size_t &bytes_transferred,
+ const ACE_Time_Value *)
+{
+ const ACE_INET_Addr &addr = this->connection_handler_->addr ();
+ ssize_t retval = this->connection_handler_->dgram ().send (iov,
+ iovcnt,
+ addr);
+ if (retval > 0)
+ bytes_transferred = retval;
+
+ // @@ Michael:
+ // Always return a positive number of bytes sent, as we do
+ // not handle sending errors in DIOP.
+ return 1;
+}
+
+ssize_t
+TAO_DIOP_Transport::recv_i (char *buf,
+ size_t len,
+ const ACE_Time_Value * /* max_wait_time */)
+{
+ ACE_INET_Addr from_addr;
+
+ ssize_t n = this->connection_handler_->dgram ().recv (buf,
+ len,
+ from_addr);
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO_DIOP_Transport::recv_i: received %d bytes from %s:%d %d\n",
+ n,
+ from_addr.get_host_name (),
+ from_addr.get_port_number (),
+ errno));
+ }
+
+ // Remember the from addr to eventually use it as remote
+ // addr for the reply.
+ this->connection_handler_->addr (from_addr);
+
+ return n;
+}
+
+
+int
+TAO_DIOP_Transport::read_process_message (ACE_Time_Value *max_wait_time,
+ int block)
+{
+ // Read the message of the socket
+ int result = this->messaging_object_->read_message (this,
+ block,
+ max_wait_time);
+
+ if (result == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - %p\n"),
+ ACE_TEXT ("DIOP_Transport::read_process_message, failure in read_message ()")));
+
+ this->tms_->connection_closed ();
+ return -1;
+ }
+ if (result < 2)
+ return result;
+
+ // Now we know that we have been able to read the complete message
+ // here.. We loop here to see whether we have read more than one
+ // message in our read.
+ // Set the result state
+ result = 1;
+
+ // See we use the reactor semantics again
+ while (result > 0)
+ {
+ result = this->process_message ();
+ }
+
+ return result;
+}
+
+
+int
+TAO_DIOP_Transport::register_handler_i (void)
+{
+ // @@ Michael:
+ //
+ // We do never register register the handler with the reactor
+ // as we never need to be informed about any incoming data,
+ // assuming we only use one-ways.
+ // If we would register and ICMP Messages would arrive, e.g
+ // due to a not reachable server, we would get informed - as this
+ // disturbs the general DIOP assumptions of not being
+ // interested in any network failures, we ignore ICMP messages.
+ return 0;
+ /*
+ // @@ 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->connection_handler_->reactor ())
+ return 0;
+
+ // Set the flag in the Connection Handler
+ this->connection_handler_->is_registered (1);
+
+
+ // Register the handler with the reactor
+ return r->register_handler (this->connection_handler_,
+ ACE_Event_Handler::READ_MASK);
+ */
+}
+
+
+int
+TAO_DIOP_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 (this->send_message (stream,
+ stub,
+ two_way,
+ max_wait_time) == -1)
+
+ return -1;
+
+ return this->idle_after_send ();
+}
+
+int
+TAO_DIOP_Transport::send_message (TAO_OutputCDR &stream,
+ TAO_Stub *stub,
+ int twoway,
+ ACE_Time_Value *max_wait_time)
+{
+ // Format the message in the stream first
+ if (this->messaging_object_->format_message (stream) != 0)
+ return -1;
+
+ // Strictly speaking, should not need to loop here because the
+ // socket never gets set to a nonblocking mode ... some Linux
+ // versions seem to need it though. Leaving it costs little.
+
+ // This guarantees to send all data (bytes) or return an error.
+ ssize_t n = this->send_message_i (stub,
+ twoway,
+ stream.begin (),
+ max_wait_time);
+
+ if (n == -1)
+ {
+ if (TAO_debug_level)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO: (%P|%t|%N|%l) closing transport %d after fault %p\n"),
+ this->id (),
+ ACE_TEXT ("send_message ()\n")));
+
+ return -1;
+ }
+
+ return 1;
+}
+
+
+
+int
+TAO_DIOP_Transport::messaging_init (CORBA::Octet major,
+ CORBA::Octet minor)
+{
+ this->messaging_object_->init (major,
+ minor);
+ return 1;
+}
+
+// @@ Frank: Hopefully DIOP doesn't need this
+/*
+int
+TAO_DIOP_Transport::tear_listen_point_list (TAO_InputCDR &cdr)
+{
+ CORBA::Boolean byte_order;
+ if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
+ return -1;
+
+ cdr.reset_byte_order (ACE_static_cast(int,byte_order));
+
+ DIOP::ListenPointList listen_list;
+ if ((cdr >> listen_list) == 0)
+ return -1;
+
+ // As we have received a bidirectional information, set the flag to
+ // 1
+ this->bidirectional_flag (1);
+ return this->connection_handler_->process_listen_point_list (listen_list);
+}
+*/
+
+int
+TAO_DIOP_Transport::process_message (void)
+{
+ // Check whether we have messages for processing
+ int retval =
+ this->messaging_object_->more_messages ();
+
+ if (retval <= 0)
+ return retval;
+
+ // Get the <message_type> that we have received
+ TAO_Pluggable_Message_Type t =
+ this->messaging_object_->message_type ();
+
+
+ int result = 0;
+ if (t == TAO_PLUGGABLE_MESSAGE_CLOSECONNECTION)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - %p\n"),
+ ACE_TEXT ("Close Connection Message recd \n")));
+
+ this->tms_->connection_closed ();
+ }
+ else if (t == TAO_PLUGGABLE_MESSAGE_REQUEST)
+ {
+ if (this->messaging_object_->process_request_message (this,
+ this->orb_core ()) == -1)
+ return -1;
+ }
+ else if (t == TAO_PLUGGABLE_MESSAGE_REPLY)
+ {
+ TAO_Pluggable_Reply_Params params (this->orb_core ());
+ if (this->messaging_object_->process_reply_message (params) == -1)
+ {
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - %p\n"),
+ ACE_TEXT ("DIOP_Transport::process_message, process_reply_message ()")));
+
+ this->messaging_object_->reset ();
+ this->tms_->connection_closed ();
+ return -1;
+ }
+
+
+ result =
+ this->tms_->dispatch_reply (params);
+
+ // @@ Somehow it seems dangerous to reset the state *after*
+ // dispatching the request, what if another threads receives
+ // another reply in the same connection?
+ // My guess is that it works as follows:
+ // - For the exclusive case there can be no such thread.
+ // - The the muxed case each thread has its own message_state.
+ // I'm pretty sure this comment is right. Could somebody else
+ // please look at it and confirm my guess?
+
+ // @@ The above comment was found in the older versions of the
+ // code. The code was also written in such a way that, when
+ // the client thread on a call from handle_input () from the
+ // reactor a call would be made on the handle_client_input
+ // (). The implementation of handle_client_input () looked so
+ // flaky. It used to create a message state upon entry in to
+ // the function using the TMS and destroy that on exit. All
+ // this was fine _theoretically_ for multiple threads. But
+ // the flakiness was originating in the implementation of
+ // get_message_state () where we were creating message state
+ // only once and dishing it out for every thread till one of
+ // them destroy's it. So, it looked broken. That has been
+ // changed. Why?. To my knowledge, the reactor does not call
+ // handle_input () on two threads at the same time. So, IMHO
+ // that defeats the purpose of creating a message state for
+ // every thread. This is just my guess. If we run in to
+ // problems this place needs to be revisited. If someone else
+ // is going to take a look please contact bala@cs.wustl.edu
+ // for details on this-- Bala
+
+
+
+ if (result == -1)
+ {
+ // Something really critical happened, we will forget about
+ // every reply on this connection.
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) : DIOP_Transport::")
+ ACE_TEXT ("process_message - ")
+ ACE_TEXT ("dispatch reply failed\n")));
+
+ this->messaging_object_->reset ();
+ this->tms_->connection_closed ();
+ return -1;
+ }
+
+ if (result == 0)
+ {
+ this->messaging_object_->reset ();
+
+ // The reply dispatcher was no longer registered.
+ // This can happened when the request/reply
+ // times out.
+ // To throw away all registered reply handlers is
+ // not the right thing, as there might be just one
+ // old reply coming in and several valid new ones
+ // pending. If we would invoke <connection_closed>
+ // we would throw away also the valid ones.
+ //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);
+ }
+ else if (t == TAO_PLUGGABLE_MESSAGE_MESSAGERROR)
+ {
+ return -1;
+ }
+
+ return 1;
+}
+
+// @@ Frank: Hopefully DIOP doesn't need this
+/*
+void
+TAO_DIOP_Transport::set_bidir_context_info (TAO_Operation_Details &opdetails)
+{
+
+ // Get a handle on to the acceptor registry
+ TAO_Acceptor_Registry * ar =
+ this->orb_core ()->acceptor_registry ();
+
+
+ // Get the first acceptor in the registry
+ TAO_AcceptorSetIterator acceptor = ar->begin ();
+
+ DIOP::ListenPointList listen_point_list;
+
+ for (;
+ acceptor != ar->end ();
+ acceptor++)
+ {
+ // Check whether it is a DIOP acceptor
+ if ((*acceptor)->tag () == TAO_TAG_UDP_PROFILE)
+ {
+ this->get_listen_point (listen_point_list,
+ *acceptor);
+ }
+ }
+
+ // We have the ListenPointList at this point. Create a output CDR
+ // stream at this point
+ TAO_OutputCDR cdr;
+
+ // Marshall the information into the stream
+ if ((cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)== 0)
+ || (cdr << listen_point_list) == 0)
+ return;
+
+ // Add this info in to the svc_list
+ opdetails.service_context ().set_context (IOP::BI_DIR_DIOP,
+ cdr);
+
+ return;
+}
+
+
+int
+TAO_DIOP_Transport::get_listen_point (
+ DIOP::ListenPointList &listen_point_list,
+ TAO_Acceptor *acceptor)
+{
+ TAO_DIOP_Acceptor *iiop_acceptor =
+ ACE_dynamic_cast (TAO_DIOP_Acceptor *,
+ acceptor );
+
+ // Get the array of endpoints serviced by <iiop_acceptor>
+ const ACE_INET_Addr *endpoint_addr =
+ iiop_acceptor->endpoints ();
+
+ // Get the count
+ size_t count =
+ iiop_acceptor->endpoint_count ();
+
+ // Get the local address of the connection
+ ACE_INET_Addr local_addr;
+
+ if (this->connection_handler_->peer ().get_local_addr (local_addr)
+ == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Could not resolve local host")
+ ACE_TEXT (" address in set_bidir_context_info () \n")),
+ -1);
+ }
+
+
+ // Note: Looks like there is no point in sending the list of
+ // endpoints on interfaces on which this connection has not
+ // been established. If this is wrong, please correct me.
+ char *local_interface = 0;
+
+ // Get the hostname for the local address
+ if (iiop_acceptor->hostname (this->orb_core_,
+ local_addr,
+ local_interface) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Could not resolve local host")
+ ACE_TEXT (" name \n")),
+ -1);
+ }
+
+ ACE_INET_Addr *tmp_addr = ACE_const_cast (ACE_INET_Addr *,
+ endpoint_addr);
+
+ for (size_t index = 0;
+ index <= count;
+ index++)
+ {
+ // Get the listen point on that acceptor if it has the same
+ // interface on which this connection is established
+ char *acceptor_interface = 0;
+
+ if (iiop_acceptor->hostname (this->orb_core_,
+ tmp_addr[index],
+ acceptor_interface) == -1)
+ continue;
+
+ // @@ This is very bad for performance, but it is a one time
+ // affair
+ if (ACE_OS::strcmp (local_interface,
+ acceptor_interface) == 0)
+ {
+ // We have the connection and the acceptor endpoint on the
+ // same interface
+ DIOP::ListenPoint point;
+ point.host = CORBA::string_dup (local_interface);
+ point.port = endpoint_addr[index].get_port_number ();
+
+ // Get the count of the number of elements
+ CORBA::ULong len = listen_point_list.length ();
+
+ // Increase the length by 1
+ listen_point_list.length (len + 1);
+
+ // Add the new length to the list
+ listen_point_list[len] = point;
+ }
+
+ // @@ This is bad....
+ CORBA::string_free (acceptor_interface);
+ }
+
+ CORBA::string_free (local_interface);
+ return 1;
+}
+*/
+
+void
+TAO_DIOP_Transport::transition_handler_state_i (void)
+{
+ this->connection_handler_ = 0;
+}
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
diff --git a/TAO/tao/Strategies/DIOP_Transport.h b/TAO/tao/Strategies/DIOP_Transport.h
new file mode 100644
index 00000000000..e8732f433cf
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Transport.h
@@ -0,0 +1,148 @@
+// This may look like C, but it's really -*- C++ -*-
+// -*- C++ -*-
+// ===================================================================
+/**
+ * @file DIOP_Transport.h
+ *
+ * $Id$
+ *
+ * @author Michael Kircher
+ */
+// ===================================================================
+
+#ifndef TAO_DIOP_TRANSPORT_H
+#define TAO_DIOP_TRANSPORT_H
+#include "ace/pre.h"
+
+#include "tao/corbafwd.h"
+
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+
+#include "tao/Transport.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/SOCK_Stream.h"
+#include "ace/Synch.h"
+#include "ace/Svc_Handler.h"
+#include "strategies_export.h"
+
+// Forward decls.
+class TAO_DIOP_Connection_Handler;
+class TAO_ORB_Core;
+class TAO_Operation_Details;
+class TAO_Pluggable_Messaging;
+class TAO_Acceptor;
+
+// Service Handler for this transport
+typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ TAO_DIOP_SVC_HANDLER;
+
+/**
+ * @class TAO_DIOP_Transport
+ *
+ * @brief Specialization of the base TAO_Transport class to handle the
+ * DIOP protocol.
+ *
+ *
+ *
+ */
+
+class TAO_Strategies_Export TAO_DIOP_Transport : public TAO_Transport
+{
+public:
+
+ /// Constructor.
+ TAO_DIOP_Transport (TAO_DIOP_Connection_Handler *handler,
+ TAO_ORB_Core *orb_core,
+ CORBA::Boolean flag);
+
+ /// Default destructor.
+ ~TAO_DIOP_Transport (void);
+
+protected:
+ /** @name Overridden Template Methods
+ *
+ * These are implementations of template methods declared by TAO_Transport.
+ */
+ //@{
+
+ virtual ACE_Event_Handler *event_handler_i (void);
+
+ virtual TAO_Pluggable_Messaging *messaging_object (void);
+
+ /// Write the complete Message_Block chain to the connection.
+ virtual ssize_t send_i (iovec *iov, int iovcnt,
+ size_t &bytes_transferred,
+ const ACE_Time_Value *max_wait_time);
+
+ /// Read len bytes from into buf.
+ virtual ssize_t recv_i (char *buf,
+ size_t len,
+ const ACE_Time_Value *s = 0);
+
+ /// Read and process the message from the connection. The processing
+ /// of the message is done by delegating the work to the underlying
+ /// messaging object
+ virtual int read_process_message (ACE_Time_Value *max_time_value = 0,
+ int block =0);
+
+ virtual int register_handler_i (void);
+
+ /// Method to do whatever it needs to do when the connection
+ /// handler is being closed and destroyed.
+ virtual void transition_handler_state_i (void);
+
+public:
+ /// @@TODO: These methods IMHO should have more meaningful
+ /// names. The names seem to indicate nothing.
+ 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 send_message (TAO_OutputCDR &stream,
+ TAO_Stub *stub = 0,
+ int twoway = 1,
+ ACE_Time_Value *max_time_wait = 0);
+
+ /// Initialising the messaging object
+ virtual int messaging_init (CORBA::Octet major,
+ CORBA::Octet minor);
+
+private:
+ /// Process the message that we have read
+ int process_message (void);
+
+ // @@ Frank : Not needed
+ /*
+ /// Set the Bidirectional context info in the service context list
+ void set_bidir_context_info (TAO_Operation_Details &opdetails);
+
+ /// Add the listen points in <acceptor> to the <listen_point_list>
+ /// if this connection is in the same interface as that of the
+ /// endpoints in the <acceptor>
+ int get_listen_point (DIOP::ListenPointList &listen_point_list,
+ TAO_Acceptor *acceptor);
+ */
+private:
+
+ /// The connection service handler used for accessing lower layer
+ /// communication protocols.
+ TAO_DIOP_Connection_Handler *connection_handler_;
+
+ /// Our messaging object.
+ TAO_Pluggable_Messaging *messaging_object_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "DIOP_Transport.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
+#include "ace/post.h"
+#endif /* TAO_DIOP_TRANSPORT_H */
diff --git a/TAO/tao/Strategies/DIOP_Transport.i b/TAO/tao/Strategies/DIOP_Transport.i
new file mode 100644
index 00000000000..81bf354f364
--- /dev/null
+++ b/TAO/tao/Strategies/DIOP_Transport.i
@@ -0,0 +1,2 @@
+// -*- C++ -*-
+//$Id$
diff --git a/TAO/tao/Strategies/Makefile b/TAO/tao/Strategies/Makefile
index 717381335ad..d88f0419edf 100644
--- a/TAO/tao/Strategies/Makefile
+++ b/TAO/tao/Strategies/Makefile
@@ -23,6 +23,13 @@ include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
include $(TAO_ROOT)/rules.tao.GNU
CPP_SRCS += \
+ DIOP_Factory \
+ DIOP_Profile \
+ DIOP_Transport \
+ DIOP_Connector \
+ DIOP_Acceptor \
+ DIOP_Connection_Handler \
+ DIOP_Endpoint \
UIOP_Factory \
UIOP_Lite_Factory \
UIOP_Profile \
diff --git a/TAO/tao/Strategies/Makefile.bor b/TAO/tao/Strategies/Makefile.bor
index ba548e586e8..f297b77b06f 100644
--- a/TAO/tao/Strategies/Makefile.bor
+++ b/TAO/tao/Strategies/Makefile.bor
@@ -22,6 +22,13 @@ OBJFILES = \
$(OBJDIR)\SHMIOP_Acceptor.obj \
$(OBJDIR)\SHMIOP_Connection_Handler.obj \
$(OBJDIR)\SHMIOP_Endpoint.obj \
+ $(OBJDIR)\DIOP_Factory.obj \
+ $(OBJDIR)\DIOP_Profile.obj \
+ $(OBJDIR)\DIOP_Transport.obj \
+ $(OBJDIR)\DIOP_Connector.obj \
+ $(OBJDIR)\DIOP_Acceptor.obj \
+ $(OBJDIR)\DIOP_Connection_Handler.obj \
+ $(OBJDIR)\DIOP_Endpoint.obj \
$(OBJDIR)\TAO_Strategies_Internal.obj \
$(OBJDIR)\uiop_endpoints.obj \
$(OBJDIR)\advanced_resource.obj \
diff --git a/TAO/tao/Strategies/TAO_Strategies_Internal.cpp b/TAO/tao/Strategies/TAO_Strategies_Internal.cpp
index f5fd25d8ad5..4aaea70973b 100644
--- a/TAO/tao/Strategies/TAO_Strategies_Internal.cpp
+++ b/TAO/tao/Strategies/TAO_Strategies_Internal.cpp
@@ -8,6 +8,7 @@
#include "advanced_resource.h"
#include "UIOP_Factory.h"
#include "SHMIOP_Factory.h"
+#include "DIOP_Factory.h"
#include "tao/Object_Loader.h"
@@ -59,7 +60,11 @@ TAO_Strategies_Internal::open_services (int &argc,
#if TAO_HAS_SHMIOP == 1
ACE_Service_Config::static_svcs ()->
insert (&ace_svc_desc_TAO_SHMIOP_Protocol_Factory);
-#endif /* TAO_HAS_UIOP == 1 */
+#endif /* TAO_HAS_SHMIOP == 1 */
+#if TAO_HAS_DIOP == 1
+ ACE_Service_Config::static_svcs ()->
+ insert (&ace_svc_desc_TAO_DIOP_Protocol_Factory);
+#endif /* TAO_HAS_DIOP == 1 */
int result = 0;
if (skip_service_config_open == 0)
diff --git a/TAO/tao/Strategies/advanced_resource.cpp b/TAO/tao/Strategies/advanced_resource.cpp
index c590e862fec..029c6c1932b 100644
--- a/TAO/tao/Strategies/advanced_resource.cpp
+++ b/TAO/tao/Strategies/advanced_resource.cpp
@@ -8,6 +8,7 @@
#include "UIOP_Factory.h"
#include "SHMIOP_Factory.h"
+#include "DIOP_Factory.h"
#include "Reactor_Per_Priority.h"
#include "LFU_Connection_Purging_Strategy.h"
@@ -43,7 +44,13 @@ TAO_Resource_Factory_Changer::TAO_Resource_Factory_Changer (void)
#if TAO_HAS_SHMIOP == 1
ACE_Service_Config::static_svcs ()->
insert (&ace_svc_desc_TAO_SHMIOP_Protocol_Factory);
-#endif /* TAO_HAS_UIOP == 1 */
+#endif /* TAO_HAS_SHMIOP == 1 */
+
+#if TAO_HAS_DIOP == 1
+ ACE_Service_Config::static_svcs ()->
+ insert (&ace_svc_desc_TAO_DIOP_Protocol_Factory);
+#endif /* TAO_HAS_DIOP == 1 */
+
}
TAO_Advanced_Resource_Factory::TAO_Advanced_Resource_Factory (void)
@@ -368,6 +375,69 @@ TAO_Advanced_Resource_Factory::init_protocol_factories (void)
}
#endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */
+#if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
+ protocol_factory =
+ ACE_Dynamic_Service<TAO_Protocol_Factory>::instance ("DIOP_Factory");
+
+ if (protocol_factory == 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_WARNING,
+ "(%P|%t) WARNING - No %s found in Service Repository."
+ " Using default instance.\n",
+ "DIOP Protocol Factory"));
+
+ ACE_NEW_RETURN (protocol_factory,
+ TAO_DIOP_Protocol_Factory,
+ -1);
+
+ ACE_AUTO_PTR_RESET (safe_protocol_factory,
+ protocol_factory,
+ TAO_Protocol_Factory);
+
+ transfer_ownership = 1;
+ }
+ else
+ {
+ transfer_ownership = 0;
+ }
+
+ ACE_NEW_RETURN (item, TAO_Protocol_Item ("DIOP_Factory"), -1);
+ // If the TAO_Protocol_Item retains ownership of the
+ // TAO_Protocol_Factory then we used an auto_ptr<> above, so
+ // release the TAO_Protocol_Factory from it. Otherwise, we
+ // obtained the TAO_Protocol_Factory from the Service
+ // Configurator so an auto_ptr<> wasn't used since the Service
+ // Configurator retains ownership, hence there was no need to
+ // use an auto_ptr<> in this method.
+ item->factory ((transfer_ownership ?
+ safe_protocol_factory.release () :
+ protocol_factory),
+ transfer_ownership);
+
+ if (this->protocol_factories_.insert (item) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) Unable to add ")
+ ACE_TEXT ("<%s> to protocol factory set.\n"),
+ item->protocol_name ().c_str ()));
+
+ delete item;
+
+ if (transfer_ownership == 0)
+ delete protocol_factory;
+
+ return -1;
+ }
+
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) Loaded default ")
+ ACE_TEXT ("protocol <DIOP_Factory>\n")));
+ }
+#endif /* TAO_HAS_DIOP && TAO_HAS_DIOP != 0 */
+
return 0;
}