diff options
Diffstat (limited to 'trunk/TAO/tao/Acceptor_Registry.cpp')
-rw-r--r-- | trunk/TAO/tao/Acceptor_Registry.cpp | 899 |
1 files changed, 899 insertions, 0 deletions
diff --git a/trunk/TAO/tao/Acceptor_Registry.cpp b/trunk/TAO/tao/Acceptor_Registry.cpp new file mode 100644 index 00000000000..ca0662470c6 --- /dev/null +++ b/trunk/TAO/tao/Acceptor_Registry.cpp @@ -0,0 +1,899 @@ +// $Id$ + +#include "tao/Acceptor_Registry.h" +#include "tao/Profile.h" +#include "tao/Transport_Acceptor.h" +#include "tao/Protocol_Factory.h" +#include "tao/Environment.h" +#include "tao/ORB_Core.h" +#include "tao/params.h" +#include "tao/MProfile.h" +#include "tao/debug.h" +#include "tao/Acceptor_Filter.h" +#include "tao/Endpoint.h" +#include "tao/ORB_Constants.h" +#include "tao/SystemException.h" +#if defined (ACE_WIN32) && defined (ACE_HAS_IPV6) +# include "tao/IIOP_Acceptor.h" +#endif /* ACE_WIN32 && ACE_HAS_IPV6 */ + +#include "ace/Auto_Ptr.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/os_ctype.h" + +#if !defined(__ACE_INLINE__) +#include "tao/Acceptor_Registry.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID (tao, + Acceptor_Registry, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_Acceptor_Registry::TAO_Acceptor_Registry (void) + : acceptors_ (0), + size_ (0) +{ +} + +TAO_Acceptor_Registry::~TAO_Acceptor_Registry (void) +{ + this->close_all (); + + delete [] this->acceptors_; +} + +size_t +TAO_Acceptor_Registry::endpoint_count (void) +{ + int count = 0; + const TAO_AcceptorSetIterator end = this->end (); + + for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i) + { + count += (*i)->endpoint_count (); + } + + return count; +} + +int +TAO_Acceptor_Registry::is_collocated (const TAO_MProfile &mprofile) +{ + const TAO_AcceptorSetIterator end = this->end (); + + const CORBA::ULong count = mprofile.profile_count (); + + // If at least one endpoint in one of the profiles matches one of + // the acceptors, we are collocated. + for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i) + { + for (TAO_PHandle j = 0; j != count; ++j) + { + const TAO_Profile *profile = mprofile.get_profile (j); + + // @@ We need to invoke a nonconst <endpoint> method on + // <profile>. The content of profile/endpoint will not + // be modified. + TAO_Profile *pf = const_cast<TAO_Profile *> (profile); + + // Check all endpoints for address equality. + if ((*i)->tag () == pf->tag ()) + { + // @note This can be a potentially expensive (O(n^2)) + // operation if the below is_collocated() call + // also executes a loop. + for (TAO_Endpoint *endp = pf->endpoint (); + endp != 0; + endp = endp->next ()) + { + if ((*i)->is_collocated (endp)) + { + return 1; + } + } + } + } + } + + return 0; +} + +TAO_Acceptor* +TAO_Acceptor_Registry::get_acceptor (CORBA::ULong tag) +{ + TAO_AcceptorSetIterator end = this->end (); + TAO_AcceptorSetIterator acceptor = this->begin (); + + for (; acceptor != end; ++acceptor) + { + if ((*acceptor)->tag () == tag) + { + return *acceptor; + } + } + + return 0; +} + +int +TAO_Acceptor_Registry::open (TAO_ORB_Core *orb_core, + ACE_Reactor *reactor, + const TAO_EndpointSet &endpoint_set, + bool ignore_address + ACE_ENV_ARG_DECL) +{ + if (endpoint_set.is_empty () + // No endpoints were specified, we let each protocol pick its + // own default. + + // All TAO pluggable protocols are expected to have the ability + // to create a default endpoint. + && this->open_default (orb_core, reactor, 0) == -1) + { + ACE_THROW_RETURN (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + 0), + CORBA::COMPLETED_NO), + -1); + } + + // Count the maximum number of endpoints in the set. This will be + // the maximum number of acceptors that need to be created. + size_t acceptor_count = 0; + TAO_EndpointSetIterator endpts (endpoint_set); + + for (ACE_CString *ep = 0; + endpts.next (ep) != 0; + endpts.advance ()) + { + const ACE_CString &iop = (*ep); + + // IOP://address1,address2 + // ^ slot + ACE_CString::size_type const slot = iop.find ("://", 0); + + if (slot == iop.npos) + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Invalid endpoint ") + ACE_TEXT ("specification: <%s>.\n"), + ACE_TEXT_CHAR_TO_TCHAR (iop.c_str ()))); + } + + ACE_THROW_RETURN (CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + EINVAL), + CORBA::COMPLETED_NO), + -1); + } + + ++acceptor_count; // We've got at least one acceptor so far. +#if defined (ACE_WIN32) && defined (ACE_HAS_IPV6) + // Since Win32 has single-stack IPv4/IPv6 we need an additional + // acceptor if an iiop protocol without endpoints is specified + // to open explicitly on IPv6 ANY *and* IPv4 ANY. + + // Now get the list of available protocol factories. + const TAO_ProtocolFactorySetItor end = + orb_core->protocol_factories ()->end (); + + // extract the protocol prefix + const ACE_CString prefix (iop.substring (0, slot)); + + for (TAO_ProtocolFactorySetItor factory = + orb_core->protocol_factories ()->begin (); + factory != end; + ++factory) + { + if ((*factory)->factory ()->match_prefix (prefix)) + { + if ((*factory)->factory ()->tag () == IOP::TAG_INTERNET_IOP) + { + // just add additional space to cover for possibility + ++acceptor_count; + } + break; // we found the protocol, no need to go on + } + } +#endif /* ACE_WIN32 && ACE_HAS_IPV6 */ + + // Now count the number of commas. That number will be the + // remaining number of endpoints in the current endpoint + // specification. + const char *ep_end = + ep->c_str () + ACE_OS::strlen (ep->c_str ()); + + for (const char *e = ACE_OS::strchr (ep->c_str (), ','); + e != 0 && e != ep_end; + e = ACE_OS::strchr (e, ',')) + { + ++acceptor_count; + ++e; + } + } + + // The array containing the TAO_Acceptors will never contain more + // than the number of endpoints stored in TAO_ORB_Parameters. + if (this->acceptors_ == 0) + { + ACE_NEW_THROW_EX (this->acceptors_, + TAO_Acceptor *[acceptor_count], + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (-1); + } + + TAO_EndpointSetIterator endpoints (endpoint_set); + + for (ACE_CString *endpoint = 0; + endpoints.next (endpoint) != 0; + endpoints.advance ()) + { + const ACE_CString &iop = (*endpoint); + + // IOP://address1,address2 + // ^ slot + ACE_CString::size_type const slot = iop.find ("://", 0); + + if (slot == iop.npos) + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Invalid endpoint ") + ACE_TEXT ("specification: <%s>.\n"), + ACE_TEXT_CHAR_TO_TCHAR (iop.c_str ()))); + } + + ACE_THROW_RETURN (CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + EINVAL), + CORBA::COMPLETED_NO), + -1); + } + + const ACE_CString prefix (iop.substring (0, slot)); + + // @@ We could move the protocol factory loop to the outermost + // level but for now we leave it inside the endpoint loop + // under the assumption that there will be more endpoints + // than protocols. + + // Now get the list of available protocol factories. + const TAO_ProtocolFactorySetItor end = + orb_core->protocol_factories ()->end (); + + bool found = false; + // If usable protocol (factory) is found then this will be + // set equal to true. + + for (TAO_ProtocolFactorySetItor factory = + orb_core->protocol_factories ()->begin (); + factory != end; + ++factory) + { + if ((*factory)->factory ()->match_prefix (prefix)) + { + // increment slot past the "://" (i.e. add 3) + ACE_CString addrs = iop.substring (slot + 3); + + const int result = this->open_i (orb_core, + reactor, + addrs, + factory, + ignore_address + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (result != 0) + { + return -1; + } + + found = true; // A usable protocol was found. + } + else + { + continue; + } + } + + if (found == false) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) ") + ACE_TEXT ("no usable transport protocol ") + ACE_TEXT ("was found.\n"))); + + ACE_THROW_RETURN (CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + EINVAL), + CORBA::COMPLETED_NO), + -1); + } + } + + return 0; +} + +// Iterate through the loaded transport protocols and create a default +// server for each protocol. +int TAO_Acceptor_Registry::open_default (TAO_ORB_Core *orb_core, + ACE_Reactor *reactor, + const char *options) +{ + // Flag that indicates at least one endpoint was opened. If one + // wasn't opened then there is a problem. + bool opened_endpoint = false; + +#if defined (ACE_WIN32) && defined (ACE_HAS_IPV6) + if (!orb_core->orb_params ()->connect_ipv6_only () && this->acceptors_ == 0) + { + // Since Win32 has single-stack IPv4/IPv6 we need an additional + // acceptor to open explicitly on IPv6 ANY *and* IPv4 ANY. + // This code takes care of that. + + TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories (); + + // Number of acceptors to set up + size_t acceptor_count = 0; + + const TAO_ProtocolFactorySetItor end = pfs->end (); + + // Loop through all the loaded protocols... + for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i) + { + if (!(*i)->factory ()->requires_explicit_endpoint ()) + { + if ((*i)->factory ()->tag () == IOP::TAG_INTERNET_IOP) + acceptor_count += 2; // IPv4 AND IPv6 endpoints + else + acceptor_count += 1; + } + } + + // Allocate TAO_Acceptor array + ACE_NEW_RETURN (this->acceptors_, + TAO_Acceptor *[acceptor_count], + -1); + + // Loop through all the loaded protocols... + for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i) + { + // If the protocol requires an explicit -ORBEndpoint option then + // don't use it, otherwise open a default endpoint for that + // protocol, this solves the problem with persistent endpoints + // (such as UNIX domain rendesvouz points) that are not cleaned + // up if the server crashes. + if (!(*i)->factory ()->requires_explicit_endpoint ()) + { + // Make an acceptor + TAO_Acceptor *acceptor = + (*i)->factory ()->make_acceptor (); + + if (acceptor == 0) + { + if (TAO_debug_level > 0) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to create ") + ACE_TEXT ("an acceptor for <%s>\n"), + ACE_TEXT_CHAR_TO_TCHAR ((*i)->protocol_name ().c_str ()) + )); + } + + return -1; + } + + if ((*i)->factory ()->tag () == IOP::TAG_INTERNET_IOP) + { + // Open first acceptor on IPv4 ANY + ACE_INET_Addr addr(static_cast<unsigned short> (0)); // IPv4 ANY + + TAO_IIOP_Acceptor* iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor); + iiop_acceptor->set_default_address (addr); + + if (this->open_default_i (orb_core, + reactor, + TAO_DEF_GIOP_MAJOR, // default major + TAO_DEF_GIOP_MINOR, // default minor + i, + acceptor, + options) != 0) + { + return -1; + } + + // record the port chosen for the IPv4 acceptor + u_short port = iiop_acceptor->default_address ().get_port_number (); + + // Create second acceptor for IPV6 traffic + acceptor = + (*i)->factory ()->make_acceptor (); + + if (acceptor == 0) + { + if (TAO_debug_level > 0) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to create ") + ACE_TEXT ("an acceptor for <%s>\n"), + ACE_TEXT_CHAR_TO_TCHAR ((*i)->protocol_name ().c_str ()) + )); + } + + return -1; + } + + addr.set (port, ACE_IPV6_ANY, AF_INET6); // IPv6 ANY on specified port + + iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor); + iiop_acceptor->set_default_address (addr); + + if (this->open_default_i (orb_core, + reactor, + TAO_DEF_GIOP_MAJOR, // default major + TAO_DEF_GIOP_MINOR, // default minor + i, + acceptor, + options) != 0) + { + return -1; + } + } + else + { + if (this->open_default_i (orb_core, + reactor, + TAO_DEF_GIOP_MAJOR, // default major + TAO_DEF_GIOP_MINOR, // default minor + i, + acceptor, + options) != 0) + { + return -1; + } + } + + opened_endpoint = true; + } + } + } + else + { +#endif /* ACE_WIN32 && ACE_HAS_IPV6 */ + TAO_ProtocolFactorySet *pfs = orb_core->protocol_factories (); + + // If the TAO_Acceptor array is zero by the time we get here then no + // endpoints were specified by the user, meaning that the number of + // acceptors will never be more than the number of loaded protocols + // in the ORB core. + if (this->acceptors_ == 0) + { + ACE_NEW_RETURN (this->acceptors_, + TAO_Acceptor *[pfs->size ()], + -1); + } + + const TAO_ProtocolFactorySetItor end = pfs->end (); + + // Loop through all the loaded protocols... + for (TAO_ProtocolFactorySetItor i = pfs->begin (); i != end; ++i) + { + // If the protocol requires an explicit -ORBEndpoint option then + // don't use it, otherwise open a default endpoint for that + // protocol, this solves the problem with persistent endpoints + // (such as UNIX domain rendesvouz points) that are not cleaned + // up if the server crashes. + if (!(*i)->factory ()->requires_explicit_endpoint ()) + { + if (this->open_default (orb_core, + reactor, + TAO_DEF_GIOP_MAJOR, // default major + TAO_DEF_GIOP_MINOR, // default minor + i, + options) != 0) + { + return -1; + } + + opened_endpoint = true; + } + } +#if defined (ACE_WIN32) && defined (ACE_HAS_IPV6) + } +#endif /* ACE_WIN32) && ACE_HAS_IPV6 */ + + if (!opened_endpoint) + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) No default endpoints ") + ACE_TEXT ("opened.\n") + ACE_TEXT ("Please specify one or more using ") + ACE_TEXT ("the \"-ORBListenEndpoints\" ") + ACE_TEXT ("option.\n"))); + } + + return -1; + } + + return 0; +} + +// Used when no endpoints were specified. Open a default server for +// the indicated protocol. +int +TAO_Acceptor_Registry::open_default (TAO_ORB_Core *orb_core, + ACE_Reactor *reactor, + int major, + int minor, + TAO_ProtocolFactorySetItor &factory, + const char *options) +{ + // No endpoints were specified, we let each protocol pick its own + // default endpoint. + + // Make an acceptor + TAO_Acceptor *acceptor = + (*factory)->factory ()->make_acceptor (); + + if (acceptor == 0) + { + if (TAO_debug_level > 0) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to create ") + ACE_TEXT ("an acceptor for <%s>\n"), + ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ()) + )); + } + + return -1; + } + + return this->open_default_i (orb_core, + reactor, + major, + minor, + factory, + acceptor, + options); +} + +// Open a default server. +int +TAO_Acceptor_Registry::open_default_i (TAO_ORB_Core *orb_core, + ACE_Reactor *reactor, + int major, + int minor, + TAO_ProtocolFactorySetItor &factory, + TAO_Acceptor* acceptor, + const char *options) +{ + // Initialize the acceptor to listen on a default endpoint. + if (acceptor->open_default (orb_core, + reactor, + major, + minor, + options) == -1) + { + delete acceptor; + + if (TAO_debug_level > 0) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to open ") + ACE_TEXT ("default acceptor for <%s>%p\n"), + ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ()), + ACE_TEXT ("") + )); + } + + return -1; + } + + this->acceptors_[this->size_++] = acceptor; + + return 0; +} + +int +TAO_Acceptor_Registry::close_all (void) +{ + const TAO_AcceptorSetIterator end = this->end (); + + for (TAO_AcceptorSetIterator i = this->begin (); i != end; ++i) + { + if (*i == 0) + { + continue; + } + + (*i)->close (); + + delete *i; + } + + this->size_ = 0; + return 0; +} + +void +TAO_Acceptor_Registry::extract_endpoint_options (ACE_CString &addrs, + ACE_CString &options, + TAO_Protocol_Factory *factory) +{ + ACE_CString::size_type const options_index = + addrs.find (factory->options_delimiter ()); + + if (options_index == addrs.length () - 1) + { + // Get rid of trailing option delimiter. + addrs = addrs.substring (0, addrs.length () - 1); + } + else if (options_index != ACE_CString::npos) + { + options = addrs.substring (options_index + 1); + addrs = addrs.substring (0, options_index); + } +} + +void +TAO_Acceptor_Registry::extract_endpoint_version (ACE_CString &address, + int &major, + int &minor) +{ + // Check if an "N.n@" version prefix was + // specified. + major = TAO_DEF_GIOP_MAJOR; + minor = TAO_DEF_GIOP_MINOR; + + if (isdigit (address[0]) + && address[1] == '.' + && isdigit (address[2]) + && address[3] == '@') + { + major = address[0] - '0'; + minor = address[2] - '0'; + address = address.substring (4); + } +} + +int +TAO_Acceptor_Registry::open_i (TAO_ORB_Core *orb_core, + ACE_Reactor *reactor, + ACE_CString &addrs, + TAO_ProtocolFactorySetItor &factory, + bool ignore_address + ACE_ENV_ARG_DECL) +{ + ACE_CString options_tmp; + this->extract_endpoint_options (addrs, + options_tmp, + (*factory)->factory ()); + + const char *options = 0; + + if (options_tmp.length () > 0) + options = options_tmp.c_str (); + + char *last_addr = 0; + ACE_Auto_Basic_Array_Ptr<char> addr_str (addrs.rep ()); + + const char *astr = ACE_OS::strtok_r (addr_str.get (), + ",", + &last_addr); + + // Iterate over the addrs specified in the endpoint. + + do + { + // For the first time only through the loop, it is + // possible for astr to be 0. This indicates that + // the user is requesting the default endpoint for + // the specified protocol. + ACE_CString address (astr == 0 ? "" : astr); + + TAO_Acceptor *acceptor = + (*factory)->factory ()->make_acceptor (); + + if (acceptor != 0) + { + // Extract the desired endpoint/protocol version if one + // exists. + int major = TAO_DEF_GIOP_MAJOR; + int minor = TAO_DEF_GIOP_MINOR; + this->extract_endpoint_version (address, + major, + minor); + + // Check for existence of endpoint. + if (ignore_address || address.length () == 0) + { + // Protocol prefix was specified without any endpoints. + // All TAO pluggable protocols are expected to have the + // ability to create a default endpoint. +#if defined (ACE_WIN32) && defined (ACE_HAS_IPV6) + if ((*factory)->factory ()->tag () == IOP::TAG_INTERNET_IOP) + { + // Open first acceptor on IPv4 ANY + ACE_INET_Addr addr(static_cast<unsigned short> (0)); // IPv4 ANY + + TAO_IIOP_Acceptor* iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor); + iiop_acceptor->set_default_address (addr); + + if (this->open_default_i (orb_core, + reactor, + major, + minor, + factory, + acceptor, + options) == 0) + { + // record the port chosen for the IPv4 acceptor + u_short port = iiop_acceptor->default_address ().get_port_number (); + + // Create second acceptor for IPV6 traffic + acceptor = + (*factory)->factory ()->make_acceptor (); + + if (acceptor == 0) + { + if (TAO_debug_level > 0) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to create ") + ACE_TEXT ("an acceptor for <%s>\n"), + ACE_TEXT_CHAR_TO_TCHAR ((*factory)->protocol_name ().c_str ()) + )); + } + + ACE_THROW_RETURN (CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + ENOMEM), + CORBA::COMPLETED_NO), + -1); + } + + addr.set (port, ACE_IPV6_ANY, AF_INET6); // IPv6 ANY on specified port + + iiop_acceptor = dynamic_cast<TAO_IIOP_Acceptor*> (acceptor); + iiop_acceptor->set_default_address (addr); + + if (this->open_default_i (orb_core, + reactor, + major, + minor, + factory, + acceptor, + options) == 0) + { + continue; + } + } + + } + else + { + if (this->open_default_i (orb_core, + reactor, + major, + minor, + factory, + acceptor, + options) == 0) + { + continue; + } + } + + // Could not open a default endpoint, nor an explicit + // one. + ACE_THROW_RETURN (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + 0), + CORBA::COMPLETED_NO), + -1); +#else /* ACE_WIN32 && ACE_HAS_IPV6 */ + if (this->open_default_i (orb_core, + reactor, + major, + minor, + factory, + acceptor, + options) == 0) + continue; + + // Could not open a default endpoint, nor an explicit + // one. + else + { + ACE_THROW_RETURN (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + 0), + CORBA::COMPLETED_NO), + -1); + } +#endif /* !ACE_WIN32 || !ACE_HAS_IPV6 */ + } + // An explicit endpoint was provided. + else if (acceptor->open (orb_core, + reactor, + major, + minor, + address.c_str (), + options) == -1) + { + /* Need to save the errno value from the acceptor->open(), + * because errno will get reset when we delete acceptor */ + const int errno_value = errno; + delete acceptor; + + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) ") + ACE_TEXT ("unable to open acceptor ") + ACE_TEXT ("for <%s>%p\n"), + ACE_TEXT_CHAR_TO_TCHAR (address.c_str ()), + ACE_TEXT (""))); + } + + ACE_THROW_RETURN (CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + errno_value), + CORBA::COMPLETED_NO), + -1); + } + + // add acceptor to list + this->acceptors_[this->size_++] = acceptor; + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) unable to create ") + ACE_TEXT ("an acceptor for <%s>.\n"), + ACE_TEXT_CHAR_TO_TCHAR (address.c_str ()))); + } + + ACE_THROW_RETURN (CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, + ENOMEM), + CORBA::COMPLETED_NO), + -1); + } + } + while (astr != 0 && (astr = ACE_OS::strtok_r (0, ",", &last_addr)) != 0); + + return 0; +} + +TAO_END_VERSIONED_NAMESPACE_DECL |