summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2007-11-19 17:49:00 -0500
committerBernard Normier <bernard@zeroc.com>2007-11-19 17:49:00 -0500
commit99bbf0fbbb8ee4fe2b5807c68c4a7b054e29f3db (patch)
tree1629e081bdbf6cfd412b36f19b1eb5f1f0face2b /cpp/src
parentFixed bug #2562 (diff)
parentMerge branch 'master' of ssh://cvs.zeroc.com/home/git/ice (diff)
downloadice-99bbf0fbbb8ee4fe2b5807c68c4a7b054e29f3db.tar.bz2
ice-99bbf0fbbb8ee4fe2b5807c68c4a7b054e29f3db.tar.xz
ice-99bbf0fbbb8ee4fe2b5807c68c4a7b054e29f3db.zip
Merge branch 'master' of cvs:/home/git/ice
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Freeze/.gitignore1
-rw-r--r--cpp/src/Freeze/ConnectionI.cpp2
-rw-r--r--cpp/src/Freeze/EvictorIteratorI.cpp8
-rw-r--r--cpp/src/Freeze/EvictorIteratorI.h2
-rw-r--r--cpp/src/Freeze/IndexI.cpp4
-rw-r--r--cpp/src/Freeze/MapI.cpp8
-rw-r--r--cpp/src/Freeze/ObjectStore.cpp10
-rw-r--r--cpp/src/Freeze/SharedDb.cpp8
-rw-r--r--cpp/src/Freeze/TransactionI.cpp4
-rw-r--r--cpp/src/Freeze/TransactionalEvictorContext.cpp57
-rw-r--r--cpp/src/Freeze/TransactionalEvictorContext.h2
-rw-r--r--cpp/src/Freeze/TransactionalEvictorI.cpp35
-rw-r--r--cpp/src/IceGrid/LocatorI.cpp229
-rw-r--r--cpp/src/IceGrid/LocatorI.h34
-rw-r--r--cpp/src/IceGrid/Scanner.l1
-rw-r--r--cpp/src/IceStorm/Scanner.l1
16 files changed, 277 insertions, 129 deletions
diff --git a/cpp/src/Freeze/.gitignore b/cpp/src/Freeze/.gitignore
index 6010c0e2930..b09bdea2d1e 100644
--- a/cpp/src/Freeze/.gitignore
+++ b/cpp/src/Freeze/.gitignore
@@ -26,3 +26,4 @@ TransactionalEvictor.h
Transaction.h
PingObject.h
Catalog.cpp
+CatalogIndexList.cpp
diff --git a/cpp/src/Freeze/ConnectionI.cpp b/cpp/src/Freeze/ConnectionI.cpp
index 824fc167c9c..10af58cdbbe 100644
--- a/cpp/src/Freeze/ConnectionI.cpp
+++ b/cpp/src/Freeze/ConnectionI.cpp
@@ -56,7 +56,7 @@ Freeze::ConnectionI::removeMapIndex(const string& mapName, const string& indexNa
}
catch(const DbDeadlockException& dx)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), _transaction);
}
catch(const DbException& dx)
{
diff --git a/cpp/src/Freeze/EvictorIteratorI.cpp b/cpp/src/Freeze/EvictorIteratorI.cpp
index 401b17750fd..0ff5f418569 100644
--- a/cpp/src/Freeze/EvictorIteratorI.cpp
+++ b/cpp/src/Freeze/EvictorIteratorI.cpp
@@ -23,7 +23,7 @@ Freeze::EvictorIteratorI::EvictorIteratorI(ObjectStoreBase* store, const Transac
_key(1024),
_more(store != 0),
_initialized(false),
- _tx(tx == 0 ? 0 : tx->dbTxn())
+ _tx(tx)
{
_batchIterator = _batch.end();
}
@@ -74,6 +74,8 @@ Freeze::EvictorIteratorI::nextBatch()
CommunicatorPtr communicator = _store->communicator();
+ DbTxn* txn = _tx == 0 ? 0: _tx->dbTxn();
+
try
{
for(;;)
@@ -108,7 +110,7 @@ Freeze::EvictorIteratorI::nextBatch()
dbKey.set_size(static_cast<u_int32_t>(firstKey.size()));
}
- _store->db()->cursor(_tx, &dbc, 0);
+ _store->db()->cursor(txn, &dbc, 0);
bool done = false;
do
@@ -217,7 +219,7 @@ Freeze::EvictorIteratorI::nextBatch()
}
catch(const DbDeadlockException& dx)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), _tx);
}
catch(const DbException& dx)
{
diff --git a/cpp/src/Freeze/EvictorIteratorI.h b/cpp/src/Freeze/EvictorIteratorI.h
index 41fed5db623..4e3e540d49c 100644
--- a/cpp/src/Freeze/EvictorIteratorI.h
+++ b/cpp/src/Freeze/EvictorIteratorI.h
@@ -45,7 +45,7 @@ private:
std::vector<Ice::Identity> _batch;
bool _more;
bool _initialized;
- DbTxn* _tx;
+ TransactionIPtr _tx;
};
}
diff --git a/cpp/src/Freeze/IndexI.cpp b/cpp/src/Freeze/IndexI.cpp
index 29b89cffcdb..f8ca1b32c7d 100644
--- a/cpp/src/Freeze/IndexI.cpp
+++ b/cpp/src/Freeze/IndexI.cpp
@@ -174,7 +174,7 @@ Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const
}
catch(const DbDeadlockException& dx)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
catch(const DbException& dx)
{
@@ -294,7 +294,7 @@ Freeze::IndexI::untypedCount(const Key& bytes) const
}
catch(const DbDeadlockException& dx)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
catch(const DbException& dx)
{
diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp
index 25b0e088c94..669db800600 100644
--- a/cpp/src/Freeze/MapI.cpp
+++ b/cpp/src/Freeze/MapI.cpp
@@ -260,7 +260,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection,
}
else
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
}
}
catch(const DbException& dx)
@@ -1476,7 +1476,7 @@ Freeze::MapHelperI::destroy()
}
else
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
}
}
catch(const DbException& dx)
@@ -1798,7 +1798,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection)
int result = 0;
- DbTxn * txn = connection->dbTxn();
+ DbTxn* txn = connection->dbTxn();
try
{
@@ -1892,7 +1892,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection)
}
catch(const DbDeadlockException& dx)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction());
}
catch(const DbException& dx)
{
diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp
index 1d554c6bc2a..53f1c6140ac 100644
--- a/cpp/src/Freeze/ObjectStore.cpp
+++ b/cpp/src/Freeze/ObjectStore.cpp
@@ -255,7 +255,7 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt
if(tx != 0)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
// Else, try again
}
@@ -406,7 +406,7 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran
out << "Deadlock in Freeze::ObjectStoreBase::load while searching \""
<< _evictor->filename() + "/" + _dbName << "\"";
}
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
catch(const DbException& dx)
{
@@ -458,7 +458,7 @@ Freeze::ObjectStoreBase::update(const Identity& ident, const ObjectRecord& rec,
out << "Deadlock in Freeze::ObjectStoreBase::update while updating \""
<< _evictor->filename() + "/" + _dbName << "\"";
}
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
catch(const DbException& dx)
{
@@ -511,7 +511,7 @@ Freeze::ObjectStoreBase::insert(const Identity& ident, const ObjectRecord& rec,
}
if(tx != 0)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
//
// Otherwise, try again
@@ -559,7 +559,7 @@ Freeze::ObjectStoreBase::remove(const Identity& ident, const TransactionIPtr& tr
}
if(tx != 0)
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction);
}
//
// Otherwise, try again
diff --git a/cpp/src/Freeze/SharedDb.cpp b/cpp/src/Freeze/SharedDb.cpp
index 57018ec6efc..ab651e267c2 100644
--- a/cpp/src/Freeze/SharedDb.cpp
+++ b/cpp/src/Freeze/SharedDb.cpp
@@ -198,6 +198,7 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD
assert(0);
throw DatabaseException(__FILE__, __LINE__, "Catalog already opened");
}
+ newCatalog->_inMap = true;
mapKey.dbName = _catalogIndexListName;
@@ -212,6 +213,8 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD
assert(0);
throw DatabaseException(__FILE__, __LINE__, "CatalogIndexList already opened");
}
+ newCatalogIndexList->_inMap = true;
+
catalog = newCatalog.release();
catalogIndexList = newCatalogIndexList.release();
@@ -572,7 +575,7 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey,
}
else
{
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
}
}
catch(const DbException& dx)
@@ -615,7 +618,8 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey, const string& keyTypeId, const
_mapKey(mapKey),
_key(keyTypeId),
_value(valueTypeId),
- _refCount(0)
+ _refCount(0),
+ _inMap(false)
{
_trace = _mapKey.communicator->getProperties()->getPropertyAsInt("Freeze.Trace.Map");
diff --git a/cpp/src/Freeze/TransactionI.cpp b/cpp/src/Freeze/TransactionI.cpp
index 725953a4c6c..e8f1bdb2932 100644
--- a/cpp/src/Freeze/TransactionI.cpp
+++ b/cpp/src/Freeze/TransactionI.cpp
@@ -137,10 +137,12 @@ Freeze::TransactionI::rollbackInternal(bool warning)
out << "failed to rollback transaction " << hex << txnId << dec << ": " << dx.what();
}
+ DeadlockException deadlockException(__FILE__, __LINE__, dx.what(), this);
+
postCompletion(false, true);
// After postCompletion is called the transaction may be
// dead. Beware!
- throw DeadlockException(__FILE__, __LINE__, dx.what());
+ throw deadlockException;
}
catch(const ::DbException& dx)
{
diff --git a/cpp/src/Freeze/TransactionalEvictorContext.cpp b/cpp/src/Freeze/TransactionalEvictorContext.cpp
index 369c6fd1763..2c68a4eae2e 100644
--- a/cpp/src/Freeze/TransactionalEvictorContext.cpp
+++ b/cpp/src/Freeze/TransactionalEvictorContext.cpp
@@ -19,6 +19,49 @@ using namespace std;
using namespace Freeze;
using namespace Ice;
+//
+// TransactionalEvictorDeadlockException
+//
+
+Freeze::TransactionalEvictorDeadlockException::TransactionalEvictorDeadlockException(const char* file, int line, const TransactionPtr& transaction) :
+ Ice::LocalException(file, line),
+ tx(transaction)
+{
+}
+
+Freeze::TransactionalEvictorDeadlockException::~TransactionalEvictorDeadlockException() throw()
+{
+}
+
+string
+Freeze::TransactionalEvictorDeadlockException::ice_name() const
+{
+ return "Freeze::TransactionalEvictorDeadlockException";
+}
+
+Ice::Exception*
+Freeze::TransactionalEvictorDeadlockException::ice_clone() const
+{
+ return new TransactionalEvictorDeadlockException(*this);
+}
+
+void
+Freeze::TransactionalEvictorDeadlockException::ice_throw() const
+{
+ throw *this;
+}
+
+void
+Freeze::TransactionalEvictorDeadlockException::ice_print(ostream& out) const
+{
+ Ice::Exception::ice_print(out);
+ out << ":\ntransactional evictor deadlock exception";
+}
+
+
+//
+// TransactionalEvictorContext
+//
Freeze::TransactionalEvictorContext::TransactionalEvictorContext(const SharedDbEnvPtr& dbEnv) :
_tx((new ConnectionI(dbEnv))->beginTransactionI()),
@@ -115,6 +158,11 @@ Freeze::TransactionalEvictorContext::checkDeadlockException()
{
_deadlockException->ice_throw();
}
+
+ if(_nestedCallDeadlockException.get() != 0)
+ {
+ _nestedCallDeadlockException->ice_throw();
+ }
}
bool
@@ -157,6 +205,15 @@ Freeze::TransactionalEvictorContext::exception(const std::exception& ex)
_deadlockException.reset(dynamic_cast<DeadlockException*>(dx->ice_clone()));
return false;
}
+
+ const TransactionalEvictorDeadlockException* edx =
+ dynamic_cast<const TransactionalEvictorDeadlockException*>(&ex);
+ if(edx != 0 && _owner == IceUtil::ThreadControl())
+ {
+ _nestedCallDeadlockException.reset(dynamic_cast<TransactionalEvictorDeadlockException*>(edx->ice_clone()));
+ return false;
+ }
+
return true;
}
diff --git a/cpp/src/Freeze/TransactionalEvictorContext.h b/cpp/src/Freeze/TransactionalEvictorContext.h
index 12b2a2e8765..9c5e16a8348 100644
--- a/cpp/src/Freeze/TransactionalEvictorContext.h
+++ b/cpp/src/Freeze/TransactionalEvictorContext.h
@@ -14,6 +14,7 @@
#include <Freeze/TransactionalEvictor.h>
#include <Freeze/EvictorStorage.h>
#include <Freeze/EvictorI.h>
+#include <Freeze/Initialize.h>
#include <IceUtil/IceUtil.h>
namespace Freeze
@@ -147,6 +148,7 @@ private:
bool _rollbackOnly;
std::auto_ptr<DeadlockException> _deadlockException;
+ std::auto_ptr<TransactionalEvictorDeadlockException> _nestedCallDeadlockException;
//
// Protected by this
diff --git a/cpp/src/Freeze/TransactionalEvictorI.cpp b/cpp/src/Freeze/TransactionalEvictorI.cpp
index 5ce3ed9dab6..8951cde8e0f 100644
--- a/cpp/src/Freeze/TransactionalEvictorI.cpp
+++ b/cpp/src/Freeze/TransactionalEvictorI.cpp
@@ -394,10 +394,11 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
{
servantHolder.init(ctx, current, store);
}
- catch(const DeadlockException&)
+ catch(const DeadlockException& dx)
{
+ assert(dx.tx == ctx->transaction());
ctx->deadlockException();
- throw;
+ throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx);
}
sample = servantHolder.servant();
}
@@ -496,6 +497,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
do
{
+ TransactionPtr tx;
+
try
{
if(ownCtx)
@@ -504,7 +507,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
}
CtxHolder ctxHolder(ownCtx, ctx, _dbEnv);
-
+ tx = ctx->transaction();
+
try
{
TransactionalEvictorContext::ServantHolder sh;
@@ -540,7 +544,7 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
if(dispatchStatus == DispatchAsync)
{
//
- // May throw DeadlockException
+ // May throw DeadlockException or TransactionalEvictorDeadlockException
//
ctx->checkDeadlockException();
@@ -565,9 +569,12 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
// servant holder destructor runs here and may throw (if !rolled back)
//
}
- catch(const DeadlockException&)
+ catch(const DeadlockException& dx)
{
- ctx->deadlockException();
+ if(dx.tx == tx)
+ {
+ ctx->deadlockException();
+ }
throw;
}
catch(...)
@@ -583,9 +590,20 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
// commit occurs here (when ownCtx)
//
}
- catch(const DeadlockException&)
+ catch(const DeadlockException& dx)
{
- if(ownCtx)
+ if(ownCtx && dx.tx == tx)
+ {
+ tryAgain = true;
+ }
+ else
+ {
+ throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx);
+ }
+ }
+ catch(const TransactionalEvictorDeadlockException& dx)
+ {
+ if(ownCtx && dx.tx == tx)
{
tryAgain = true;
}
@@ -594,7 +612,6 @@ Freeze::TransactionalEvictorI::dispatch(Request& request)
throw;
}
}
-
} while(tryAgain);
}
diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp
index 9158def55ff..b7361dce4a1 100644
--- a/cpp/src/IceGrid/LocatorI.cpp
+++ b/cpp/src/IceGrid/LocatorI.cpp
@@ -26,53 +26,67 @@ class AMI_Adapter_getDirectProxyI : public AMI_Adapter_getDirectProxy
{
public:
- AMI_Adapter_getDirectProxyI(const LocatorIPtr& locator, const string& id, const LocatorAdapterInfo& adapter) :
- _locator(locator), _id(id), _adapter(adapter)
+ AMI_Adapter_getDirectProxyI(const LocatorI::RequestPtr& request, const string& id) :
+ _request(request), _id(id)
{
}
virtual void ice_response(const ::Ice::ObjectPrx& obj)
{
assert(obj);
- _locator->getDirectProxyCallback(_adapter.proxy->ice_getIdentity(), obj);
+ _request->response(_id, obj);
}
- virtual void ice_exception(const ::Ice::Exception& ex)
- {
- _locator->getDirectProxyException(_adapter, _id, ex);
+ virtual void ice_exception(const ::Ice::Exception& e)
+ {
+ try
+ {
+ e.ice_throw();
+ }
+ catch(const AdapterNotActiveException& ex)
+ {
+ if(ex.activatable)
+ {
+ _request->activate(_id);
+ return;
+ }
+ }
+ catch(const Ice::Exception&)
+ {
+ }
+
+ _request->exception(_id, e);
}
private:
- const LocatorIPtr _locator;
+ const LocatorI::RequestPtr _request;
const string _id;
- const LocatorAdapterInfo _adapter;
};
class AMI_Adapter_activateI : public AMI_Adapter_activate
{
public:
- AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id, const LocatorAdapterInfo& adapter) :
- _locator(locator), _id(id), _adapter(adapter)
+ AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id) :
+ _locator(locator), _id(id)
{
}
virtual void ice_response(const ::Ice::ObjectPrx& obj)
{
- _locator->getDirectProxyCallback(_adapter.proxy->ice_getIdentity(), obj);
+ _locator->activateFinished(_id, obj);
}
virtual void ice_exception(const ::Ice::Exception& ex)
{
- _locator->getDirectProxyException(_adapter, _id, ex);
+ _locator->activateException(_id, ex);
}
private:
const LocatorIPtr _locator;
const string _id;
- const LocatorAdapterInfo _adapter;
};
//
@@ -205,29 +219,70 @@ LocatorI::Request::execute()
++_lastAdapter;
}
}
- assert(!adapters.empty());
+
for(LocatorAdapterInfoSeq::const_iterator p = adapters.begin(); p != adapters.end(); ++p)
{
- requestAdapter(*p);
+ p->proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, p->id));
+ }
+}
+
+void
+LocatorI::Request::activate(const string& id)
+{
+ //
+ // Activate the adapter
+ //
+ // NOTE: we use a timeout large enough to ensure that the activate() call won't
+ // timeout if the server hangs in deactivation and/or activation.
+ //
+ for(LocatorAdapterInfoSeq::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p)
+ {
+ if(p->id == id)
+ {
+ _locator->activate(*p, this);
+ _activating.insert(id);
+ }
+ }
+
+ //
+ // If this is a request for a replica group, don't wait for the activation to
+ // complete. Instead, we query the next adapter which might be already active.
+ //
+ if(_replicaGroup)
+ {
+ LocatorAdapterInfo adapter;
+ {
+ Lock sync(*this);
+ if(_lastAdapter != _adapters.end())
+ {
+ adapter = *_lastAdapter;
+ ++_lastAdapter;
+ }
+ }
+ if(adapter.proxy)
+ {
+ adapter.proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, adapter.id));
+ }
}
}
void
-LocatorI::Request::exception(const Ice::Exception& ex)
+LocatorI::Request::exception(const string& id, const Ice::Exception& ex)
{
LocatorAdapterInfo adapter;
{
Lock sync(*this);
-
if(!_exception.get())
{
_exception.reset(ex.ice_clone());
}
+
+ _activating.erase(id);
if(_lastAdapter == _adapters.end())
{
--_count; // Expect one less adapter proxy if there's no more adapters to query.
-
+
//
// If we received all the required proxies, it's time to send the
// answer back to the client.
@@ -236,7 +291,6 @@ LocatorI::Request::exception(const Ice::Exception& ex)
{
sendResponse();
}
- return;
}
else
{
@@ -244,16 +298,28 @@ LocatorI::Request::exception(const Ice::Exception& ex)
++_lastAdapter;
}
}
- requestAdapter(adapter);
+
+ if(adapter.proxy)
+ {
+ adapter.proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, adapter.id));
+ }
}
void
-LocatorI::Request::response(const Ice::ObjectPrx& proxy)
+LocatorI::Request::response(const string& id, const Ice::ObjectPrx& proxy)
{
+ if(!proxy)
+ {
+ exception(id, AdapterNotActiveException());
+ return;
+ }
+
Lock sync(*this);
assert(proxy);
- _proxies.push_back(proxy->ice_identity(_locator->getCommunicator()->stringToIdentity("dummy")));
+ _activating.erase(id);
+
+ _proxies[id] = proxy->ice_identity(_locator->getCommunicator()->stringToIdentity("dummy"));
//
// If we received all the required proxies, it's time to send the
@@ -266,22 +332,11 @@ LocatorI::Request::response(const Ice::ObjectPrx& proxy)
}
void
-LocatorI::Request::requestAdapter(const LocatorAdapterInfo& adapter)
-{
- assert(adapter.proxy);
- if(_locator->getDirectProxyRequest(this, adapter))
- {
- AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(_locator, _id, adapter);
- adapter.proxy->getDirectProxy_async(amiCB);
- }
-}
-
-void
LocatorI::Request::sendResponse()
{
if(_proxies.size() == 1)
{
- _amdCB->ice_response(_proxies.back());
+ _amdCB->ice_response(_proxies.begin()->second);
}
else if(_proxies.empty())
{
@@ -304,10 +359,19 @@ LocatorI::Request::sendResponse()
{
Ice::EndpointSeq endpoints;
endpoints.reserve(_proxies.size());
- for(vector<Ice::ObjectPrx>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p)
+ for(LocatorAdapterInfoSeq::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p)
{
- Ice::EndpointSeq edpts = (*p)->ice_getEndpoints();
- endpoints.insert(endpoints.end(), edpts.begin(), edpts.end());
+ map<string, Ice::ObjectPrx>::const_iterator q = _proxies.find(p->id);
+ if(q != _proxies.end())
+ {
+ Ice::EndpointSeq edpts = q->second->ice_getEndpoints();
+ endpoints.insert(endpoints.end(), edpts.begin(), edpts.end());
+ }
+ }
+
+ for(set<string>::const_iterator q = _activating.begin(); q != _activating.end(); ++q)
+ {
+ _locator->cancelActivate(*q, this);
}
Ice::ObjectPrx proxy = _locator->getCommunicator()->stringToProxy("dummy:default");
@@ -442,54 +506,55 @@ LocatorI::getLocalQuery(const Ice::Current&) const
return _localQuery;
}
-bool
-LocatorI::getDirectProxyRequest(const RequestPtr& request, const LocatorAdapterInfo& adapter)
+const Ice::CommunicatorPtr&
+LocatorI::getCommunicator() const
{
- Lock sync(*this);
-
- //
- // Check if there's already pending requests for this adapter. If that's the case,
- // we just add this one to the queue. If not, we add it to the queue and initiate
- // a call on the adapter to get its direct proxy.
- //
- PendingRequestsMap::iterator p;
- p = _pendingRequests.insert(make_pair(adapter.proxy->ice_getIdentity(), PendingRequests())).first;
- p->second.push_back(request);
- return p->second.size() == 1;
+ return _communicator;
}
void
-LocatorI::getDirectProxyException(const LocatorAdapterInfo& adpt, const string& id, const Ice::Exception& ex)
+LocatorI::activate(const LocatorAdapterInfo& adapter, const RequestPtr& request)
{
- try
- {
- ex.ice_throw();
- }
- catch(const AdapterNotActiveException& ex)
{
- if(ex.activatable)
+ Lock sync(*this);
+
+ //
+ // Check if there's already pending requests for this adapter. If that's the case,
+ // we just add this one to the queue. If not, we add it to the queue and initiate
+ // a call on the adapter to get its direct proxy.
+ //
+ PendingRequestsMap::iterator p;
+ p = _pendingRequests.insert(make_pair(adapter.id, PendingRequests())).first;
+ p->second.insert(request);
+ if(p->second.size() != 1)
{
- //
- // Activate the adapter if it can be activated on demand.
- //
- // NOTE: we use a timeout large enough to ensure that the
- // activate() call won't timeout if the server hangs in
- // deactivation and/or activation.
- //
- AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, id, adpt);
- int timeout = adpt.activationTimeout + adpt.deactivationTimeout;
- AdapterPrx::uncheckedCast(adpt.proxy->ice_timeout(timeout * 1000))->activate_async(amiCB);
return;
}
}
- catch(const Ice::Exception&)
+
+ AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, adapter.id);
+ int timeout = adapter.activationTimeout + adapter.deactivationTimeout;
+ AdapterPrx::uncheckedCast(adapter.proxy->ice_timeout(timeout * 1000))->activate_async(amiCB);
+}
+
+void
+LocatorI::cancelActivate(const string& id, const RequestPtr& request)
+{
+ Lock sync(*this);
+ PendingRequestsMap::iterator p = _pendingRequests.find(id);
+ if(p != _pendingRequests.end())
{
+ p->second.erase(request);
}
+}
+void
+LocatorI::activateFinished(const string& id, const Ice::ObjectPrx& proxy)
+{
PendingRequests requests;
{
Lock sync(*this);
- PendingRequestsMap::iterator p = _pendingRequests.find(adpt.proxy->ice_getIdentity());
+ PendingRequestsMap::iterator p = _pendingRequests.find(id);
assert(p != _pendingRequests.end());
requests.swap(p->second);
_pendingRequests.erase(p);
@@ -497,40 +562,24 @@ LocatorI::getDirectProxyException(const LocatorAdapterInfo& adpt, const string&
for(PendingRequests::iterator q = requests.begin(); q != requests.end(); ++q)
{
- (*q)->exception(ex);
+ (*q)->response(id, proxy);
}
}
void
-LocatorI::getDirectProxyCallback(const Ice::Identity& adapterId, const Ice::ObjectPrx& proxy)
+LocatorI::activateException(const string& id, const Ice::Exception& ex)
{
PendingRequests requests;
{
Lock sync(*this);
- PendingRequestsMap::iterator p = _pendingRequests.find(adapterId);
+ PendingRequestsMap::iterator p = _pendingRequests.find(id);
assert(p != _pendingRequests.end());
requests.swap(p->second);
_pendingRequests.erase(p);
}
- if(proxy)
- {
- for(PendingRequests::const_iterator q = requests.begin(); q != requests.end(); ++q)
- {
- (*q)->response(proxy);
- }
- }
- else
+ for(PendingRequests::iterator q = requests.begin(); q != requests.end(); ++q)
{
- for(PendingRequests::const_iterator q = requests.begin(); q != requests.end(); ++q)
- {
- (*q)->exception(AdapterNotActiveException());
- }
+ (*q)->exception(id, ex);
}
}
-
-const Ice::CommunicatorPtr&
-LocatorI::getCommunicator() const
-{
- return _communicator;
-}
diff --git a/cpp/src/IceGrid/LocatorI.h b/cpp/src/IceGrid/LocatorI.h
index e36741631f9..f0f97239c83 100644
--- a/cpp/src/IceGrid/LocatorI.h
+++ b/cpp/src/IceGrid/LocatorI.h
@@ -13,6 +13,8 @@
#include <IceGrid/Internal.h>
#include <IceGrid/Locator.h>
+#include <set>
+
namespace IceGrid
{
@@ -30,6 +32,8 @@ typedef std::vector<LocatorAdapterInfo> LocatorAdapterInfoSeq;
class LocatorI : public Locator, public IceUtil::Mutex
{
+public:
+
class Request : public IceUtil::Mutex, public IceUtil::Shared
{
public:
@@ -38,8 +42,15 @@ class LocatorI : public Locator, public IceUtil::Mutex
const LocatorAdapterInfoSeq&, int, const TraceLevelsPtr&);
void execute();
- void response(const Ice::ObjectPrx&);
- void exception(const Ice::Exception&);
+ void response(const std::string&, const Ice::ObjectPrx&);
+ void activate(const std::string&);
+ void exception(const std::string&, const Ice::Exception&);
+
+ virtual bool
+ operator<(const Request& r) const
+ {
+ return this < &r;
+ }
private:
@@ -54,13 +65,12 @@ class LocatorI : public Locator, public IceUtil::Mutex
const TraceLevelsPtr _traceLevels;
unsigned int _count;
LocatorAdapterInfoSeq::const_iterator _lastAdapter;
- std::vector<Ice::ObjectPrx> _proxies;
+ std::map<std::string, Ice::ObjectPrx> _proxies;
std::auto_ptr<Ice::Exception> _exception;
+ std::set<std::string> _activating;
};
typedef IceUtil::Handle<Request> RequestPtr;
-public:
-
LocatorI(const Ice::CommunicatorPtr&, const DatabasePtr&, const Ice::LocatorRegistryPrx&, const RegistryPrx&,
const QueryPrx&);
@@ -73,13 +83,15 @@ public:
virtual Ice::LocatorRegistryPrx getRegistry(const Ice::Current&) const;
virtual RegistryPrx getLocalRegistry(const Ice::Current&) const;
virtual QueryPrx getLocalQuery(const Ice::Current&) const;
-
- bool getDirectProxyRequest(const RequestPtr&, const LocatorAdapterInfo&);
- void getDirectProxyException(const LocatorAdapterInfo&, const std::string&, const Ice::Exception&);
- void getDirectProxyCallback(const Ice::Identity&, const Ice::ObjectPrx&);
const Ice::CommunicatorPtr& getCommunicator() const;
+ void activate(const LocatorAdapterInfo&, const RequestPtr&);
+ void cancelActivate(const std::string&, const RequestPtr&);
+
+ void activateFinished(const std::string&, const Ice::ObjectPrx&);
+ void activateException(const std::string&, const Ice::Exception&);
+
protected:
const Ice::CommunicatorPtr _communicator;
@@ -88,8 +100,8 @@ protected:
const RegistryPrx _localRegistry;
const QueryPrx _localQuery;
- typedef std::vector<RequestPtr> PendingRequests;
- typedef std::map<Ice::Identity, PendingRequests> PendingRequestsMap;
+ typedef std::set<RequestPtr> PendingRequests;
+ typedef std::map<std::string, PendingRequests> PendingRequestsMap;
PendingRequestsMap _pendingRequests;
};
diff --git a/cpp/src/IceGrid/Scanner.l b/cpp/src/IceGrid/Scanner.l
index 8f78cea0757..2ebda3c291d 100644
--- a/cpp/src/IceGrid/Scanner.l
+++ b/cpp/src/IceGrid/Scanner.l
@@ -45,6 +45,7 @@ NL [\n]
keyword [[:alpha:]]*
%option noyywrap
+%option always-interactive
%%
diff --git a/cpp/src/IceStorm/Scanner.l b/cpp/src/IceStorm/Scanner.l
index 07fc177c19f..818f8f0b9b7 100644
--- a/cpp/src/IceStorm/Scanner.l
+++ b/cpp/src/IceStorm/Scanner.l
@@ -45,6 +45,7 @@ NL [\n]
keyword [[:alpha:]]*
%option noyywrap
+%option always-interactive
%%