summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-03-15 10:06:45 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-03-15 10:06:45 +0000
commit2f982f8647e1947476d1ed59547db5a66bd0df6e (patch)
treee682054fc676e2a35903c6d8c0e10a573e31b80e
parentadding SSL support (diff)
downloadice-2f982f8647e1947476d1ed59547db5a66bd0df6e.tar.bz2
ice-2f982f8647e1947476d1ed59547db5a66bd0df6e.tar.xz
ice-2f982f8647e1947476d1ed59547db5a66bd0df6e.zip
Fixes for bug 897.
-rw-r--r--cpp/include/Ice/OutgoingAsync.h4
-rw-r--r--cpp/include/Ice/Proxy.h6
-rw-r--r--cpp/src/Ice/ConnectionI.cpp52
-rw-r--r--cpp/src/Ice/ConnectionI.h5
-rw-r--r--cpp/src/Ice/Makefile1
-rw-r--r--cpp/src/Ice/Outgoing.cpp3
-rw-r--r--cpp/src/Ice/OutgoingAsync.cpp101
-rw-r--r--cpp/src/Ice/Protocol.h9
-rw-r--r--cpp/src/Ice/Proxy.cpp23
-rw-r--r--cpp/src/IceGrid/Database.cpp4
-rw-r--r--cpp/src/IceGrid/LocatorI.cpp3
-rw-r--r--cpp/test/Ice/binding/AllTests.cpp132
12 files changed, 195 insertions, 148 deletions
diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h
index 42ab59596d5..cdb8d708e3e 100644
--- a/cpp/include/Ice/OutgoingAsync.h
+++ b/cpp/include/Ice/OutgoingAsync.h
@@ -56,11 +56,9 @@ private:
void cleanup();
- ReferencePtr _reference;
- ::Ice::ConnectionIPtr _connection;
+ ::Ice::ObjectPrx _proxy;
int _cnt;
Ice::OperationMode _mode;
- bool _compress;
IceUtil::Monitor<IceUtil::RecMutex> _monitor;
};
diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h
index 7853fda3beb..ad62ed11017 100644
--- a/cpp/include/Ice/Proxy.h
+++ b/cpp/include/Ice/Proxy.h
@@ -198,7 +198,7 @@ public:
virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::vector< ::Ice::Byte>&,
::std::vector< ::Ice::Byte>&, const ::Ice::Context&) = 0;
- virtual ::Ice::ConnectionPtr ice_connection() = 0;
+ virtual ::Ice::ConnectionIPtr __getConnection(bool&) const = 0;
};
} }
@@ -219,7 +219,7 @@ public:
virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::vector< ::Ice::Byte>&,
::std::vector< ::Ice::Byte>&, const ::Ice::Context&);
- virtual ::Ice::ConnectionPtr ice_connection();
+ virtual ::Ice::ConnectionIPtr __getConnection(bool&) const;
void __copyFrom(const ::IceInternal::Handle< ::IceDelegateM::Ice::Object>&);
@@ -251,7 +251,7 @@ public:
virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::vector< ::Ice::Byte>&,
::std::vector< ::Ice::Byte>&, const ::Ice::Context&);
- virtual ::Ice::ConnectionPtr ice_connection();
+ virtual ::Ice::ConnectionIPtr __getConnection(bool&) const;
void __copyFrom(const ::IceInternal::Handle< ::IceDelegateD::Ice::Object>&);
diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp
index 30f1c9a8140..4d8171c6783 100644
--- a/cpp/src/Ice/ConnectionI.cpp
+++ b/cpp/src/Ice/ConnectionI.cpp
@@ -476,15 +476,6 @@ Ice::ConnectionI::monitor()
}
}
-//
-// TODO: Should not be a member function of Connection.
-//
-void
-Ice::ConnectionI::prepareRequest(BasicStream* os)
-{
- os->writeBlob(_requestHdr);
-}
-
void
Ice::ConnectionI::sendRequest(BasicStream* os, Outgoing* out, bool compress)
{
@@ -834,7 +825,7 @@ Ice::ConnectionI::prepareBatchRequest(BasicStream* os)
{
try
{
- _batchStream.writeBlob(_requestBatchHdr);
+ _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr));
}
catch(const LocalException& ex)
{
@@ -1411,9 +1402,6 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance,
_finishedCount(0),
_warn(_instance->properties()->getPropertyAsInt("Ice.Warn.Connections") > 0),
_acmTimeout(0),
- _requestHdr(headerSize + sizeof(Int), 0),
- _requestBatchHdr(headerSize + sizeof(Int), 0),
- _replyHdr(headerSize, 0),
_compressionLevel(1),
_nextRequestId(1),
_requestsHint(_requests.end()),
@@ -1443,42 +1431,6 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance,
}
}
- vector<Byte>& requestHdr = const_cast<vector<Byte>&>(_requestHdr);
- requestHdr[0] = magic[0];
- requestHdr[1] = magic[1];
- requestHdr[2] = magic[2];
- requestHdr[3] = magic[3];
- requestHdr[4] = protocolMajor;
- requestHdr[5] = protocolMinor;
- requestHdr[6] = encodingMajor;
- requestHdr[7] = encodingMinor;
- requestHdr[8] = requestMsg;
- requestHdr[9] = 0;
-
- vector<Byte>& requestBatchHdr = const_cast<vector<Byte>&>(_requestBatchHdr);
- requestBatchHdr[0] = magic[0];
- requestBatchHdr[1] = magic[1];
- requestBatchHdr[2] = magic[2];
- requestBatchHdr[3] = magic[3];
- requestBatchHdr[4] = protocolMajor;
- requestBatchHdr[5] = protocolMinor;
- requestBatchHdr[6] = encodingMajor;
- requestBatchHdr[7] = encodingMinor;
- requestBatchHdr[8] = requestBatchMsg;
- requestBatchHdr[9] = 0;
-
- vector<Byte>& replyHdr = const_cast<vector<Byte>&>(_replyHdr);
- replyHdr[0] = magic[0];
- replyHdr[1] = magic[1];
- replyHdr[2] = magic[2];
- replyHdr[3] = magic[3];
- replyHdr[4] = protocolMajor;
- replyHdr[5] = protocolMinor;
- replyHdr[6] = encodingMajor;
- replyHdr[7] = encodingMinor;
- replyHdr[8] = replyMsg;
- replyHdr[9] = 0;
-
int& compressionLevel = const_cast<int&>(_compressionLevel);
compressionLevel = _instance->properties()->getPropertyAsIntWithDefault("Ice.Compression.Level", 1);
if(compressionLevel < 1)
@@ -2255,7 +2207,7 @@ Ice::ConnectionI::invokeAll(BasicStream& stream, Int invokeNum, Int requestId, B
if(response)
{
assert(invokeNum == 1); // No further invocations if a response is expected.
- os->writeBlob(_replyHdr);
+ os->writeBlob(replyHdr, sizeof(replyHdr));
//
// Add the request ID.
diff --git a/cpp/src/Ice/ConnectionI.h b/cpp/src/Ice/ConnectionI.h
index 2405def16eb..78404cdbcab 100644
--- a/cpp/src/Ice/ConnectionI.h
+++ b/cpp/src/Ice/ConnectionI.h
@@ -64,7 +64,6 @@ public:
void monitor();
- void prepareRequest(IceInternal::BasicStream*);
void sendRequest(IceInternal::BasicStream*, IceInternal::Outgoing*, bool);
void sendAsyncRequest(IceInternal::BasicStream*, const IceInternal::OutgoingAsyncPtr&, bool);
@@ -165,10 +164,6 @@ private:
const int _acmTimeout;
IceUtil::Time _acmAbsoluteTimeout;
- const std::vector<Byte> _requestHdr;
- const std::vector<Byte> _requestBatchHdr;
- const std::vector<Byte> _replyHdr;
-
const int _compressionLevel;
Int _nextRequestId;
diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile
index afe2e0981d3..042690013c8 100644
--- a/cpp/src/Ice/Makefile
+++ b/cpp/src/Ice/Makefile
@@ -80,6 +80,7 @@ OBJS = Acceptor.o \
PropertiesI.o \
Properties.o \
PropertyNames.o \
+ Protocol.o \
ProtocolPluginFacade.o \
ProxyFactory.o \
Proxy.o \
diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp
index fd8c0b46786..448a891f579 100644
--- a/cpp/src/Ice/Outgoing.cpp
+++ b/cpp/src/Ice/Outgoing.cpp
@@ -13,6 +13,7 @@
#include <Ice/Reference.h>
#include <Ice/Endpoint.h>
#include <Ice/LocalException.h>
+#include <Ice/Protocol.h>
using namespace std;
using namespace Ice;
@@ -58,7 +59,7 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s
case Reference::ModeOneway:
case Reference::ModeDatagram:
{
- _connection->prepareRequest(&_os);
+ _os.writeBlob(requestHdr, sizeof(requestHdr));
break;
}
diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp
index 982edf7b866..fef41fa0b86 100644
--- a/cpp/src/Ice/OutgoingAsync.cpp
+++ b/cpp/src/Ice/OutgoingAsync.cpp
@@ -19,6 +19,7 @@
#include <Ice/ProxyFactory.h>
#include <Ice/RouterInfo.h>
#include <Ice/Outgoing.h> // For LocalExceptionWrapper.
+#include <Ice/Protocol.h>
using namespace std;
using namespace Ice;
@@ -205,8 +206,6 @@ IceInternal::OutgoingAsync::__finished(const LocalException& exc)
if(__os) // Don't retry if cleanup() was already called.
{
- bool doRetry = false;
-
//
// A CloseConnectionException indicates graceful server
// shutdown, and is therefore always repeatable without
@@ -224,29 +223,14 @@ IceInternal::OutgoingAsync::__finished(const LocalException& exc)
{
try
{
- ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory();
- if(proxyFactory)
- {
- proxyFactory->checkRetryAfterException(exc, _reference, _cnt);
- }
- else
- {
- exc.ice_throw(); // The communicator is already destroyed, so we cannot retry.
- }
-
- doRetry = true;
+ _proxy->__handleException(exc, _cnt);
+ __send();
+ return;
}
catch(const LocalException&)
{
}
}
-
- if(doRetry)
- {
- _connection = 0;
- __send();
- return;
- }
}
try
@@ -290,48 +274,30 @@ IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operat
//
prx->__checkTwowayOnly(operation);
- ReferencePtr ref = prx->__reference();
-
- //
- // Optimization: Don't update the connection if it is not
- // necessary.
- //
- if(!_connection || !_reference || _reference != ref)
- {
- _connection = ref->getConnection(_compress);
- }
-
- _reference = ref;
+ _proxy = prx;
_cnt = 0;
_mode = mode;
+
+ ReferencePtr ref = _proxy->__reference();
assert(!__is);
- __is = new BasicStream(_reference->getInstance().get());
+ __is = new BasicStream(ref->getInstance().get());
assert(!__os);
- __os = new BasicStream(_reference->getInstance().get());
+ __os = new BasicStream(ref->getInstance().get());
- //
- // If we are using a router, then add the proxy to the router info object.
- //
- RoutableReferencePtr rr = RoutableReferencePtr::dynamicCast(_reference);
- if(rr && rr->getRouterInfo())
- {
- rr->getRouterInfo()->addProxy(prx);
- }
-
- _connection->prepareRequest(__os);
+ __os->writeBlob(requestHdr, sizeof(requestHdr));
- _reference->getIdentity().__write(__os);
+ ref->getIdentity().__write(__os);
//
// For compatibility with the old FacetPath.
//
- if(_reference->getFacet().empty())
+ if(ref->getFacet().empty())
{
__os->write(static_cast<string*>(0), static_cast<string*>(0));
}
else
{
- string facet = _reference->getFacet();
+ string facet = ref->getFacet();
__os->write(&facet, &facet + 1);
}
@@ -365,14 +331,11 @@ IceInternal::OutgoingAsync::__send()
{
while(true)
{
- if(!_connection)
- {
- _connection = _reference->getConnection(_compress);
- }
-
+ bool compress;
+ Ice::ConnectionIPtr connection = _proxy->__getDelegate()->__getConnection(compress);
try
{
- _connection->sendAsyncRequest(__os, this, _compress);
+ connection->sendAsyncRequest(__os, this, compress);
//
// Don't do anything after sendAsyncRequest() returned
@@ -385,25 +348,12 @@ IceInternal::OutgoingAsync::__send()
}
catch(const LocalExceptionWrapper& ex)
{
- if(!ex.retry())
- {
- ex.get()->ice_throw();
- }
+ _proxy->__handleExceptionWrapper(ex);
}
catch(const LocalException& ex)
{
- ProxyFactoryPtr proxyFactory = _reference->getInstance()->proxyFactory();
- if(proxyFactory)
- {
- proxyFactory->checkRetryAfterException(ex, _reference, _cnt);
- }
- else
- {
- ex.ice_throw(); // The communicator is already destroyed, so we cannot retry.
- }
+ _proxy->__handleException(ex, _cnt);
}
-
- _connection = 0;
}
}
catch(const LocalException& ex)
@@ -417,9 +367,10 @@ IceInternal::OutgoingAsync::warning(const Exception& ex) const
{
if(__os) // Don't print anything if cleanup() was already called.
{
- if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
+ ReferencePtr ref = _proxy->__reference();
+ if(ref->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
{
- Warning out(_reference->getInstance()->logger());
+ Warning out(ref->getInstance()->logger());
out << "Ice::Exception raised by AMI callback:\n" << ex;
}
}
@@ -430,9 +381,10 @@ IceInternal::OutgoingAsync::warning(const std::exception& ex) const
{
if(__os) // Don't print anything if cleanup() was already called.
{
- if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
+ ReferencePtr ref = _proxy->__reference();
+ if(ref->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
{
- Warning out(_reference->getInstance()->logger());
+ Warning out(ref->getInstance()->logger());
out << "std::exception raised by AMI callback:\n" << ex.what();
}
}
@@ -443,9 +395,10 @@ IceInternal::OutgoingAsync::warning() const
{
if(__os) // Don't print anything if cleanup() was already called.
{
- if(_reference->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
+ ReferencePtr ref = _proxy->__reference();
+ if(ref->getInstance()->properties()->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
{
- Warning out(_reference->getInstance()->logger());
+ Warning out(ref->getInstance()->logger());
out << "unknown exception raised by AMI callback";
}
}
diff --git a/cpp/src/Ice/Protocol.h b/cpp/src/Ice/Protocol.h
index 7e4fd49954e..99499fb56f3 100644
--- a/cpp/src/Ice/Protocol.h
+++ b/cpp/src/Ice/Protocol.h
@@ -32,7 +32,7 @@ const ::Ice::Int headerSize = 14;
//
// The magic number at the front of each message
//
-const ::Ice::Byte magic[] = { 0x49, 0x63, 0x65, 0x50 }; // 'I', 'c', 'e', 'P'
+extern const ::Ice::Byte magic[4];
//
// The current Ice protocol and encoding version
@@ -51,6 +51,13 @@ const ::Ice::Byte replyMsg = 2;
const ::Ice::Byte validateConnectionMsg = 3;
const ::Ice::Byte closeConnectionMsg = 4;
+//
+// The request header, batch request header and reply header.
+//
+extern const ::Ice::Byte requestHdr[headerSize + sizeof(Ice::Int)];
+extern const ::Ice::Byte requestBatchHdr[headerSize + sizeof(Ice::Int)];
+extern const ::Ice::Byte replyHdr[headerSize];
+
}
#endif
diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp
index d450f00bc95..253f5909657 100644
--- a/cpp/src/Ice/Proxy.cpp
+++ b/cpp/src/Ice/Proxy.cpp
@@ -735,7 +735,8 @@ IceProxy::Ice::Object::ice_connection()
try
{
Handle< ::IceDelegate::Ice::Object> __del = __getDelegate();
- return __del->ice_connection();
+ bool compress;
+ return __del->__getConnection(compress);
}
catch(const LocalException& __ex)
{
@@ -777,6 +778,12 @@ IceProxy::Ice::Object::__copyFrom(const ObjectPrx& from)
if(_reference->getCacheConnection())
{
+ //
+ // The _delegate attribute is only used if "cache connection"
+ // is enabled. If it's not enabled, we don't keep track of the
+ // delegate -- a new delegate is created for each invocations.
+ //
+
if(delegateD)
{
Handle< ::IceDelegateD::Ice::Object> delegate = __createDelegateD();
@@ -931,6 +938,11 @@ IceProxy::Ice::Object::__getDelegate()
if(_reference->getCacheConnection())
{
+ //
+ // The _delegate attribute is only used if "cache connection"
+ // is enabled. If it's not enabled, we don't keep track of the
+ // delegate -- a new delegate is created for each invocations.
+ //
_delegate = delegate;
}
@@ -1133,9 +1145,10 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation,
return ok;
}
-ConnectionPtr
-IceDelegateM::Ice::Object::ice_connection()
+ConnectionIPtr
+IceDelegateM::Ice::Object::__getConnection(bool& compress) const
{
+ compress = __compress;
return __connection;
}
@@ -1238,8 +1251,8 @@ IceDelegateD::Ice::Object::ice_invoke(const string&,
return false;
}
-ConnectionPtr
-IceDelegateD::Ice::Object::ice_connection()
+ConnectionIPtr
+IceDelegateD::Ice::Object::__getConnection(bool&) const
{
throw CollocationOptimizationException(__FILE__, __LINE__);
return 0;
diff --git a/cpp/src/IceGrid/Database.cpp b/cpp/src/IceGrid/Database.cpp
index a95e1c4773c..e7e20fd3a43 100644
--- a/cpp/src/IceGrid/Database.cpp
+++ b/cpp/src/IceGrid/Database.cpp
@@ -742,8 +742,8 @@ Database::getAdapters(const string& id, bool allRegistered, int& endpointCount)
Ice::Identity identity;
identity.category = "IceGridAdapter";
identity.name = id;
- AdapterPrx adpt = AdapterPrx::uncheckedCast(_internalAdapter->createDirectProxy(identity));
- adpts.push_back(make_pair(id, adpt));
+ Ice::ObjectPrx adpt = _internalAdapter->createDirectProxy(identity)->ice_collocationOptimization(false);
+ adpts.push_back(make_pair(id, AdapterPrx::uncheckedCast(adpt)));
endpointCount = 1;
return adpts;
}
diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp
index 500ef3fe99b..47d9321ca67 100644
--- a/cpp/src/IceGrid/LocatorI.cpp
+++ b/cpp/src/IceGrid/LocatorI.cpp
@@ -398,6 +398,9 @@ LocatorI::getDirectProxyException(const AdapterPrx& adapter, const string& id, c
}
catch(const Ice::Exception&)
{
+ //
+ // TODO: Add a warning!!!
+ //
}
PendingRequests requests;
diff --git a/cpp/test/Ice/binding/AllTests.cpp b/cpp/test/Ice/binding/AllTests.cpp
index 6bbc0d92b92..97b90a69267 100644
--- a/cpp/test/Ice/binding/AllTests.cpp
+++ b/cpp/test/Ice/binding/AllTests.cpp
@@ -103,7 +103,7 @@ allTests(const Ice::CommunicatorPtr& communicator)
TestIntfPrx test3 = TestIntfPrx::uncheckedCast(test1);
test(test3->ice_connection() == test1->ice_connection());
test(test3->ice_connection() == test2->ice_connection());
-
+
try
{
test3->ice_ping();
@@ -122,6 +122,10 @@ allTests(const Ice::CommunicatorPtr& communicator)
adapters.push_back(com->createObjectAdapter("Adapter12", "default"));
adapters.push_back(com->createObjectAdapter("Adapter13", "default"));
+ //
+ // Ensure that when a connection is opened it's reused for new
+ // proxies and that all endpoints are eventually tried.
+ //
set<string> names;
names.insert("Adapter11");
names.insert("Adapter12");
@@ -143,8 +147,34 @@ allTests(const Ice::CommunicatorPtr& communicator)
test1->ice_connection()->close(false);
}
- com->deactivateObjectAdapter(adapters[0]);
+ //
+ // Ensure that the proxy correctly caches the connection (we
+ // always send the request over the same connection.)
+ //
+ {
+ for(vector<RemoteObjectAdapterPrx>::const_iterator p = adapters.begin(); p != adapters.end(); ++p)
+ {
+ (*p)->getTestIntf()->ice_ping();
+ }
+
+ TestIntfPrx test = createTestIntfPrx(adapters);
+ string name = test->getAdapterName();
+ const int nRetry = 10;
+ int i;
+ for(i = 0; i < nRetry && test->getAdapterName() == name; i++);
+ test(i == nRetry);
+
+ for(vector<RemoteObjectAdapterPrx>::const_iterator p = adapters.begin(); p != adapters.end(); ++p)
+ {
+ (*p)->getTestIntf()->ice_connection()->close(false);
+ }
+ }
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapters.
+ //
+ com->deactivateObjectAdapter(adapters[0]);
names.insert("Adapter12");
names.insert("Adapter13");
while(!names.empty())
@@ -164,8 +194,11 @@ allTests(const Ice::CommunicatorPtr& communicator)
test1->ice_connection()->close(false);
}
- com->deactivateObjectAdapter(adapters[2]);
-
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapter.
+ //
+ com->deactivateObjectAdapter(adapters[2]);
TestIntfPrx test = createTestIntfPrx(adapters);
test(test->getAdapterName() == "Adapter12");
@@ -173,6 +206,97 @@ allTests(const Ice::CommunicatorPtr& communicator)
}
cout << "ok" << endl;
+ cout << "testing binding with multiple endpoints and AMI... " << flush;
+ {
+ vector<RemoteObjectAdapterPrx> adapters;
+ adapters.push_back(com->createObjectAdapter("AdapterAMI11", "default"));
+ adapters.push_back(com->createObjectAdapter("AdapterAMI12", "default"));
+ adapters.push_back(com->createObjectAdapter("AdapterAMI13", "default"));
+
+ //
+ // Ensure that when a connection is opened it's reused for new
+ // proxies and that all endpoints are eventually tried.
+ //
+ set<string> names;
+ names.insert("AdapterAMI11");
+ names.insert("AdapterAMI12");
+ names.insert("AdapterAMI13");
+ while(!names.empty())
+ {
+ vector<RemoteObjectAdapterPrx> adpts = adapters;
+
+ TestIntfPrx test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts.begin(), adpts.end());
+ TestIntfPrx test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts.begin(), adpts.end());
+ TestIntfPrx test3 = createTestIntfPrx(adpts);
+
+ test(test1->ice_connection() == test2->ice_connection());
+ test(test2->ice_connection() == test3->ice_connection());
+
+ names.erase(getAdapterNameWithAMI(test1));
+ test1->ice_connection()->close(false);
+ }
+
+ //
+ // Ensure that the proxy correctly caches the connection (we
+ // always send the request over the same connection.)
+ //
+ {
+ for(vector<RemoteObjectAdapterPrx>::const_iterator p = adapters.begin(); p != adapters.end(); ++p)
+ {
+ (*p)->getTestIntf()->ice_ping();
+ }
+
+ TestIntfPrx test = createTestIntfPrx(adapters);
+ string name = getAdapterNameWithAMI(test);
+ const int nRetry = 10;
+ int i;
+ for(i = 0; i < nRetry && getAdapterNameWithAMI(test) == name; i++);
+ test(i == nRetry);
+
+ for(vector<RemoteObjectAdapterPrx>::const_iterator p = adapters.begin(); p != adapters.end(); ++p)
+ {
+ (*p)->getTestIntf()->ice_connection()->close(false);
+ }
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapters.
+ //
+ com->deactivateObjectAdapter(adapters[0]);
+ names.insert("AdapterAMI12");
+ names.insert("AdapterAMI13");
+ while(!names.empty())
+ {
+ vector<RemoteObjectAdapterPrx> adpts = adapters;
+
+ TestIntfPrx test1 = createTestIntfPrx(adpts);
+ random_shuffle(adpts.begin(), adpts.end());
+ TestIntfPrx test2 = createTestIntfPrx(adpts);
+ random_shuffle(adpts.begin(), adpts.end());
+ TestIntfPrx test3 = createTestIntfPrx(adpts);
+
+ test(test1->ice_connection() == test2->ice_connection());
+ test(test2->ice_connection() == test3->ice_connection());
+
+ names.erase(test1->getAdapterName());
+ test1->ice_connection()->close(false);
+ }
+
+ //
+ // Deactivate an adapter and ensure that we can still
+ // establish the connection to the remaining adapter.
+ //
+ com->deactivateObjectAdapter(adapters[2]);
+ TestIntfPrx test = createTestIntfPrx(adapters);
+ test(test->getAdapterName() == "AdapterAMI12");
+
+ deactivate(com, adapters);
+ }
+ cout << "ok" << endl;
+
cout << "testing random endpoint selection... " << flush;
{
vector<RemoteObjectAdapterPrx> adapters;