summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2004-09-30 17:21:47 +0000
committerMarc Laukien <marc@zeroc.com>2004-09-30 17:21:47 +0000
commit338f12d50adc609ddff7641af1d84be3cba282b7 (patch)
tree06ffe08c28ab4da3cd710a7165e1ba7356823f9d /cpp/src
parentAdded tests for collection of leaf nodes. (diff)
downloadice-338f12d50adc609ddff7641af1d84be3cba282b7.tar.bz2
ice-338f12d50adc609ddff7641af1d84be3cba282b7.tar.xz
ice-338f12d50adc609ddff7641af1d84be3cba282b7.zip
more glacier2
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier/Blobject.h7
-rw-r--r--cpp/src/Glacier/ClientBlobject.h3
-rw-r--r--cpp/src/Glacier/ServerBlobject.h3
-rw-r--r--cpp/src/Glacier2/Blobject.cpp5
-rw-r--r--cpp/src/Glacier2/Blobject.h3
-rw-r--r--cpp/src/Glacier2/ClientBlobject.cpp3
-rw-r--r--cpp/src/Glacier2/ClientBlobject.h3
-rw-r--r--cpp/src/Glacier2/Glacier2Router.cpp18
-rw-r--r--cpp/src/Glacier2/RequestQueue.cpp3
-rw-r--r--cpp/src/Glacier2/RouterI.cpp143
-rw-r--r--cpp/src/Glacier2/RouterI.h20
-rw-r--r--cpp/src/Glacier2/ServerBlobject.h3
-rw-r--r--cpp/src/Glacier2/SessionRouterI.cpp232
-rw-r--r--cpp/src/Glacier2/SessionRouterI.h10
-rw-r--r--cpp/src/Ice/Instance.cpp2
15 files changed, 339 insertions, 119 deletions
diff --git a/cpp/src/Glacier/Blobject.h b/cpp/src/Glacier/Blobject.h
index 7491c63b929..cc757d8ce3b 100644
--- a/cpp/src/Glacier/Blobject.h
+++ b/cpp/src/Glacier/Blobject.h
@@ -47,13 +47,14 @@ public:
Blobject(const Ice::CommunicatorPtr&, bool);
virtual ~Blobject();
- void destroy();
+ virtual void destroy();
+
+protected:
+
void invoke(Ice::ObjectPrx&, const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
bool modifyProxy(Ice::ObjectPrx&, const Ice::Current&);
-protected:
-
Ice::CommunicatorPtr _communicator;
const bool _reverse;
diff --git a/cpp/src/Glacier/ClientBlobject.h b/cpp/src/Glacier/ClientBlobject.h
index de5930b3707..7deeb9677e4 100644
--- a/cpp/src/Glacier/ClientBlobject.h
+++ b/cpp/src/Glacier/ClientBlobject.h
@@ -22,7 +22,8 @@ public:
ClientBlobject(const Ice::CommunicatorPtr&, const IceInternal::RoutingTablePtr&, const std::string&);
- void destroy();
+ virtual void destroy();
+
virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
diff --git a/cpp/src/Glacier/ServerBlobject.h b/cpp/src/Glacier/ServerBlobject.h
index a04ef3d3d15..fbab7ad0d79 100644
--- a/cpp/src/Glacier/ServerBlobject.h
+++ b/cpp/src/Glacier/ServerBlobject.h
@@ -21,7 +21,8 @@ public:
ServerBlobject(const Ice::ObjectAdapterPtr&);
- void destroy();
+ virtual void destroy();
+
virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
diff --git a/cpp/src/Glacier2/Blobject.cpp b/cpp/src/Glacier2/Blobject.cpp
index 334ecd3164a..57bf70e55dd 100644
--- a/cpp/src/Glacier2/Blobject.cpp
+++ b/cpp/src/Glacier2/Blobject.cpp
@@ -17,10 +17,11 @@ static const string serverAlwaysBatch = "Glacier2.Server.AlwaysBatch";
static const string clientAlwaysBatch = "Glacier2.Client.AlwaysBatch";
Glacier2::Blobject::Blobject(const CommunicatorPtr& communicator, bool reverse) :
+ _properties(communicator->getProperties()),
_logger(communicator->getLogger()),
_alwaysBatch(reverse ?
- communicator->getProperties()->getPropertyAsInt(serverAlwaysBatch) > 0 :
- communicator->getProperties()->getPropertyAsInt(clientAlwaysBatch) > 0)
+ _properties->getPropertyAsInt(serverAlwaysBatch) > 0 :
+ _properties->getPropertyAsInt(clientAlwaysBatch) > 0)
{
_requestQueue = new RequestQueue(communicator, reverse);
_requestQueue->start();
diff --git a/cpp/src/Glacier2/Blobject.h b/cpp/src/Glacier2/Blobject.h
index 8d5e89f6652..5895b2fad06 100644
--- a/cpp/src/Glacier2/Blobject.h
+++ b/cpp/src/Glacier2/Blobject.h
@@ -23,13 +23,14 @@ public:
Blobject(const Ice::CommunicatorPtr&, bool);
virtual ~Blobject();
- void destroy();
+ virtual void destroy();
protected:
void invoke(Ice::ObjectPrx&, const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
+ const Ice::PropertiesPtr _properties;
const Ice::LoggerPtr _logger;
private:
diff --git a/cpp/src/Glacier2/ClientBlobject.cpp b/cpp/src/Glacier2/ClientBlobject.cpp
index f568efa27df..30fe28b30f1 100644
--- a/cpp/src/Glacier2/ClientBlobject.cpp
+++ b/cpp/src/Glacier2/ClientBlobject.cpp
@@ -1,4 +1,3 @@
-
// **********************************************************************
//
// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
@@ -21,7 +20,7 @@ Glacier2::ClientBlobject::ClientBlobject(const CommunicatorPtr& communicator,
const string& allow) :
Glacier2::Blobject(communicator, false),
_routingTable(routingTable),
- _rejectTraceLevel(communicator->getProperties()->getPropertyAsInt("Glacier2.Client.Trace.Reject"))
+ _rejectTraceLevel(_properties->getPropertyAsInt("Glacier2.Client.Trace.Reject"))
{
vector<string>& allowCategories = const_cast<vector<string>&>(_allowCategories);
diff --git a/cpp/src/Glacier2/ClientBlobject.h b/cpp/src/Glacier2/ClientBlobject.h
index 412c3c9b485..2d3d24ad695 100644
--- a/cpp/src/Glacier2/ClientBlobject.h
+++ b/cpp/src/Glacier2/ClientBlobject.h
@@ -26,7 +26,8 @@ public:
ClientBlobject(const Ice::CommunicatorPtr&, const IceInternal::RoutingTablePtr&, const std::string&);
virtual ~ClientBlobject();
- void destroy();
+ virtual void destroy();
+
virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp
index 3c59e915638..ee0acd991d1 100644
--- a/cpp/src/Glacier2/Glacier2Router.cpp
+++ b/cpp/src/Glacier2/Glacier2Router.cpp
@@ -153,18 +153,20 @@ Glacier2::RouterService::start(int argc, char* argv[])
}
//
- // Create a router implementation that can handle sessions, and
- // add it to the client object adapter.
+ // Create the session router. The session router registers itself
+ // and all required servant locators, so no registration has to be
+ // done here.
//
_sessionRouter = new SessionRouterI(clientAdapter, serverAdapter, verifier);
- const char* routerIdProperty = "Glacier2.RouterIdentity";
- Identity routerId = stringToIdentity(properties->getPropertyWithDefault(routerIdProperty, "Glacier2/router"));
- clientAdapter->add(_sessionRouter, routerId);
//
// Everything ok, let's go.
//
clientAdapter->activate();
+ if(serverAdapter)
+ {
+ serverAdapter->activate();
+ }
return true;
}
@@ -172,12 +174,8 @@ Glacier2::RouterService::start(int argc, char* argv[])
bool
Glacier2::RouterService::stop()
{
- //
- // Destroy the session router.
- //
- assert(_sessionRouter);
_sessionRouter->destroy();
-
+ _sessionRouter = 0;
return true;
}
diff --git a/cpp/src/Glacier2/RequestQueue.cpp b/cpp/src/Glacier2/RequestQueue.cpp
index 50d7402c83a..fa4e6eb921c 100644
--- a/cpp/src/Glacier2/RequestQueue.cpp
+++ b/cpp/src/Glacier2/RequestQueue.cpp
@@ -187,7 +187,6 @@ Glacier2::RequestQueue::run()
while(true)
{
vector<RequestPtr> requests;
- set<ConnectionPtr> flushSet;
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
@@ -216,6 +215,8 @@ Glacier2::RequestQueue::run()
try
{
+ set<ConnectionPtr> flushSet;
+
for(vector<RequestPtr>::const_iterator p = requests.begin(); p != requests.end(); ++p)
{
const ObjectPrx& proxy = (*p)->getProxy();
diff --git a/cpp/src/Glacier2/RouterI.cpp b/cpp/src/Glacier2/RouterI.cpp
index 609d6363093..5f49cbc52e2 100644
--- a/cpp/src/Glacier2/RouterI.cpp
+++ b/cpp/src/Glacier2/RouterI.cpp
@@ -14,108 +14,89 @@ using namespace std;
using namespace Ice;
using namespace Glacier2;
-class RouterLocator : public ServantLocator
-{
-public:
-
- RouterLocator(const ServerBlobjectPtr& serverBlobject) :
- _serverBlobject(serverBlobject)
- {
- }
-
- virtual ObjectPtr
- locate(const Current& current, LocalObjectPtr&)
- {
- return _serverBlobject;
- }
-
- virtual void
- finished(const Current&, const ObjectPtr&, const LocalObjectPtr&)
- {
- }
-
- virtual void
- deactivate(const string&)
- {
- }
-
-private:
-
- ServerBlobjectPtr _serverBlobject;
-};
-
-Glacier2::RouterI::RouterI(const ObjectAdapterPtr& clientAdapter,
- const ObjectAdapterPtr& serverAdapter,
- const ConnectionPtr& connection) :
+Glacier2::RouterI::RouterI(const ObjectAdapterPtr& clientAdapter, const ObjectAdapterPtr& serverAdapter,
+ const ConnectionPtr& connection, const string& userId) :
_communicator(clientAdapter->getCommunicator()),
_routingTable(new IceInternal::RoutingTable),
_routingTableTraceLevel(_communicator->getProperties()->getPropertyAsInt("Glacier2.Trace.RoutingTable")),
_clientProxy(clientAdapter->createProxy(stringToIdentity("dummy"))),
- _clientBlobject(new ClientBlobject(_communicator, _routingTable, ""))
+ _clientBlobject(new ClientBlobject(_communicator, _routingTable, "")),
+ _connection(connection),
+ _userId(userId),
+ _timestamp(IceUtil::Time::now()),
+ _destroy(false)
{
- try
+ if(serverAdapter)
{
- if(serverAdapter)
+ ObjectPrx& serverProxy = const_cast<ObjectPrx&>(_serverProxy);
+ Identity ident;
+ ident.name = "dummy";
+ ident.category.resize(20);
+ for(string::iterator p = ident.category.begin(); p != ident.category.end(); ++p)
{
- ObjectPrx& serverProxy = const_cast<ObjectPrx&>(_serverProxy);
- Identity ident;
- ident.name = "dummy";
- ident.category.resize(20);
- for(string::iterator p = ident.category.begin(); p != ident.category.end(); ++p)
- {
- *p = static_cast<char>(33 + rand() % (127-33)); // We use ASCII 33-126 (from ! to ~, w/o space).
- }
- serverProxy = serverAdapter->createProxy(ident);
-
- ServerBlobjectPtr& serverBlobject = const_cast<ServerBlobjectPtr&>(_serverBlobject);
- serverBlobject = new ServerBlobject(_communicator, connection);
- serverAdapter->addServantLocator(new RouterLocator(serverBlobject), ident.category);
- serverAdapter->activate();
+ *p = static_cast<char>(33 + rand() % (127-33)); // We use ASCII 33-126 (from ! to ~, w/o space).
}
- }
- catch(...)
- {
- destroy();
- throw;
+ serverProxy = serverAdapter->createProxy(ident);
+
+ ServerBlobjectPtr& serverBlobject = const_cast<ServerBlobjectPtr&>(_serverBlobject);
+ serverBlobject = new ServerBlobject(_communicator, connection);
}
}
Glacier2::RouterI::~RouterI()
{
+ assert(_destroy);
}
void
Glacier2::RouterI::destroy()
{
- _clientBlobject->destroy();
+ IceUtil::Mutex::Lock lock(*this);
+
+ assert(!_destroy);
+ _clientBlobject->destroy();
+
if(_serverBlobject)
{
_serverBlobject->destroy();
- }
+ }
+
+ _destroy = true;
}
ObjectPrx
Glacier2::RouterI::getClientProxy(const Current&) const
{
+ // No mutex lock necessary, _clientProxy is immutable and is never destroyed.
return _clientProxy;
}
ObjectPrx
Glacier2::RouterI::getServerProxy(const Current&) const
{
+ // No mutex lock necessary, _serverProxy is immutable and is never destroyed.
return _serverProxy;
}
void
Glacier2::RouterI::addProxy(const ObjectPrx& proxy, const Current&)
{
+ IceUtil::Mutex::Lock lock(*this);
+
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
if(_routingTableTraceLevel)
{
Trace out(_communicator->getLogger(), "Glacier2");
out << "adding proxy to routing table:\n" << _communicator->proxyToString(proxy);
}
+ _timestamp = IceUtil::Time::now();
+
_routingTable->add(proxy);
}
@@ -128,11 +109,59 @@ Glacier2::RouterI::createSession(const std::string&, const std::string&, const C
ClientBlobjectPtr
Glacier2::RouterI::getClientBlobject() const
{
+ IceUtil::Mutex::Lock lock(*this);
+
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ _timestamp = IceUtil::Time::now();
+
return _clientBlobject;
}
ServerBlobjectPtr
Glacier2::RouterI::getServerBlobject() const
{
+ IceUtil::Mutex::Lock lock(*this);
+
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ _timestamp = IceUtil::Time::now();
+
return _serverBlobject;
}
+
+IceUtil::Time
+Glacier2::RouterI::getTimestamp() const
+{
+ IceUtil::Mutex::TryLock lock(*this);
+
+ if(lock.acquired())
+ {
+ return _timestamp;
+ }
+ else
+ {
+ return IceUtil::Time::now();
+ }
+}
+
+string
+Glacier2::RouterI::toString() const
+{
+ ostringstream out;
+
+ out << "user-id = " << _userId << '\n';
+ if(_serverProxy)
+ {
+ out << "category = " << _serverProxy->ice_getIdentity().category << '\n';
+ }
+ out << _connection->toString();
+
+ return out.str();
+}
diff --git a/cpp/src/Glacier2/RouterI.h b/cpp/src/Glacier2/RouterI.h
index fc5dd9297c1..f21fb543f59 100644
--- a/cpp/src/Glacier2/RouterI.h
+++ b/cpp/src/Glacier2/RouterI.h
@@ -21,11 +21,11 @@ namespace Glacier2
class RouterI;
typedef IceUtil::Handle<RouterI> RouterIPtr;
-class RouterI : public Router
+class RouterI : public Router, public IceUtil::Mutex
{
public:
- RouterI(const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&, const Ice::ConnectionPtr&);
+ RouterI(const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&, const Ice::ConnectionPtr&, const std::string&);
virtual ~RouterI();
void destroy();
@@ -34,8 +34,12 @@ public:
virtual void addProxy(const Ice::ObjectPrx&, const Ice::Current&);
virtual void createSession(const std::string&, const std::string&, const Ice::Current&);
- Glacier2::ClientBlobjectPtr getClientBlobject() const;
- Glacier2::ServerBlobjectPtr getServerBlobject() const;
+ ClientBlobjectPtr getClientBlobject() const;
+ ServerBlobjectPtr getServerBlobject() const;
+
+ IceUtil::Time getTimestamp() const;
+
+ std::string toString() const;
private:
@@ -44,8 +48,12 @@ private:
const int _routingTableTraceLevel;
const Ice::ObjectPrx _clientProxy;
const Ice::ObjectPrx _serverProxy;
- const Glacier2::ClientBlobjectPtr _clientBlobject;
- const Glacier2::ServerBlobjectPtr _serverBlobject;
+ const ClientBlobjectPtr _clientBlobject;
+ const ServerBlobjectPtr _serverBlobject;
+ const Ice::ConnectionPtr _connection;
+ const std::string _userId;
+ mutable IceUtil::Time _timestamp;
+ bool _destroy;
};
}
diff --git a/cpp/src/Glacier2/ServerBlobject.h b/cpp/src/Glacier2/ServerBlobject.h
index 2cc3a42e673..7f5ac076cf2 100644
--- a/cpp/src/Glacier2/ServerBlobject.h
+++ b/cpp/src/Glacier2/ServerBlobject.h
@@ -25,7 +25,8 @@ public:
ServerBlobject(const Ice::CommunicatorPtr&, const Ice::ConnectionPtr&);
virtual ~ServerBlobject();
- void destroy();
+ virtual void destroy();
+
virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, const std::vector<Ice::Byte>&,
const Ice::Current&);
diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp
index 80b8d88b02a..8bb60387729 100644
--- a/cpp/src/Glacier2/SessionRouterI.cpp
+++ b/cpp/src/Glacier2/SessionRouterI.cpp
@@ -15,11 +15,11 @@ using namespace std;
using namespace Ice;
using namespace Glacier2;
-class SessionLocator : public ServantLocator
+class ClientLocator : public ServantLocator
{
public:
- SessionLocator(const SessionRouterIPtr& sessionRouter) :
+ ClientLocator(const SessionRouterIPtr& sessionRouter) :
_sessionRouter(sessionRouter)
{
}
@@ -27,7 +27,6 @@ public:
virtual ObjectPtr
locate(const Current& current, LocalObjectPtr&)
{
- assert(current.con);
return _sessionRouter->getRouter(current.con)->getClientBlobject();
}
@@ -46,46 +45,121 @@ private:
const SessionRouterIPtr _sessionRouter;
};
+class ServerLocator : public ServantLocator
+{
+public:
+
+ ServerLocator(const SessionRouterIPtr& sessionRouter) :
+ _sessionRouter(sessionRouter)
+ {
+ }
+
+ virtual ObjectPtr
+ locate(const Current& current, LocalObjectPtr&)
+ {
+ return _sessionRouter->getRouter(current.id.category)->getServerBlobject();
+ }
+
+ virtual void
+ finished(const Current&, const ObjectPtr&, const LocalObjectPtr&)
+ {
+ }
+
+ virtual void
+ deactivate(const std::string&)
+ {
+ }
+
+private:
+
+ const SessionRouterIPtr _sessionRouter;
+};
+
Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter,
const ObjectAdapterPtr& serverAdapter,
const PermissionsVerifierPrx& verifier) :
+ _properties(clientAdapter->getCommunicator()->getProperties()),
_logger(clientAdapter->getCommunicator()->getLogger()),
- _traceLevel(clientAdapter->getCommunicator()->getProperties()->getPropertyAsInt("Glacier2.Trace.Session")),
+ _traceLevel(_properties->getPropertyAsInt("Glacier2.Trace.Session")),
_clientAdapter(clientAdapter),
_serverAdapter(serverAdapter),
_verifier(verifier),
- _sessionThread(new SessionThread(this)),
- _routersHint(_routers.end()),
+ _sessionTimeout(IceUtil::Time::seconds(_properties->getPropertyAsInt("Glacier2.SessionTimeout"))),
+ _sessionThread(_sessionTimeout > IceUtil::Time() ? new SessionThread(this) : 0),
+ _routersByConnectionHint(_routersByConnection.end()),
+ _routersByCategoryHint(_routersByCategory.end()),
_destroy(false)
{
- _clientAdapter->addServantLocator(new SessionLocator(this), "");
+ //
+ // This session router is used directly as servant for the main
+ // Glacier2 router Ice object.
+ //
+ const char* routerIdProperty = "Glacier2.RouterIdentity";
+ Identity routerId = stringToIdentity(_properties->getPropertyWithDefault(routerIdProperty, "Glacier2/router"));
+ _clientAdapter->add(this, routerId);
+
+ //
+ // All other calls on the client object adapter are dispatched to
+ // a router servant based on connection information.
+ //
+ ServantLocatorPtr clientLocator = new ClientLocator(this);
+ _clientAdapter->addServantLocator(clientLocator, "");
+
+ //
+ // If there is a server object adapter, all calls on this adapter
+ // are dispatched to a router servant based on the category field
+ // of the identity.
+ //
+ if(_serverAdapter)
+ {
+ ServantLocatorPtr serverLocator = new ServerLocator(this);
+ _serverAdapter->addServantLocator(serverLocator, "");
+ }
+
+ if(_sessionThread)
+ {
+ _sessionThread->start();
+ }
}
Glacier2::SessionRouterI::~SessionRouterI()
{
assert(_destroy);
- assert(_routers.empty());
+ assert(_routersByConnection.empty());
+ assert(_routersByCategory.empty());
}
void
Glacier2::SessionRouterI::destroy()
{
+ map<ConnectionPtr, RouterIPtr> routers;
+
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
assert(!_destroy);
- _destroy = true;
+ _routersByConnection.swap(routers);
+ _routersByConnectionHint = _routersByConnection.end();
- for_each(_routers.begin(), _routers.end(),
- IceUtil::secondVoidMemFun<const ConnectionPtr, RouterI>(&RouterI::destroy));
- _routers.clear();
- _routersHint = _routers.end();
+ _routersByCategory.clear();
+ _routersByCategoryHint = _routersByCategory.end();
+ _destroy = true;
notify();
}
- _sessionThread->getThreadControl().join();
+ //
+ // We destroy the routers outside the thread synchronization, to
+ // avoid deadlocks.
+ //
+ for_each(routers.begin(), routers.end(),
+ IceUtil::secondVoidMemFun<const ConnectionPtr, RouterI>(&RouterI::destroy));
+
+ if(_sessionThread)
+ {
+ _sessionThread->getThreadControl().join();
+ }
}
ObjectPrx
@@ -111,7 +185,10 @@ Glacier2::SessionRouterI::createSession(const std::string& userId, const std::st
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
- assert(!_destroy);
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
//
// Check the user-id and password.
@@ -127,14 +204,22 @@ Glacier2::SessionRouterI::createSession(const std::string& userId, const std::st
//
// Add a new per-client router.
//
- RouterIPtr router = new RouterI(_clientAdapter, _serverAdapter, current.con);
- _routersHint = _routers.insert(_routersHint, pair<const ConnectionPtr, RouterIPtr>(current.con, router));
+ RouterIPtr router = new RouterI(_clientAdapter, _serverAdapter, current.con, userId);
+ _routersByConnectionHint = _routersByConnection.insert(_routersByConnectionHint,
+ pair<const ConnectionPtr, RouterIPtr>(current.con, router));
+ if(_serverAdapter)
+ {
+ string category = router->getServerProxy(current)->ice_getIdentity().category;
+ assert(!category.empty());
+ _routersByCategoryHint = _routersByCategory.insert(_routersByCategoryHint,
+ pair<string, RouterIPtr>(category, router));
+ }
if(_traceLevel >= 1)
{
Trace out(_logger, "Glacier2");
- out << "added session for `" << userId << "':\n";
- out << current.con->toString();
+ out << "new session\n";
+ out << router->toString();
}
}
@@ -143,36 +228,125 @@ Glacier2::SessionRouterI::getRouter(const ConnectionPtr& connection) const
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
- assert(!_destroy);
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
- map<ConnectionPtr, RouterIPtr>& routers = const_cast<map<ConnectionPtr, RouterIPtr>&>(_routers);
+ map<ConnectionPtr, RouterIPtr>& routers = const_cast<map<ConnectionPtr, RouterIPtr>&>(_routersByConnection);
- if(_routersHint != routers.end() && _routersHint->first == connection)
+ if(_routersByConnectionHint != routers.end() && _routersByConnectionHint->first == connection)
{
- return _routersHint->second;
+ return _routersByConnectionHint->second;
}
map<ConnectionPtr, RouterIPtr>::iterator p = routers.find(connection);
if(p != routers.end())
{
- _routersHint = p;
+ _routersByConnectionHint = p;
+ return p->second;
+ }
+ else
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+}
+
+RouterIPtr
+Glacier2::SessionRouterI::getRouter(const string& category) const
+{
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ if(_destroy)
+ {
+ throw ObjectNotExistException(__FILE__, __LINE__);
+ }
+
+ map<string, RouterIPtr>& routers = const_cast<map<string, RouterIPtr>&>(_routersByCategory);
+
+ if(_routersByCategoryHint != routers.end() && _routersByCategoryHint->first == category)
+ {
+ return _routersByCategoryHint->second;
+ }
+
+ map<string, RouterIPtr>::iterator p = routers.find(category);
+
+ if(p != routers.end())
+ {
+ _routersByCategoryHint = p;
return p->second;
}
else
{
- return 0;
+ throw ObjectNotExistException(__FILE__, __LINE__);
}
}
void
Glacier2::SessionRouterI::run()
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+ while(true)
+ {
+ vector<RouterIPtr> routers;
+
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
+
+ if(_destroy)
+ {
+ return;
+ }
+
+ assert(_sessionTimeout > IceUtil::Time());
+ timedWait(_sessionTimeout);
+
+ if(_destroy)
+ {
+ return;
+ }
+
+ IceUtil::Time minTimestamp = IceUtil::Time::now() - _sessionTimeout;
+
+ map<ConnectionPtr, RouterIPtr>::iterator p = _routersByConnection.begin();
+
+ while(p != _routersByConnection.end())
+ {
+ if(minTimestamp < p->second->getTimestamp())
+ {
+ RouterIPtr router = p->second;
+ routers.push_back(router);
+
+ _routersByConnection.erase(p++);
+ _routersByConnectionHint = p;
+
+ if(_serverAdapter)
+ {
+ string category = router->getServerProxy(Current())->ice_getIdentity().category;
+ assert(!category.empty());
+ _routersByCategory.erase(category);
+ _routersByCategoryHint = _routersByCategory.end();
+ }
+
+ if(_traceLevel >= 1)
+ {
+ Trace out(_logger, "Glacier2");
+ out << "expired session\n";
+ out << router->toString();
+ }
+ }
+ else
+ {
+ ++p;
+ }
+ }
+ }
- while(!_destroy)
- {
- wait();
+ //
+ // We destroy the expired routers outside the thread
+ // synchronization, to avoid deadlocks.
+ //
+ for_each(routers.begin(), routers.end(), IceUtil::voidMemFun(&RouterI::destroy));
}
}
diff --git a/cpp/src/Glacier2/SessionRouterI.h b/cpp/src/Glacier2/SessionRouterI.h
index 649ce0cfd57..fd8a1170ee0 100644
--- a/cpp/src/Glacier2/SessionRouterI.h
+++ b/cpp/src/Glacier2/SessionRouterI.h
@@ -39,16 +39,19 @@ public:
virtual void createSession(const std::string&, const std::string&, const Ice::Current&);
RouterIPtr getRouter(const Ice::ConnectionPtr&) const;
+ RouterIPtr getRouter(const std::string&) const;
virtual void run();
private:
+ const Ice::PropertiesPtr _properties;
const Ice::LoggerPtr _logger;
const int _traceLevel;
const Ice::ObjectAdapterPtr _clientAdapter;
const Ice::ObjectAdapterPtr _serverAdapter;
const PermissionsVerifierPrx _verifier;
+ const IceUtil::Time _sessionTimeout;
//
// TODO: I can't inherit directly from IceUtil::Thread, because of
@@ -68,10 +71,11 @@ private:
};
const IceUtil::Handle<SessionThread> _sessionThread;
- int _serverAdapterCount;
+ std::map<Ice::ConnectionPtr, RouterIPtr> _routersByConnection;
+ mutable std::map<Ice::ConnectionPtr, RouterIPtr>::iterator _routersByConnectionHint;
- std::map<Ice::ConnectionPtr, RouterIPtr> _routers;
- mutable std::map<Ice::ConnectionPtr, RouterIPtr>::iterator _routersHint;
+ std::map<std::string, RouterIPtr> _routersByCategory;
+ mutable std::map<std::string, RouterIPtr>::iterator _routersByCategoryHint;
bool _destroy;
};
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index 5bee1edad51..a1588e45e68 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -522,7 +522,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Prope
}
{
- Int num = _properties->getPropertyAsIntWithDefault("Ice.ConnectiondleTime", 60);
+ Int num = _properties->getPropertyAsIntWithDefault("Ice.ConnectionIdleTime", 60);
if(num < 0)
{
const_cast<Int&>(_connectionIdleTime) = 0;