summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Reference.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/Reference.cpp')
-rw-r--r--cpp/src/Ice/Reference.cpp1364
1 files changed, 829 insertions, 535 deletions
diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp
index 8faf9e32e17..27045b5a9c0 100644
--- a/cpp/src/Ice/Reference.cpp
+++ b/cpp/src/Ice/Reference.cpp
@@ -32,186 +32,156 @@ using namespace IceInternal;
void IceInternal::incRef(IceInternal::Reference* p) { p->__incRef(); }
void IceInternal::decRef(IceInternal::Reference* p) { p->__decRef(); }
-bool
-IceInternal::Reference::operator==(const Reference& r) const
+ReferencePtr
+IceInternal::Reference::changeMode(Mode newMode) const
{
- if(this == &r)
- {
- return true;
- }
-
- if(identity != r.identity)
- {
- return false;
- }
-
- if(context != r.context)
- {
- return false;
- }
-
- if(facet != r.facet)
+ if(newMode == mode)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->mode = newMode;
+ return r;
+}
- if(mode != r.mode)
+ReferencePtr
+IceInternal::Reference::changeIdentity(const Identity& newIdentity) const
+{
+ if(newIdentity == identity)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->identity = newIdentity;
+ return r;
+}
- if(secure != r.secure)
+ReferencePtr
+IceInternal::Reference::changeContext(const Context& newContext) const
+{
+ if(newContext == context)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->context = newContext;
+ return r;
+}
- if(adapterId != r.adapterId)
+ReferencePtr
+IceInternal::Reference::changeFacet(const string& newFacet) const
+{
+ if(newFacet == facet)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->facet = newFacet;
+ return r;
+}
- if(endpoints != r.endpoints)
+ReferencePtr
+IceInternal::Reference::changeSecure(bool newSecure) const
+{
+ if(newSecure == secure)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->secure = newSecure;
+ return r;
+}
- if(routerInfo != r.routerInfo)
+ReferencePtr
+IceInternal::Reference::changeCollocationOptimization(bool newCollocationOptimization) const
+{
+ if(newCollocationOptimization == collocationOptimization)
{
- return false;
+ return ReferencePtr(const_cast<Reference*>(this));
}
+ ReferencePtr r = instance->referenceFactory()->clone(this);
+ r->collocationOptimization = newCollocationOptimization;
+ return r;
+}
- if(locatorInfo != r.locatorInfo)
- {
- return false;
- }
+ReferencePtr
+IceInternal::Reference::changeRouter(const RouterPrx&) const
+{
+ return ReferencePtr(const_cast<Reference*>(this));
+}
- if(fixedConnections != r.fixedConnections)
- {
- return false;
- }
+ReferencePtr
+IceInternal::Reference::changeLocator(const LocatorPrx&) const
+{
+ return ReferencePtr(const_cast<Reference*>(this));
+}
- if(collocationOptimization != r.collocationOptimization)
- {
- return false;
- }
+ReferencePtr
+IceInternal::Reference::changeDefault() const
+{
+ return ReferencePtr(const_cast<Reference*>(this));
+}
- return true;
+ReferencePtr
+IceInternal::Reference::changeCompress(bool) const
+{
+ return ReferencePtr(const_cast<Reference*>(this));
}
-bool
-IceInternal::Reference::operator!=(const Reference& r) const
+ReferencePtr
+IceInternal::Reference::changeTimeout(int) const
{
- return !operator==(r);
+ return ReferencePtr(const_cast<Reference*>(this));
}
-bool
-IceInternal::Reference::operator<(const Reference& r) const
+Int
+Reference::hash() const
{
- if(this == &r)
- {
- return false;
- }
-
- if(identity < r.identity)
- {
- return true;
- }
- else if(r.identity < identity)
- {
- return false;
- }
-
- if(context < r.context)
- {
- return true;
- }
- else if(r.context < context)
- {
- return false;
- }
+ IceUtil::Mutex::Lock sync(hashMutex);
- if(facet < r.facet)
- {
- return true;
- }
- else if(r.facet < facet)
+ if(hashInitialized)
{
- return false;
+ return hashValue;
}
- if(mode < r.mode)
- {
- return true;
- }
- else if(r.mode < mode)
- {
- return false;
- }
-
- if(!secure && r.secure)
- {
- return true;
- }
- else if(r.secure < secure)
- {
- return false;
- }
-
- if(adapterId < r.adapterId)
- {
- return true;
- }
- else if(r.adapterId < adapterId)
- {
- return false;
- }
-
- if(endpoints < r.endpoints)
- {
- return true;
- }
- else if(r.endpoints < endpoints)
- {
- return false;
- }
-
- if(routerInfo < r.routerInfo)
- {
- return true;
- }
- else if(r.routerInfo < routerInfo)
- {
- return false;
- }
-
- if(locatorInfo < r.locatorInfo)
- {
- return true;
- }
- else if(r.locatorInfo < locatorInfo)
- {
- return false;
- }
-
- if(fixedConnections < r.fixedConnections)
+ string::const_iterator p;
+ Context::const_iterator q;
+
+ Int h = static_cast<Int>(mode);
+
+ for(p = identity.name.begin(); p != identity.name.end(); ++p)
{
- return true;
+ h = 5 * h + *p;
}
- else if(r.fixedConnections < fixedConnections)
+
+ for(p = identity.category.begin(); p != identity.category.end(); ++p)
{
- return false;
+ h = 5 * h + *p;
}
-
- if(!collocationOptimization && r.collocationOptimization)
+
+ for(q = context.begin(); q != context.end(); ++q)
{
- return true;
+ for(p = q->first.begin(); p != q->first.end(); ++p)
+ {
+ h = 5 * h + *p;
+ }
+ for(p = q->second.begin(); p != q->second.end(); ++p)
+ {
+ h = 5 * h + *p;
+ }
}
- else if(r.collocationOptimization < collocationOptimization)
+
+ for(p = facet.begin(); p != facet.end(); ++p)
{
- return false;
+ h = 5 * h + *p;
}
- return false;
+ h = 5 * h + static_cast<Int>(secure);
+
+ hashValue = h;
+ hashInitialized = true;
+
+ return h;
}
void
@@ -240,23 +210,7 @@ IceInternal::Reference::streamWrite(BasicStream* s) const
s->write(secure);
- s->writeSize(Ice::Int(endpoints.size()));
-
- if(!endpoints.empty())
- {
- assert(adapterId.empty());
-
- vector<EndpointPtr>::const_iterator p;
-
- for(p = endpoints.begin(); p != endpoints.end(); ++p)
- {
- (*p)->streamWrite(s);
- }
- }
- else
- {
- s->write(adapterId);
- }
+ // Derived class writes the remainder of the reference.
}
string
@@ -337,353 +291,850 @@ IceInternal::Reference::toString() const
s << " -s";
}
- if(!endpoints.empty())
+ return s.str();
+
+ // Derived class writes the remainder of the string.
+}
+
+bool
+IceInternal::Reference::operator==(const Reference& r) const
+{
+ //
+ // Note: if(this == &r) test is performed by each non-abstract derived class.
+ //
+
+ if(mode != r.mode)
+ {
+ return false;
+ }
+
+ if(identity != r.identity)
+ {
+ return false;
+ }
+
+ if(context != r.context)
+ {
+ return false;
+ }
+
+ if(facet != r.facet)
+ {
+ return false;
+ }
+
+ if(secure != r.secure)
+ {
+ return false;
+ }
+
+ if(collocationOptimization != r.collocationOptimization)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IceInternal::Reference::operator!=(const Reference& r) const
+{
+ return !operator==(r);
+}
+
+bool
+IceInternal::Reference::operator<(const Reference& r) const
+{
+ //
+ // Note: if(this == &r) test is performed by each non-abstract derived class.
+ //
+
+ if(mode < r.mode)
+ {
+ return true;
+ }
+ else if(r.mode < mode)
+ {
+ return false;
+ }
+
+ if(identity < r.identity)
+ {
+ return true;
+ }
+ else if(r.identity < identity)
+ {
+ return false;
+ }
+
+ if(context < r.context)
+ {
+ return true;
+ }
+ else if(r.context < context)
+ {
+ return false;
+ }
+
+ if(facet < r.facet)
+ {
+ return true;
+ }
+ else if(r.facet < facet)
+ {
+ return false;
+ }
+
+ if(!secure && r.secure)
+ {
+ return true;
+ }
+ else if(r.secure < secure)
+ {
+ return false;
+ }
+
+ if(!collocationOptimization && r.collocationOptimization)
+ {
+ return true;
+ }
+ else if(r.collocationOptimization < collocationOptimization)
+ {
+ return false;
+ }
+
+ return false;
+}
+
+class ConnectionIsDatagram : public unary_function<ConnectionIPtr, bool>
+{
+public:
+
+ bool
+ operator()(ConnectionIPtr p) const
+ {
+ return p->endpoint()->datagram();
+ }
+};
+
+class ConnectionIsSecure : public unary_function<ConnectionIPtr, bool>
+{
+public:
+
+ bool
+ operator()(ConnectionIPtr p) const
{
- assert(adapterId.empty());
+ return p->endpoint()->secure();
+ }
+};
+
+vector<ConnectionIPtr>
+IceInternal::Reference::filterConnections(const vector<ConnectionIPtr>& allConnections) const
+{
+ vector<ConnectionIPtr> connections = allConnections;
- vector<EndpointPtr>::const_iterator p;
- for(p = endpoints.begin(); p != endpoints.end(); ++p)
+ switch(mode)
+ {
+ case ModeTwoway:
+ case ModeOneway:
+ case ModeBatchOneway:
{
- string endp = (*p)->toString();
- if(!endp.empty())
- {
- s << ':' << endp;
- }
+ //
+ // Filter out datagram connections.
+ //
+ connections.erase(remove_if(connections.begin(), connections.end(), ConnectionIsDatagram()),
+ connections.end());
+ break;
+ }
+
+ case ModeDatagram:
+ case ModeBatchDatagram:
+ {
+ //
+ // Filter out non-datagram connections.
+ //
+ connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsDatagram())),
+ connections.end());
+ break;
}
}
- else if(!adapterId.empty())
+
+ //
+ // Randomize the order of connections.
+ //
+ random_shuffle(connections.begin(), connections.end());
+
+ //
+ // If a secure connection is requested, remove all non-secure
+ // connections. Otherwise make non-secure connections preferred over
+ // secure connections by partitioning the connection vector, so that
+ // non-secure connections come first.
+ //
+ if(secure)
+ {
+ connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsSecure())),
+ connections.end());
+ }
+ else
{
- string a = IceUtil::escapeString(adapterId, "");
- //
- // If the encoded adapter id string contains characters which
- // the reference parser uses as separators, then we enclose
- // the adapter id string in quotes.
- //
- s << " @ ";
- if(a.find_first_of(" \t\n\r") != string::npos)
- {
- s << '"' << a << '"';
- }
- else
- {
- s << adapterId;
- }
+ //
+ // We must use stable_partition() instead of just simply
+ // partition(), because otherwise some STL implementations
+ // order our now randomized connections.
+ //
+ stable_partition(connections.begin(), connections.end(), not1(ConnectionIsSecure()));
}
- return s.str();
+ return connections;
}
-ReferencePtr
-IceInternal::Reference::changeIdentity(const Identity& newIdentity) const
+IceInternal::Reference::Reference(const InstancePtr& inst, const Ice::Identity& ident, const Ice::Context& ctx,
+ const std::string& fs, Mode md, bool sec, bool collocationOpt)
+ : instance(inst),
+ mode(md),
+ identity(ident),
+ context(ctx),
+ facet(fs),
+ secure(sec),
+ collocationOptimization(collocationOpt),
+ hashInitialized(false)
{
- if(newIdentity == identity)
+}
+
+IceInternal::Reference::Reference(const Reference& r)
+{
+ instance = r.instance;
+ mode = r.mode;
+ identity = r.identity;
+ context = r.context;
+ facet = r.facet;
+ secure = r.secure;
+ collocationOptimization = r.collocationOptimization;
+ hashInitialized = false;
+}
+
+void IceInternal::incRef(IceInternal::FixedReference* p) { p->__incRef(); }
+void IceInternal::decRef(IceInternal::FixedReference* p) { p->__decRef(); }
+
+IceInternal::FixedReference::FixedReference(const InstancePtr& inst, const Ice::Identity& ident,
+ const Ice::Context& ctx, const std::string& fs, Mode md,
+ bool sec, bool collocationOpt,
+ const vector<Ice::ConnectionIPtr>& fixedConns)
+ : Reference(inst, ident, ctx, fs, md, sec, collocationOpt),
+ fixedConnections(fixedConns)
+{
+}
+
+vector<EndpointPtr>
+IceInternal::FixedReference::getEndpoints() const
+{
+ return vector<EndpointPtr>();
+}
+
+void
+IceInternal::FixedReference::streamWrite(BasicStream* s) const
+{
+ MarshalException ex(__FILE__, __LINE__);
+ ex.reason = "Cannot marshal a fixed reference";
+ throw ex;
+}
+
+string
+IceInternal::FixedReference::toString() const
+{
+ MarshalException ex(__FILE__, __LINE__);
+ ex.reason = "Cannot stringify a fixed reference";
+ throw ex;
+}
+
+ConnectionIPtr
+IceInternal::FixedReference::getConnection(bool& compress) const
+{
+ vector<ConnectionIPtr> filteredConns = filterConnections(fixedConnections);
+ if(filteredConns.empty())
{
- return ReferencePtr(const_cast<Reference*>(this));
+ NoEndpointException ex(__FILE__, __LINE__);
+ ex.proxy = toString();
+ throw ex;
}
- else
+
+ ConnectionIPtr connection = filteredConns[0];
+ assert(connection);
+ compress = connection->endpoint()->compress();
+
+ return connection;
+}
+
+bool
+IceInternal::FixedReference::operator==(const Reference& r) const
+{
+ if(this == &r)
+ {
+ return true;
+ }
+ const FixedReference* rhs = dynamic_cast<const FixedReference*>(&r);
+ if(!rhs || !Reference::operator==(r))
{
- return instance->referenceFactory()->create(newIdentity, context, facet, mode, secure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return false;
}
+ return fixedConnections == rhs->fixedConnections;
}
-ReferencePtr
-IceInternal::Reference::changeContext(const Context& newContext) const
+bool
+IceInternal::FixedReference::operator!=(const Reference& r) const
{
- if(newContext == context)
+ return !operator==(r);
+}
+
+bool
+IceInternal::FixedReference::operator<(const Reference& r) const
+{
+ if(this == &r)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return false;
}
- else
+ const FixedReference* rhs = dynamic_cast<const FixedReference*>(&r);
+ if(!rhs || !Reference::operator<(r))
{
- return instance->referenceFactory()->create(identity, newContext, facet, mode, secure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return false;
}
+ return fixedConnections < rhs->fixedConnections;
}
ReferencePtr
-IceInternal::Reference::changeFacet(const string& newFacet) const
+IceInternal::FixedReference::clone() const
{
- if(newFacet == facet)
+ return new FixedReference(*this);
+}
+
+IceInternal::FixedReference::FixedReference(const FixedReference& r)
+ : Reference(r)
+{
+ fixedConnections = r.fixedConnections;
+}
+
+void IceInternal::incRef(IceInternal::RoutableReference* p) { p->__incRef(); }
+void IceInternal::decRef(IceInternal::RoutableReference* p) { p->__decRef(); }
+
+std::vector<EndpointPtr>
+IceInternal::RoutableReference::getRoutedEndpoints() const
+{
+ if(routerInfo)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ //
+ // If we route, we send everything to the router's client
+ // proxy endpoints.
+ //
+ ObjectPrx clientProxy = routerInfo->getClientProxy();
+ return clientProxy->__reference()->getEndpoints();
}
- else
+ return vector<EndpointPtr>();
+}
+
+ReferencePtr
+IceInternal::RoutableReference::changeRouter(const RouterPrx& newRouter) const
+{
+ RouterInfoPtr newRouterInfo = getInstance()->routerManager()->get(newRouter);
+ if(newRouterInfo == routerInfo)
{
- return instance->referenceFactory()->create(identity, context, newFacet, mode, secure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return RoutableReferencePtr(const_cast<RoutableReference*>(this));
}
+ RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this));
+ r->routerInfo = newRouterInfo;
+ return r;
+}
+
+ReferencePtr
+IceInternal::RoutableReference::changeDefault() const
+{
+ RoutableReferencePtr r = RoutableReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this));
+ r->routerInfo = getInstance()->routerManager()->get(getInstance()->referenceFactory()->getDefaultRouter());
+ return r;
+}
+
+ReferencePtr
+IceInternal::RoutableReference::changeCompress(bool newCompress) const
+{
+ return RoutableReferencePtr(const_cast<RoutableReference*>(this));
}
ReferencePtr
-IceInternal::Reference::changeTimeout(int newTimeout) const
+IceInternal::RoutableReference::changeTimeout(int newTimeout) const
+{
+ return RoutableReferencePtr(const_cast<RoutableReference*>(this));
+}
+
+void
+IceInternal::RoutableReference::streamWrite(BasicStream* s) const
+{
+ Reference::streamWrite(s);
+}
+
+string
+IceInternal::RoutableReference::toString() const
+{
+ return Reference::toString();
+}
+
+bool
+IceInternal::RoutableReference::operator==(const Reference& r) const
{
//
- // We change the timeout settings in all endpoints.
+ // Note: if(this == &r) test is performed by each non-abstract derived class.
//
- vector<EndpointPtr>::const_iterator p;
- vector<EndpointPtr> newEndpoints;
- for(p = endpoints.begin(); p != endpoints.end(); ++p)
+ const RoutableReference* rhs = dynamic_cast<const RoutableReference*>(&r);
+ if(!rhs || !Reference::operator==(r))
{
- newEndpoints.push_back((*p)->timeout(newTimeout));
+ return false;
}
-
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- newEndpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return routerInfo == rhs->routerInfo;
}
-ReferencePtr
-IceInternal::Reference::changeMode(Mode newMode) const
+bool
+IceInternal::RoutableReference::operator!=(const Reference& r) const
{
- if(newMode == mode)
+ return !operator==(r);
+}
+
+bool
+IceInternal::RoutableReference::operator<(const Reference& r) const
+{
+ if(this == &r)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return false;
}
- else
+ const RoutableReference* rhs = dynamic_cast<const RoutableReference*>(&r);
+ if(!rhs || !Reference::operator<(r))
{
- return instance->referenceFactory()->create(identity, context, facet, newMode, secure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return false;
}
+ return routerInfo < rhs->routerInfo;
}
-ReferencePtr
-IceInternal::Reference::changeSecure(bool newSecure) const
+IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const Ice::Identity& ident,
+ const Ice::Context& ctx, const std::string& fs, Mode md,
+ bool sec, const RouterInfoPtr& rtrInfo, bool collocationOpt)
+ : Reference(inst, ident, ctx, fs, md, sec, collocationOpt),
+ routerInfo(rtrInfo)
{
- if(newSecure == secure)
+}
+
+IceInternal::RoutableReference::RoutableReference(const RoutableReference& r)
+ : Reference(r)
+{
+ routerInfo = r.routerInfo;
+}
+
+void IceInternal::incRef(IceInternal::DirectReference* p) { p->__incRef(); }
+void IceInternal::decRef(IceInternal::DirectReference* p) { p->__decRef(); }
+
+IceInternal::DirectReference::DirectReference(const InstancePtr& inst, const Ice::Identity& ident,
+ const Ice::Context& ctx, const std::string& fs, Mode md,
+ bool sec, const std::vector<EndpointPtr>& endpts,
+ const RouterInfoPtr& rtrInfo, bool collocationOpt)
+ : RoutableReference(inst, ident, ctx, fs, md, sec, rtrInfo, collocationOpt),
+ endpoints(endpts)
+{
+}
+
+vector<EndpointPtr>
+IceInternal::DirectReference::getEndpoints() const
+{
+ return endpoints;
+}
+
+DirectReferencePtr
+IceInternal::DirectReference::changeEndpoints(const vector<EndpointPtr>& newEndpoints) const
+{
+ if(newEndpoints == endpoints)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return DirectReferencePtr(const_cast<DirectReference*>(this));
}
- else
+ DirectReferencePtr r = DirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this));
+ r->endpoints = newEndpoints;
+ return r;
+}
+
+ReferencePtr
+IceInternal::DirectReference::changeCompress(bool newCompress) const
+{
+ DirectReferencePtr r = DirectReferencePtr::dynamicCast(RoutableReference::changeCompress(newCompress));
+ vector<EndpointPtr> newEndpoints;
+ vector<EndpointPtr>::const_iterator p;
+ for(p = endpoints.begin(); p != endpoints.end(); ++p)
{
- return instance->referenceFactory()->create(identity, context, facet, mode, newSecure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ newEndpoints.push_back((*p)->compress(newCompress));
}
+ r->endpoints = newEndpoints;
+ return r;
}
ReferencePtr
-IceInternal::Reference::changeCompress(bool newCompress) const
+IceInternal::DirectReference::changeTimeout(int newTimeout) const
{
- //
- // We change the compress settings in all endpoints.
- //
+ DirectReferencePtr r = DirectReferencePtr::dynamicCast(RoutableReference::changeTimeout(newTimeout));
+ vector<EndpointPtr> newEndpoints;
vector<EndpointPtr>::const_iterator p;
+ for(p = endpoints.begin(); p != endpoints.end(); ++p)
+ {
+ newEndpoints.push_back((*p)->timeout(newTimeout));
+ }
+ r->endpoints = newEndpoints;
+ return r;
+}
- vector<EndpointPtr> newEndpoints;
+void
+IceInternal::DirectReference::streamWrite(BasicStream* s) const
+{
+ RoutableReference::streamWrite(s);
+
+ s->writeSize(Ice::Int(endpoints.size()));
+ vector<EndpointPtr>::const_iterator p;
for(p = endpoints.begin(); p != endpoints.end(); ++p)
{
- newEndpoints.push_back((*p)->compress(newCompress));
+ (*p)->streamWrite(s);
}
-
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- newEndpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
}
-ReferencePtr
-IceInternal::Reference::changeAdapterId(const string& newAdapterId) const
+string
+IceInternal::DirectReference::toString() const
{
- if(newAdapterId == adapterId)
+ string result = RoutableReference::toString();
+
+ vector<EndpointPtr>::const_iterator p;
+ for(p = endpoints.begin(); p != endpoints.end(); ++p)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ string endp = (*p)->toString();
+ if(!endp.empty())
+ {
+ result.append(":");
+ result.append(endp);
+ }
}
- else
+ return result;
+}
+
+ConnectionIPtr
+IceInternal::DirectReference::getConnection(bool& comp) const
+{
+ vector<EndpointPtr> endpts = RoutableReference::getRoutedEndpoints();
+ if(endpts.empty())
+ {
+ endpts = endpoints;
+ }
+ vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure());
+ if(filteredEndpoints.empty())
{
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, newAdapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ NoEndpointException ex(__FILE__, __LINE__);
+ ex.proxy = toString();
+ throw ex;
}
+
+ OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory();
+ ConnectionIPtr connection = factory->create(filteredEndpoints, comp);
+ assert(connection);
+
+ //
+ // If we have a router, set the object adapter for this router
+ // (if any) to the new connection, so that callbacks from the
+ // router can be received over this new connection.
+ //
+ if(getRouterInfo())
+ {
+ connection->setAdapter(getRouterInfo()->getAdapter());
+ }
+
+ assert(connection);
+ return connection;
}
-ReferencePtr
-IceInternal::Reference::changeEndpoints(const vector<EndpointPtr>& newEndpoints) const
+bool
+IceInternal::DirectReference::operator==(const Reference& r) const
{
- if(newEndpoints == endpoints)
+ if(this == &r)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return true;
}
- else
+ const DirectReference* rhs = dynamic_cast<const DirectReference*>(&r);
+ if(!rhs || !RoutableReference::operator==(r))
{
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- newEndpoints, routerInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return false;
}
+ return endpoints == rhs->endpoints;
}
-ReferencePtr
-IceInternal::Reference::changeRouter(const RouterPrx& newRouter) const
+bool
+IceInternal::DirectReference::operator!=(const Reference& r) const
{
- RouterInfoPtr newRouterInfo = instance->routerManager()->get(newRouter);
+ return !operator==(r);
+}
- if(newRouterInfo == routerInfo)
+bool
+IceInternal::DirectReference::operator<(const Reference& r) const
+{
+ if(this == &r)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return false;
}
- else
+ const DirectReference* rhs = dynamic_cast<const DirectReference*>(&r);
+ if(!rhs || !RoutableReference::operator<(r))
{
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- endpoints, newRouterInfo, locatorInfo, fixedConnections,
- collocationOptimization);
+ return false;
}
+ return endpoints < rhs->endpoints;
}
ReferencePtr
-IceInternal::Reference::changeLocator(const LocatorPrx& newLocator) const
+IceInternal::DirectReference::clone() const
{
- LocatorInfoPtr newLocatorInfo = instance->locatorManager()->get(newLocator);
+ return new DirectReference(*this);
+}
- if(newLocatorInfo == locatorInfo)
+IceInternal::DirectReference::DirectReference(const DirectReference& r)
+ : RoutableReference(r)
+{
+ endpoints = r.endpoints;
+}
+
+
+void IceInternal::incRef(IceInternal::IndirectReference* p) { p->__incRef(); }
+void IceInternal::decRef(IceInternal::IndirectReference* p) { p->__decRef(); }
+
+IceInternal::IndirectReference::IndirectReference(const InstancePtr& inst, const Ice::Identity& ident,
+ const Ice::Context& ctx, const std::string& fs, Mode md,
+ bool sec, const string& adptid, const RouterInfoPtr& rtrInfo,
+ const LocatorInfoPtr& locInfo, bool collocationOpt)
+ : RoutableReference(inst, ident, ctx, fs, md, sec, rtrInfo, collocationOpt),
+ adapterId(adptid),
+ locatorInfo(locInfo)
+{
+}
+
+vector<EndpointPtr>
+IceInternal::IndirectReference::getEndpoints() const
+{
+ return vector<EndpointPtr>();
+}
+
+IndirectReferencePtr
+IceInternal::IndirectReference::changeAdapterId(const string& newAdapterId) const
+{
+ if(newAdapterId == adapterId)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ return IndirectReferencePtr(const_cast<IndirectReference*>(this));
}
- else
+ IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this));
+ r->adapterId = adapterId;
+ return r;
+}
+
+ReferencePtr
+IceInternal::IndirectReference::changeLocator(const LocatorPrx& newLocator) const
+{
+ LocatorInfoPtr newLocatorInfo = getInstance()->locatorManager()->get(newLocator);
+
+ if(newLocatorInfo == locatorInfo)
{
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- endpoints, routerInfo, newLocatorInfo, fixedConnections,
- collocationOptimization);
+ return IndirectReferencePtr(const_cast<IndirectReference*>(this));
}
+ IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(getInstance()->referenceFactory()->clone(this));
+ r->locatorInfo = newLocatorInfo;
+ return r;
}
ReferencePtr
-IceInternal::Reference::changeCollocationOptimization(bool newCollocationOptimization) const
+IceInternal::IndirectReference::changeDefault() const
{
- if(newCollocationOptimization == collocationOptimization)
+ IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeDefault());
+ r->locatorInfo = getInstance()->locatorManager()->get(getInstance()->referenceFactory()->getDefaultLocator());
+ return r;
+}
+
+ReferencePtr
+IceInternal::IndirectReference::changeCompress(bool newCompress) const
+{
+ IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeCompress(newCompress));
+ if(locatorInfo)
{
- return ReferencePtr(const_cast<Reference*>(this));
+ LocatorPrx newLocator = LocatorPrx::uncheckedCast(locatorInfo->getLocator()->ice_compress(newCompress));
+ r->locatorInfo = getInstance()->locatorManager()->get(newLocator);
}
- else
+ return r;
+}
+
+ReferencePtr
+IceInternal::IndirectReference::changeTimeout(int newTimeout) const
+{
+ IndirectReferencePtr r = IndirectReferencePtr::dynamicCast(RoutableReference::changeTimeout(newTimeout));
+ LocatorInfoPtr newLocatorInfo;
+ if(locatorInfo)
{
- return instance->referenceFactory()->create(identity, context, facet, mode, secure, adapterId,
- endpoints, routerInfo, locatorInfo, fixedConnections,
- newCollocationOptimization);
+ LocatorPrx newLocator = LocatorPrx::uncheckedCast(locatorInfo->getLocator()->ice_timeout(newTimeout));
+ r->locatorInfo = getInstance()->locatorManager()->get(newLocator);
}
+ return r;
}
-ReferencePtr
-IceInternal::Reference::changeDefault() const
+void
+IceInternal::IndirectReference::streamWrite(BasicStream* s) const
{
- RouterInfoPtr defaultRouterInfo = instance->routerManager()->
- get(instance->referenceFactory()->getDefaultRouter());
- LocatorInfoPtr defaultLocatorInfo = instance->locatorManager()->
- get(instance->referenceFactory()->getDefaultLocator());
+ RoutableReference::streamWrite(s);
- return instance->referenceFactory()->create(identity, context, "", ModeTwoway, false, adapterId,
- endpoints, defaultRouterInfo, defaultLocatorInfo,
- vector<ConnectionIPtr>(), true);
+ s->writeSize(0);
+ s->write(adapterId);
}
-ConnectionIPtr
-IceInternal::Reference::getConnection(bool& compress) const
+string
+IceInternal::IndirectReference::toString() const
{
- ConnectionIPtr connection;
+ string result = RoutableReference::toString();
+ if(adapterId.empty())
+ {
+ return result;
+ }
+ result.append(" @ ");
//
- // If we have a fixed connection, we return such fixed connection.
+ // If the encoded adapter id string contains characters which
+ // the reference parser uses as separators, then we enclose
+ // the adapter id string in quotes.
//
- if(!fixedConnections.empty())
+ string a = IceUtil::escapeString(adapterId, "");
+ if(a.find_first_of(" \t\n\r") != string::npos)
+ {
+ result.append("\"");
+ result.append(a);
+ result.append("\"");
+ }
+ else
+ {
+ result.append(adapterId);
+ }
+ return result;
+}
+
+ConnectionIPtr
+IceInternal::IndirectReference::getConnection(bool& comp) const
+{
+ ConnectionIPtr connection;
+
+ while(true)
{
- vector<ConnectionIPtr> filteredConns = filterConnections(fixedConnections);
- if(filteredConns.empty())
+ vector<EndpointPtr> endpts = RoutableReference::getRoutedEndpoints();
+ bool cached;
+ if(endpts.empty() && locatorInfo)
+ {
+ const IndirectReferencePtr self = const_cast<IndirectReference*>(this);
+ endpts = locatorInfo->getEndpoints(self, cached);
+ }
+ vector<EndpointPtr> filteredEndpoints = filterEndpoints(endpts, getMode(), getSecure());
+ if(filteredEndpoints.empty())
{
NoEndpointException ex(__FILE__, __LINE__);
ex.proxy = toString();
throw ex;
}
- connection = filteredConns[0];
- compress = connection->endpoint()->compress();
- }
- else
- {
- while(true)
+ try
{
- bool cached;
- vector<EndpointPtr> endpts;
-
- if(routerInfo)
- {
- //
- // If we route, we send everything to the router's client
- // proxy endpoints.
- //
- ObjectPrx clientProxy = routerInfo->getClientProxy();
- endpts = clientProxy->__reference()->endpoints;
- }
- else if(!endpoints.empty())
- {
- endpts = endpoints;
- }
- else if(locatorInfo)
- {
- ReferencePtr self = const_cast<Reference*>(this);
- endpts = locatorInfo->getEndpoints(self, cached);
- }
-
- vector<EndpointPtr> filteredEndpts = filterEndpoints(endpts);
- if(filteredEndpts.empty())
- {
- NoEndpointException ex(__FILE__, __LINE__);
- ex.proxy = toString();
- throw ex;
- }
-
- try
- {
- OutgoingConnectionFactoryPtr factory = instance->outgoingConnectionFactory();
- connection = factory->create(filteredEndpts, compress);
- assert(connection);
- }
- catch(const LocalException& ex)
+ OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory();
+ connection = factory->create(filteredEndpoints, comp);
+ assert(connection);
+ }
+ catch(const LocalException& ex)
+ {
+ if(!getRouterInfo())
{
- if(!routerInfo && endpoints.empty())
- {
- assert(locatorInfo);
- ReferencePtr self = const_cast<Reference*>(this);
- locatorInfo->clearCache(self);
-
- if(cached)
+ assert(locatorInfo);
+ const IndirectReferencePtr self = const_cast<IndirectReference*>(this);
+ locatorInfo->clearCache(self);
+
+ if(cached)
+ {
+ TraceLevelsPtr traceLevels = getInstance()->traceLevels();
+ LoggerPtr logger = getInstance()->logger();
+ if(traceLevels->retry >=2)
{
- TraceLevelsPtr traceLevels = instance->traceLevels();
- LoggerPtr logger = instance->logger();
- if(traceLevels->retry >= 2)
- {
- Trace out(logger, traceLevels->retryCat);
- out << "connection to cached endpoints failed\n"
- << "removing endpoints from cache and trying one more time\n" << ex;
- }
- continue;
+ Trace out(logger, traceLevels->retryCat);
+ out << "connection to cached endpoints failed\n"
+ << "removing endpoints from cache and trying one more time\n" << ex;
}
+ continue;
}
-
- throw;
}
-
- break;
- }
-
- //
- // If we have a router, set the object adapter for this router
- // (if any) to the new connection, so that callbacks from the
- // router can be received over this new connection.
- //
- if(routerInfo)
- {
- connection->setAdapter(routerInfo->getAdapter());
+
+ throw;
}
+
+ break;
+ }
+
+ //
+ // If we have a router, set the object adapter for this router
+ // (if any) to the new connection, so that callbacks from the
+ // router can be received over this new connection.
+ //
+ if(getRouterInfo())
+ {
+ connection->setAdapter(getRouterInfo()->getAdapter());
}
assert(connection);
return connection;
}
+bool
+IceInternal::IndirectReference::operator==(const Reference& r) const
+{
+ if(this == &r)
+ {
+ return true;
+ }
+ const IndirectReference* rhs = dynamic_cast<const IndirectReference*>(&r);
+ if(!rhs || !RoutableReference::operator==(r))
+ {
+ return false;
+ }
+ return adapterId == rhs->adapterId && locatorInfo == rhs->locatorInfo;
+}
+
+bool
+IceInternal::IndirectReference::operator!=(const Reference& r) const
+{
+ return !operator==(r);
+}
+
+bool
+IceInternal::IndirectReference::operator<(const Reference& r) const
+{
+ if(this == &r)
+ {
+ return false;
+ }
+ const IndirectReference* rhs = dynamic_cast<const IndirectReference*>(&r);
+ if(!rhs || !RoutableReference::operator<(r))
+ {
+ return false;
+ }
+ return adapterId < rhs->adapterId && locatorInfo < rhs->locatorInfo;
+}
+
+ReferencePtr
+IceInternal::IndirectReference::clone() const
+{
+ return new IndirectReference(*this);
+}
+
+IceInternal::IndirectReference::IndirectReference(const IndirectReference& r)
+ : RoutableReference(r)
+{
+ adapterId = r.adapterId;
+ locatorInfo = r.locatorInfo;
+}
+
vector<EndpointPtr>
-IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints) const
+IceInternal::filterEndpoints(const vector<EndpointPtr>& allEndpoints, Reference::Mode m, bool sec)
{
vector<EndpointPtr> endpoints = allEndpoints;
@@ -693,11 +1144,11 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints)
endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::unknown)),
endpoints.end());
- switch(mode)
+ switch(m)
{
- case ModeTwoway:
- case ModeOneway:
- case ModeBatchOneway:
+ case Reference::ModeTwoway:
+ case Reference::ModeOneway:
+ case Reference::ModeBatchOneway:
{
//
// Filter out datagram endpoints.
@@ -707,8 +1158,8 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints)
break;
}
- case ModeDatagram:
- case ModeBatchDatagram:
+ case Reference::ModeDatagram:
+ case Reference::ModeBatchDatagram:
{
//
// Filter out non-datagram endpoints.
@@ -731,7 +1182,7 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints)
// secure endpoints by partitioning the endpoint vector, so that
// non-secure endpoints come first.
//
- if(secure)
+ if(sec)
{
endpoints.erase(remove_if(endpoints.begin(), endpoints.end(), not1(Ice::constMemFun(&Endpoint::secure))),
endpoints.end());
@@ -749,160 +1200,3 @@ IceInternal::Reference::filterEndpoints(const vector<EndpointPtr>& allEndpoints)
return endpoints;
}
-class ConnectionIsDatagram : public unary_function<ConnectionIPtr, bool>
-{
-public:
-
- bool
- operator()(ConnectionIPtr p) const
- {
- return p->endpoint()->datagram();
- }
-};
-
-class ConnectionIsSecure : public unary_function<ConnectionIPtr, bool>
-{
-public:
-
- bool
- operator()(ConnectionIPtr p) const
- {
- return p->endpoint()->secure();
- }
-};
-
-vector<ConnectionIPtr>
-IceInternal::Reference::filterConnections(const vector<ConnectionIPtr>& allConnections) const
-{
- vector<ConnectionIPtr> connections = allConnections;
-
- switch(mode)
- {
- case ModeTwoway:
- case ModeOneway:
- case ModeBatchOneway:
- {
- //
- // Filter out datagram connections.
- //
- connections.erase(remove_if(connections.begin(), connections.end(), ConnectionIsDatagram()),
- connections.end());
- break;
- }
-
- case ModeDatagram:
- case ModeBatchDatagram:
- {
- //
- // Filter out non-datagram connections.
- //
- connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsDatagram())),
- connections.end());
- break;
- }
- }
-
- //
- // Randomize the order of connections.
- //
- random_shuffle(connections.begin(), connections.end());
-
- //
- // If a secure connection is requested, remove all non-secure
- // connections. Otherwise make non-secure connections preferred over
- // secure connections by partitioning the connection vector, so that
- // non-secure connections come first.
- //
- if(secure)
- {
- connections.erase(remove_if(connections.begin(), connections.end(), not1(ConnectionIsSecure())),
- connections.end());
- }
- else
- {
- //
- // We must use stable_partition() instead of just simply
- // partition(), because otherwise some STL implementations
- // order our now randomized connections.
- //
- stable_partition(connections.begin(), connections.end(), not1(ConnectionIsSecure()));
- }
-
- return connections;
-}
-
-IceInternal::Reference::Reference(const InstancePtr& inst,
- const Identity& ident,
- const Context& ctx,
- const string& fs,
- Mode md,
- bool sec,
- const string& adptid,
- const vector<EndpointPtr>& endpts,
- const RouterInfoPtr& rtrInfo,
- const LocatorInfoPtr& locInfo,
- const vector<ConnectionIPtr>& fixedConns,
- bool collocationOpt) :
- instance(inst),
- identity(ident),
- context(ctx),
- facet(fs),
- mode(md),
- secure(sec),
- adapterId(adptid),
- endpoints(endpts),
- routerInfo(rtrInfo),
- locatorInfo(locInfo),
- fixedConnections(fixedConns),
- collocationOptimization(collocationOpt),
- hashValue(0)
-{
- //
- // It's either adapter id or endpoints, it can't be both.
- //
- assert(!(!adapterId.empty() && !endpoints.empty()));
-
- Int h = 0;
-
- string::const_iterator p;
- Context::const_iterator q;
-
- for(p = identity.name.begin(); p != identity.name.end(); ++p)
- {
- h = 5 * h + *p;
- }
-
- for(p = identity.category.begin(); p != identity.category.end(); ++p)
- {
- h = 5 * h + *p;
- }
-
- for(q = context.begin(); q != context.end(); ++q)
- {
- for(p = q->first.begin(); p != q->first.end(); ++p)
- {
- h = 5 * h + *p;
- }
- for(p = q->second.begin(); p != q->second.end(); ++p)
- {
- h = 5 * h + *p;
- }
- }
-
- for(p = facet.begin(); p != facet.end(); ++p)
- {
- h = 5 * h + *p;
- }
-
- h = 5 * h + static_cast<Int>(mode);
-
- h = 5 * h + static_cast<Int>(secure);
-
- //
- // TODO: Should we also take the endpoints and other stuff into
- // account for hash calculation? Perhaps not, the code above
- // should be good enough for a good hash value.
- //
-
- const_cast<Int&>(hashValue) = h;
-}