// // Copyright (c) ZeroC, Inc. All rights reserved. // #include #include #include #include #include using namespace std; using namespace Ice; using namespace Glacier2; Glacier2::RouterI::RouterI(shared_ptr instance, shared_ptr connection, const string& userId, shared_ptr session, const Identity& controlId, shared_ptr filters, const Context& context) : _instance(move(instance)), _routingTable(make_shared(_instance->communicator(), _instance->proxyVerifier())), _clientBlobject(make_shared(_instance, move(filters), context, _routingTable)), _clientBlobjectBuffered(_instance->clientRequestQueueThread()), _serverBlobjectBuffered(_instance->serverRequestQueueThread()), _connection(move(connection)), _userId(userId), _session(move(session)), _controlId(controlId), _context(context), _timestamp(chrono::steady_clock::now()) { // // If Glacier2 will be used with pre 3.2 clients, then the client proxy must be set. // Otherwise getClientProxy just needs to return a nil proxy. // if(_instance->properties()->getPropertyAsInt("Glacier2.ReturnClientProxy") > 0) { const_cast&>(_clientProxy) = _instance->clientObjectAdapter()->createProxy(stringToIdentity("dummy")); } if(_instance->serverObjectAdapter()) { Identity ident = { "dummy", "" }; random_device rd; mt19937 gen(rd()); uniform_int_distribution<> dist(33, 126); // We use ASCII 33-126 (from ! to ~, w/o space). for(unsigned int i = 0; i < 20; ++i) { ident.category.push_back(static_cast(dist(gen))); } const_cast&>(_serverProxy) = _instance->serverObjectAdapter()->createProxy(ident); shared_ptr& serverBlobject = const_cast&>(_serverBlobject); serverBlobject = make_shared(_instance, _connection); } if(_instance->getObserver()) { updateObserver(_instance->getObserver()); } } void Glacier2::RouterI::destroy(function error) { if(_session) { if(_instance->serverObjectAdapter()) { try { // // Remove the session control object. // _instance->serverObjectAdapter()->remove(_controlId); } catch(const NotRegisteredException&) { } catch(const ObjectAdapterDeactivatedException&) { // // Expected if the router has been shutdown. // } } if(_context.size() > 0) { _session->destroyAsync(nullptr, move(error), nullptr, _context); } else { _session->destroyAsync(nullptr, move(error), nullptr); } } _clientBlobject->destroy(); if(_serverBlobject) { _serverBlobject->destroy(); } _routingTable->destroy(); } shared_ptr Glacier2::RouterI::getClientProxy(Ice::optional& hasRoutingTable, const Current&) const { // No mutex lock necessary, _clientProxy is immutable and is never destroyed. hasRoutingTable = true; return _clientProxy; } shared_ptr Glacier2::RouterI::getServerProxy(const Current&) const { // No mutex lock necessary, _serverProxy is immutable and is never destroyed. return _serverProxy; } ObjectProxySeq Glacier2::RouterI::addProxies(ObjectProxySeq proxies, const Current& current) { return _routingTable->add(move(proxies), current); } string Glacier2::RouterI::getCategoryForClient(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } void Glacier2::RouterI::createSessionAsync(string, string, function& returnValue)>, function, const Current&) { assert(false); // Must not be called in this router implementation. } void Glacier2::RouterI::createSessionFromSecureConnectionAsync(function& returnValue)>, function, const Current&) { assert(false); // Must not be called in this router implementation. } void Glacier2::RouterI::refreshSessionAsync(function, function, const Current&) { assert(false); // Must not be called in this router implementation. } void Glacier2::RouterI::destroySession(const Current&) { assert(false); // Must not be called in this router implementation. } Long Glacier2::RouterI::getSessionTimeout(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } Int Glacier2::RouterI::getACMTimeout(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } shared_ptr Glacier2::RouterI::getClientBlobject() const { // Can only be called with the SessionRouterI mutex locked if(!_clientBlobjectBuffered && _observer) { _observer->forwarded(true); } return _clientBlobject; } shared_ptr Glacier2::RouterI::getServerBlobject() const { // Can only be called with the SessionRouterI mutex locked if(!_serverBlobjectBuffered && _observer) { _observer->forwarded(false); } return _serverBlobject; } shared_ptr Glacier2::RouterI::getSession() const { return _session; // No mutex lock necessary, _session is immutable. } chrono::steady_clock::time_point Glacier2::RouterI::getTimestamp() const { // Can only be called with the SessionRouterI mutex locked return _timestamp; } void Glacier2::RouterI::updateTimestamp() const { // Can only be called with the SessionRouterI mutex locked _timestamp = chrono::steady_clock::now(); } void Glacier2::RouterI::updateObserver(const shared_ptr& observer) { // Can only be called with the SessionRouterI mutex locked _observer = _routingTable->updateObserver(observer, _userId, _connection); _clientBlobject->updateObserver(_observer); if(_serverBlobject) { _serverBlobject->updateObserver(_observer); } } string Glacier2::RouterI::toString() const { ostringstream out; out << "id = " << _userId << '\n'; if(_serverProxy) { out << "category = " << _serverProxy->ice_getIdentity().category << '\n'; } out << _connection->toString(); return out.str(); }