summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/LocatorInfo.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2009-01-15 16:02:54 +0100
committerBenoit Foucher <benoit@zeroc.com>2009-01-15 16:02:54 +0100
commita10f33af6ee6298b4a7412a3819cc4818f086fa4 (patch)
tree7dc924b0692491a6419b81ae419b559ccef467cf /cpp/src/Ice/LocatorInfo.cpp
parentbug 3266 - fix IceSSL/C++ for custom contexts (diff)
downloadice-a10f33af6ee6298b4a7412a3819cc4818f086fa4.tar.bz2
ice-a10f33af6ee6298b4a7412a3819cc4818f086fa4.tar.xz
ice-a10f33af6ee6298b4a7412a3819cc4818f086fa4.zip
- Fixed errorDetection test
- Fixed bug 3504, added locator request queue.
Diffstat (limited to 'cpp/src/Ice/LocatorInfo.cpp')
-rw-r--r--cpp/src/Ice/LocatorInfo.cpp446
1 files changed, 328 insertions, 118 deletions
diff --git a/cpp/src/Ice/LocatorInfo.cpp b/cpp/src/Ice/LocatorInfo.cpp
index 12d87e3dcab..0113f80a868 100644
--- a/cpp/src/Ice/LocatorInfo.cpp
+++ b/cpp/src/Ice/LocatorInfo.cpp
@@ -26,6 +26,174 @@ IceUtil::Shared* IceInternal::upCast(LocatorManager* p) { return p; }
IceUtil::Shared* IceInternal::upCast(LocatorInfo* p) { return p; }
IceUtil::Shared* IceInternal::upCast(LocatorTable* p) { return p; }
+namespace
+{
+
+class ObjectRequest : public LocatorInfo::Request, public Ice::AMI_Locator_findObjectById
+{
+public:
+
+ ObjectRequest(const LocatorInfoPtr& locatorInfo, const Ice::Identity& id) : Request(locatorInfo), _id(id)
+ {
+ }
+
+ virtual void ice_response(const Ice::ObjectPrx& proxy)
+ {
+ _locatorInfo->removeObjectRequest(_id);
+ response(proxy);
+ }
+
+ virtual void ice_exception(const Ice::Exception& ex)
+ {
+ _locatorInfo->removeObjectRequest(_id);
+ exception(ex);
+ }
+
+ virtual void send()
+ {
+ _locatorInfo->getLocator()->findObjectById_async(this, _id);
+ }
+
+private:
+
+ const Ice::Identity _id;
+};
+
+class AdapterRequest : public LocatorInfo::Request, public Ice::AMI_Locator_findAdapterById
+{
+public:
+
+ AdapterRequest(const LocatorInfoPtr& locatorInfo, const string& id) : Request(locatorInfo), _id(id)
+ {
+ }
+
+ virtual void ice_response(const Ice::ObjectPrx& proxy)
+ {
+ _locatorInfo->removeAdapterRequest(_id);
+ response(proxy);
+ }
+
+ virtual void ice_exception(const Ice::Exception& ex)
+ {
+ _locatorInfo->removeAdapterRequest(_id);
+ exception(ex);
+ }
+
+ virtual void send()
+ {
+ _locatorInfo->getLocator()->findAdapterById_async(this, _id);
+ }
+
+private:
+
+ const string _id;
+};
+
+class ObjectRequestCallback : public LocatorInfo::RequestCallback
+{
+public:
+
+ virtual void
+ response(const LocatorInfoPtr& locatorInfo, const Ice::ObjectPrx& object)
+ {
+ locatorInfo->getWellKnownObjectEndpoints(_reference, object, _ttl, false, _callback);
+ }
+
+ virtual void
+ exception(const LocatorInfoPtr& locatorInfo, const Ice::Exception& ex)
+ {
+ if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex))
+ {
+ try
+ {
+ bool cached;
+ vector<EndpointIPtr> endpoints = locatorInfo->getEndpoints(_reference, _ttl, cached);
+ _callback->setEndpoints(endpoints, cached);
+ }
+ catch(const Ice::LocalException& e)
+ {
+ _callback->setException(e);
+ }
+ }
+ else
+ {
+ locatorInfo->getEndpointsException(_reference, ex, _callback);
+ }
+ }
+
+ ObjectRequestCallback(const ReferencePtr& ref, int ttl, const LocatorInfo::GetEndpointsCallbackPtr& cb) :
+ _reference(ref), _ttl(ttl), _callback(cb)
+ {
+ }
+
+private:
+
+ const ReferencePtr _reference;
+ int _ttl;
+ const LocatorInfo::GetEndpointsCallbackPtr _callback;
+};
+
+class AdapterRequestCallback : public LocatorInfo::RequestCallback
+{
+public:
+
+ virtual void
+ response(const LocatorInfoPtr& locatorInfo, const Ice::ObjectPrx& object)
+ {
+ vector<EndpointIPtr> endpoints;
+ if(object)
+ {
+ endpoints = object->__reference()->getEndpoints();
+ if(!endpoints.empty())
+ {
+ locatorInfo->getTable()->addAdapterEndpoints(_reference->getAdapterId(), endpoints);
+ }
+ }
+
+ if(_reference->getInstance()->traceLevels()->location >= 1)
+ {
+ locatorInfo->getEndpointsTrace(_reference, endpoints, false);
+ }
+
+ _callback->setEndpoints(endpoints, false);
+ }
+
+ virtual void
+ exception(const LocatorInfoPtr& locatorInfo, const Ice::Exception& ex)
+ {
+ if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex))
+ {
+ try
+ {
+ bool cached;
+ vector<EndpointIPtr> endpoints = locatorInfo->getEndpoints(_reference, _ttl, cached);
+ _callback->setEndpoints(endpoints, cached);
+ }
+ catch(const Ice::LocalException& e)
+ {
+ _callback->setException(e);
+ }
+ }
+ else
+ {
+ locatorInfo->getEndpointsException(_reference, ex, _callback);
+ }
+ }
+
+ AdapterRequestCallback(const ReferencePtr& ref, int ttl, const LocatorInfo::GetEndpointsCallbackPtr& callback) :
+ _reference(ref), _ttl(ttl), _callback(callback)
+ {
+ }
+
+private:
+
+ const ReferencePtr _reference;
+ const int _ttl;
+ const LocatorInfo::GetEndpointsCallbackPtr _callback;
+};
+
+}
+
IceInternal::LocatorManager::LocatorManager() :
_tableHint(_table.end())
{
@@ -238,6 +406,111 @@ IceInternal::LocatorTable::checkTTL(const IceUtil::Time& time, int ttl) const
}
}
+void
+IceInternal::LocatorInfo::Request::addCallback(const RequestCallbackPtr& callback)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
+ if(_response)
+ {
+ callback->response(_locatorInfo, _proxy);
+ return;
+ }
+ else if(_exception.get())
+ {
+ callback->exception(_locatorInfo, *_exception.get());
+ return;
+ }
+
+ _callbacks.push_back(callback);
+
+ if(!_sent)
+ {
+ _sent = true;
+ try
+ {
+ send();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ sync.release();
+ exception(ex);
+ sync.acquire();
+ }
+ }
+}
+
+Ice::ObjectPrx
+IceInternal::LocatorInfo::Request::getProxy()
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
+ if(_response)
+ {
+ return _proxy;
+ }
+ else if(_exception.get())
+ {
+ _exception->ice_throw();
+ return 0; // Keep the compiler happy.
+ }
+
+ if(!_sent)
+ {
+ _sent = true;
+ try
+ {
+ send();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ sync.release();
+ exception(ex);
+ sync.acquire();
+ }
+ }
+
+ while(!_response && !_exception.get())
+ {
+ _monitor.wait();
+ }
+
+ if(_exception.get())
+ {
+ _exception->ice_throw();
+ }
+ assert(_response);
+ return _proxy;
+}
+
+IceInternal::LocatorInfo::Request::Request(const LocatorInfoPtr& locatorInfo) :
+ _locatorInfo(locatorInfo), _sent(false), _response(false)
+{
+}
+
+void
+IceInternal::LocatorInfo::Request::response(const Ice::ObjectPrx& proxy)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
+ _response = true;
+ _proxy = proxy;
+ for(vector<RequestCallbackPtr>::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p)
+ {
+ (*p)->response(_locatorInfo, proxy);
+ }
+ _monitor.notifyAll();
+}
+
+void
+IceInternal::LocatorInfo::Request::exception(const Ice::Exception& ex)
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
+ _exception.reset(ex.ice_clone());
+ for(vector<RequestCallbackPtr>::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p)
+ {
+ (*p)->exception(_locatorInfo, ex);
+ }
+ _monitor.notifyAll();
+}
+
IceInternal::LocatorInfo::LocatorInfo(const LocatorPrx& locator, const LocatorTablePtr& table) :
_locator(locator),
_table(table)
@@ -323,7 +596,8 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, bool& c
out << "adapter = " << ref->getAdapterId();
}
- object = _locator->findAdapterById(ref->getAdapterId());
+ RequestPtr request = getAdapterRequest(ref->getAdapterId());
+ object = request->getProxy();
if(object)
{
endpoints = object->__reference()->getEndpoints();
@@ -345,7 +619,8 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, bool& c
}
objectCached = false;
- object = _locator->findObjectById(ref->getIdentity());
+ RequestPtr request = getObjectRequest(ref->getIdentity());
+ object = request->getProxy();
}
bool endpointsCached = true;
@@ -384,73 +659,6 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, bool& c
return endpoints;
}
-namespace IceInternal
-{
-
-class findAdapterByIdCallback : public AMI_Locator_findAdapterById
-{
-public:
-
- virtual void
- ice_response(const Ice::ObjectPrx& object)
- {
- vector<EndpointIPtr> endpoints;
- if(object)
- {
- endpoints = object->__reference()->getEndpoints();
- if(!endpoints.empty())
- {
- _table->addAdapterEndpoints(_reference->getAdapterId(), endpoints);
- }
- }
-
- if(_reference->getInstance()->traceLevels()->location >= 1)
- {
- _locatorInfo->getEndpointsTrace(_reference, endpoints, false);
- }
-
- _callback->setEndpoints(endpoints, false);
- }
-
- virtual void
- ice_exception(const Ice::Exception& ex)
- {
- if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex))
- {
- try
- {
- bool cached;
- vector<EndpointIPtr> endpoints = _locatorInfo->getEndpoints(_reference, _ttl, cached);
- _callback->setEndpoints(endpoints, cached);
- }
- catch(const Ice::LocalException& e)
- {
- _callback->setException(e);
- }
- }
- else
- {
- _locatorInfo->getEndpointsException(_reference, ex, _callback);
- }
- }
-
- findAdapterByIdCallback(const LocatorInfoPtr& locatorInfo, const LocatorTablePtr& table,
- const ReferencePtr& reference, int ttl, const LocatorInfo::GetEndpointsCallbackPtr& callback) :
- _locatorInfo(locatorInfo), _table(table), _reference(reference), _ttl(ttl), _callback(callback)
- {
- }
-
-private:
-
- const LocatorInfoPtr _locatorInfo;
- const LocatorTablePtr _table;
- const ReferencePtr _reference;
- const int _ttl;
- const LocatorInfo::GetEndpointsCallbackPtr _callback;
-};
-
-};
-
void
IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, const GetEndpointsCallbackPtr& callback)
{
@@ -474,8 +682,8 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, const G
// Search the adapter in the location service if we didn't
// find it in the cache.
//
- _locator->findAdapterById_async(
- new IceInternal::findAdapterByIdCallback(this, _table, ref, ttl, callback), adapterId);
+ RequestPtr request = getAdapterRequest(adapterId);
+ request->addCallback(new AdapterRequestCallback(ref, ttl, callback));
return;
}
else
@@ -499,53 +707,8 @@ IceInternal::LocatorInfo::getEndpoints(const ReferencePtr& ref, int ttl, const G
out << "searching for object by id" << "\nobject = " << instance->identityToString(ref->getIdentity());
}
- class Callback : public Ice::AMI_Locator_findObjectById
- {
- public:
-
- virtual void
- ice_response(const Ice::ObjectPrx& object)
- {
- _locatorInfo->getWellKnownObjectEndpoints(_reference, object, _ttl, false, _callback);
- }
-
- virtual void
- ice_exception(const Ice::Exception& ex)
- {
- if(dynamic_cast<const Ice::CollocationOptimizationException*>(&ex))
- {
- try
- {
- bool cached;
- vector<EndpointIPtr> endpoints = _locatorInfo->getEndpoints(_reference, _ttl, cached);
- _callback->setEndpoints(endpoints, cached);
- }
- catch(const Ice::LocalException& e)
- {
- _callback->setException(e);
- }
- }
- else
- {
- _locatorInfo->getEndpointsException(_reference, ex, _callback);
- }
- }
-
- Callback(const LocatorInfoPtr& locatorInfo, const ReferencePtr& reference, int ttl,
- const GetEndpointsCallbackPtr& callback) :
- _locatorInfo(locatorInfo), _reference(reference), _ttl(ttl), _callback(callback)
- {
- }
-
- private:
-
- const LocatorInfoPtr _locatorInfo;
- const ReferencePtr _reference;
- int _ttl;
- const GetEndpointsCallbackPtr _callback;
- };
-
- _locator->findObjectById_async(new Callback(this, ref, ttl, callback), identity);
+ RequestPtr request = getObjectRequest(identity);
+ request->addCallback(new ObjectRequestCallback(ref, ttl, callback));
return;
}
else
@@ -828,3 +991,50 @@ IceInternal::LocatorInfo::getEndpointsTrace(const ReferencePtr& ref, const vecto
}
}
}
+
+IceInternal::LocatorInfo::RequestPtr
+IceInternal::LocatorInfo::getAdapterRequest(const string& id)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ map<string, RequestPtr>::const_iterator p = _adapterRequests.find(id);
+ if(p != _adapterRequests.end())
+ {
+ return p->second;
+ }
+
+ RequestPtr request = new AdapterRequest(this, id);
+ _adapterRequests.insert(make_pair(id, request));
+ return request;
+}
+
+void
+IceInternal::LocatorInfo::removeAdapterRequest(const string& id)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ assert(_adapterRequests.find(id) != _adapterRequests.end());
+ _adapterRequests.erase(id);
+}
+
+IceInternal::LocatorInfo::RequestPtr
+IceInternal::LocatorInfo::getObjectRequest(const Ice::Identity& id)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ map<Ice::Identity, RequestPtr>::const_iterator p = _objectRequests.find(id);
+ if(p != _objectRequests.end())
+ {
+ return p->second;
+ }
+
+ RequestPtr request = new ObjectRequest(this, id);
+ _objectRequests.insert(make_pair(id, request));
+ return request;
+}
+
+void
+IceInternal::LocatorInfo::removeObjectRequest(const Ice::Identity& id)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ assert(_objectRequests.find(id) != _objectRequests.end());
+ _objectRequests.erase(id);
+}
+