diff options
Diffstat (limited to 'TAO/tao/Pluggable.cpp')
-rw-r--r-- | TAO/tao/Pluggable.cpp | 446 |
1 files changed, 358 insertions, 88 deletions
diff --git a/TAO/tao/Pluggable.cpp b/TAO/tao/Pluggable.cpp index 051c17f07f4..5be3407dfc2 100644 --- a/TAO/tao/Pluggable.cpp +++ b/TAO/tao/Pluggable.cpp @@ -5,6 +5,11 @@ #include "tao/Stub.h" #include "tao/Environment.h" #include "tao/GIOP.h" +#include "tao/CDR.h" +#include "tao/Object_KeyC.h" +#include "tao/debug.h" + +#include "ace/ACE.h" #if !defined (__ACE_INLINE__) # include "tao/Pluggable.i" @@ -12,162 +17,427 @@ ACE_RCSID(tao, Pluggable, "$Id$") -TAO_Connector_Registry::TAO_Connector_Registry (void) - : iiop_connector_ (0) +TAO_IOP_Version::~TAO_IOP_Version (void) { } -TAO_Connector_Registry::~TAO_Connector_Registry (void) +TAO_IOP_Version::TAO_IOP_Version (const TAO_IOP_Version &src) + : major (src.major), + minor (src.minor) { } -TAO_Connector * -TAO_Connector_Registry::get_connector (CORBA::ULong tag) +TAO_IOP_Version::TAO_IOP_Version (CORBA::Octet maj, CORBA::Octet min) + : major (maj), + minor (min) { - // For now, only IIOP connectors. - if (tag != TAO_IOP_TAG_INTERNET_IOP) - ACE_ERROR_RETURN ((LM_ERROR, - "Invalid connector tag %d\n", - tag), - 0); - else - return iiop_connector_; } -CORBA::Boolean -TAO_Connector_Registry::add_connector (TAO_Connector *connector) +void +TAO_IOP_Version::set_version (CORBA::Octet maj, CORBA::Octet min) { - if (connector->tag() == TAO_IOP_TAG_INTERNET_IOP) - { - // do not copy, but save the reference (i.e. pointer) - this->iiop_connector_ = connector; - return 1; - } - else - ACE_ERROR_RETURN ((LM_ERROR, - "Invalid connector tag %d\n", - connector->tag ()), - 0); + this->major = maj; + this->minor = min; } int -TAO_Connector_Registry::open(TAO_Resource_Factory *trf, ACE_Reactor *reactor) +TAO_IOP_Version::operator== (const TAO_IOP_Version *&src) { - // @@ Once again since we only accept 1 iiop connector, this is easy - if (iiop_connector_) - return this->iiop_connector_->open (trf, reactor); - else - return 0; + return this->major == src->major && this->minor == src->minor; } int -TAO_Connector_Registry::close_all() +TAO_IOP_Version::operator== (const TAO_IOP_Version &src) { - // @@ Loop through all registered connectors ... not too hard - // since there is only one! - if (iiop_connector_) - return this->iiop_connector_->close (); - else - return 0; + return this->major == src.major && this->minor == src.minor; } -int -TAO_Connector_Registry::preconnect (const char *the_preconnections) +TAO_IOP_Version & +TAO_IOP_Version::operator= (const TAO_IOP_Version &src) { - // It would be good to use auto_ptr<> to guard against premature - // termination and, thus, leaks. - int result=0; - char *preconnections = ACE_OS::strdup (the_preconnections); + this->major = src.major; + this->minor = src.minor; + return *this; +} + +// **************************************************************** - // @@ OK, what we should do is parse the string so that we can - // gather @@ together addresses of the same protocol together and - // pass to the @@ appropriate connector. But, for now we ASSUME - // they are all @@ INET IP:Port!! HACK. fredk +TAO_Profile::~TAO_Profile (void) +{ +} - if (this->iiop_connector_) - result = this->iiop_connector_->preconnect (preconnections); +// Generic Profile +CORBA::ULong +TAO_Profile::tag (void) const +{ + return this->tag_; +} - ACE_OS::free (preconnections); +CORBA::ULong +TAO_Profile::_incr_refcnt (void) +{ + // OK, think I got it. When this object is created (guard) the + // lock is automatically acquired (refcount_lock_). Then when + // we leave this method the destructir for guard is called which + // releases the lock! + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->refcount_lock_, 0); - return result; + return this->refcount_++; +} + +CORBA::ULong +TAO_Profile::_decr_refcnt (void) +{ + { + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->refcount_lock_, 0); + this->refcount_--; + if (this->refcount_ != 0) + return this->refcount_; + } + + // refcount is 0, so delete us! + // delete will call our ~ destructor which in turn deletes stuff. + delete this; + return 0; +} + +// **************************************************************** + +TAO_Unknown_Profile::TAO_Unknown_Profile (CORBA::ULong tag) + : TAO_Profile (tag) +{ } int -TAO_Connector_Registry::connect (TAO_Stub *&obj, - TAO_Transport *&transport) +TAO_Unknown_Profile::parse_string (const char *, + CORBA::Environment &) +{ + // @@ THROW something???? + return -1; +} + +CORBA::String +TAO_Unknown_Profile::to_string (CORBA::Environment &) { - CORBA::ULong req_tag = TAO_IOP_TAG_INTERNET_IOP; - TAO_Profile *profile = obj->profile_in_use (); + // @@ THROW something? + return 0; +} - // @@ And the profile selection policy is .... ONLY IIOP, and the - // @@ first one found! - if (profile->tag () != req_tag) +const TAO_opaque& +TAO_Unknown_Profile::body (void) const +{ + return this->body_; +} + +int +TAO_Unknown_Profile::decode (TAO_InputCDR& cdr) +{ + if ((cdr >> this->body_) == 0) return -1; + return 0; +} - // here is where we get the appropriate connector object but we are - // the Connector Registry so call get_connector(tag) +int +TAO_Unknown_Profile::encode (TAO_OutputCDR &stream) const +{ + stream.write_ulong (this->tag ()); + return (stream << this->body_); +} - TAO_Connector *connector = - this->get_connector (req_tag); +const TAO_ObjectKey & +TAO_Unknown_Profile::object_key (void) const +{ + // @@ TODO this is wrong, but the function is deprecated anyway.... + static TAO_ObjectKey empty_key; + return empty_key; +} - return connector->connect (profile, transport); +TAO_ObjectKey * +TAO_Unknown_Profile::_key (CORBA::Environment &) const +{ + // @@ THROW something??? + return 0; } -TAO_IOP_Version::~TAO_IOP_Version (void) +CORBA::Boolean +TAO_Unknown_Profile::is_equivalent (TAO_Profile* other_profile, + CORBA::Environment &) { + if (other_profile->tag () != this->tag ()) + return 0; + + TAO_Unknown_Profile *op = + ACE_dynamic_cast (TAO_Unknown_Profile*, other_profile); + + return (this->body_ == op->body_); } -TAO_IOP_Version::TAO_IOP_Version (const TAO_IOP_Version &src) - : major (src.major), - minor (src.minor) +CORBA::ULong +TAO_Unknown_Profile::hash (CORBA::ULong max, + CORBA::Environment &) { + return (ACE::hash_pjw (ACE_reinterpret_cast (const char*, + this->body_.get_buffer ()), + this->body_.length ()) % max); } -TAO_IOP_Version::TAO_IOP_Version (CORBA::Octet maj, CORBA::Octet min) - : major (maj), - minor (min) +ASYS_TCHAR * +TAO_Unknown_Profile::addr_to_string(void) { + return 0; } void -TAO_IOP_Version::set_version (CORBA::Octet maj, CORBA::Octet min) +TAO_Unknown_Profile::reset_hint (void) { - this->major = maj; - this->minor = min; + // do nothing } -int -TAO_IOP_Version::operator== (const TAO_IOP_Version *&src) +// **************************************************************** + +// Transport ... +TAO_Transport::TAO_Transport (CORBA::ULong tag) + : tag_ (tag) { - return this->major == src->major && this->minor == src->minor; } -int -TAO_IOP_Version::operator== (const TAO_IOP_Version &src) +TAO_Transport::~TAO_Transport (void) { - return this->major == src.major && this->minor == src.minor; } -TAO_IOP_Version & -TAO_IOP_Version::operator= (const TAO_IOP_Version &src) +CORBA::ULong +TAO_Transport::tag (void) const { - this->major = src.major; - this->minor = src.minor; - return *this; + return this->tag_; } -TAO_Profile::~TAO_Profile (void) +// Connector +TAO_Connector::TAO_Connector (CORBA::ULong tag) + : tag_(tag) { } -TAO_Transport::~TAO_Transport (void) +CORBA::ULong +TAO_Connector::tag (void) const { + return this->tag_; +} + + + +int +TAO_Connector::make_mprofile (const char *string, + TAO_MProfile &mprofile, + CORBA::Environment &ACE_TRY_ENV) +{ + // This method utilizes the "Template Method" design pattern to + // parse the given URL style IOR for the protocol being used + // and create an mprofile from it. + // + // The methods that must be defined by all Connector sub-classes are: + // make_profile + // check_prefix + + // Check for a valid string + if (!string || !*string) + return 1; // Failure + + // 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 (this->check_prefix (string) != 0) + { + return 1; + // Failure: not the correct IOR for this protocol. + // DO NOT throw an exception here since the Connector_Registry + // should be allowed the opportunity to continue looking for + // an appropriate connector. + } + + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - TAO_Connector::make_mprofile <%s>\n", + string)); + } + + ACE_CString ior; + + ior.set (string, ACE_OS::strlen (string), 1); + + // Find out where the protocol name ends + int ior_index = ior.find (':'); + + if (ior_index == ACE_CString::npos) + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // No colon ':' in the IOR! + } + else + { + ior_index++; + // Add the length of the colon to the IOR index (i.e. 1) + } + + + const char endpoint_delimiter = ','; + // The delimiter used to seperate inidividual addresses. + + // Count the number of endpoints in the IOR. This will be the number + // of entries in the Mprofile. + + CORBA::ULong profile_count = 1; + // Number of endpoints in the IOR (initialized to 1) + + for (size_t j = 0; j < ior.length (); ++j) + { + if (ior[j] == endpoint_delimiter) + profile_count++; + } + + // Tell the MProfile object how many Profiles it should hold. + // Mprofile::set(size) returns the number profiles it can hold. + if (mprofile.set (profile_count) != ACE_static_cast (int, profile_count)) + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Error while setting the MProfile size! + } + + // Find the version, if it exists, and keep track of it so that it + // may be passed to each Profile. + + int version_index; + // Index denoting where version is located in the IOR + + if (ior.find ("//") == ior_index) + { + version_index = 0; + // No version provided + // `protocol://' + } + else if (ior.find ("//") == ior_index + 3) + { + version_index = ior_index; + // Version provided + // `protocol:N.n//' + + ior_index += 5; + // Skip over the `N.n//' + } + else + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Problem in IOR between protocol prefix and double slash "//" + } + + // The idea behind the following loop is to split the IOR into several + // strings that can be parsed by each profile. + // For example, + // `1.3//moo,shu,chicken/arf' + // will be parsed into: + // `1.3//moo/arf' + // `1.3//shu/arf' + // `1.3//chicken/arf' + // + // If no version is provided then the string will be of the form: + // `//moo/arf' + + int objkey_index = ior.find (this->object_key_delimiter (), ior_index); + // Find the object key + // + // Typically, a forward slash '/' is used to delimit endpoints from the + // object key. However, some protocols may use forward slashes in + // the endpoints themselves. To prevent ambiguities from arising, a + // protocol specific object key delimiter can be used. + + if (objkey_index == 0 || objkey_index == ACE_CString::npos) + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Failure: No endpoints specified or no object key specified. + } + + int begin = 0; + int end = ior_index - 1; + // Initialize the end of the endpoint index + + for (CORBA::ULong j = 0; j < profile_count; ++j) + { + begin += end + 1; + + if (j < profile_count - 1) + end = ior.find (endpoint_delimiter, begin); + else + end = objkey_index - begin; // Handle last endpoint differently + + if (end < ACE_static_cast (int, ior.length ()) && end != ior.npos) + { + ACE_CString endpoint = ior.substring (begin, end); + + if (version_index > 0) + { + endpoint = ior.substring (version_index, 5) + endpoint; + // Concatenate version string and endpoint + } + else + { + endpoint = ior.substring (ior_index - 2, 2) + endpoint; + // No version provided + } + + endpoint += ior.substring (objkey_index); + // Add the object key to the string. + + // The endpoint should now be of the form: + // `N.n://endpoint/object_key' + // or + // `//endpoint/object_key' + + TAO_Profile *profile = 0; + // Must initialize since pointer is passed as a reference! + + if (this->make_profile (endpoint.c_str (), + profile, + ACE_TRY_ENV) != 0) + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Failure: Problem during profile creation + } + + // Create a Profile using the individual endpoint string + + // Give up ownership of the profile. + if (mprofile.give_profile (profile) != 0) + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Failure presumably only occurs when MProfile is full! + // This should never happen. + } + } + else + { + ACE_THROW_RETURN (CORBA::INITIALIZE (), -1); + // Unable to seperate endpoints + } + } + + return 0; // Success } TAO_Connector::~TAO_Connector (void) { } +// Acceptor +TAO_Acceptor::TAO_Acceptor (CORBA::ULong tag) + : tag_ (tag) +{ +} + +CORBA::ULong +TAO_Acceptor::tag (void) const +{ + return this->tag_; +} + TAO_Acceptor::~TAO_Acceptor (void) { } |