diff options
author | Joe George <joe@zeroc.com> | 2021-01-28 14:18:08 -0500 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2021-02-01 16:50:22 -0500 |
commit | 3dd23049d2424404255585228ffc5e0314fed7ce (patch) | |
tree | 5dd38567c461ab08f0c402f54551b42e23de29cb | |
parent | Remove checksum support (#607) (diff) | |
download | ice-3dd23049d2424404255585228ffc5e0314fed7ce.tar.bz2 ice-3dd23049d2424404255585228ffc5e0314fed7ce.tar.xz ice-3dd23049d2424404255585228ffc5e0314fed7ce.zip |
Port Glacier2, IceBox, IceBridge, IceDB, IceXML, icegriddb
37 files changed, 1951 insertions, 2665 deletions
diff --git a/cpp/config/Make.rules b/cpp/config/Make.rules index 9f6a066f92e..c70786deebb 100644 --- a/cpp/config/Make.rules +++ b/cpp/config/Make.rules @@ -60,7 +60,12 @@ static_excludes = test/Ice/library test/Ice/plugin # # Components and projects which are built with C++11 # -cpp11_components = $(coreandstub_components) icebox +cpp11_components = $(coreandstub_components) \ + glacier2router Glacier2CryptPermissionsVerifier \ + icebox iceboxadmin icebridge \ + IceDB \ + IceXML \ + icegridnode icegridregistry icegridadmin icegriddb \ cpp11_projects = test/Common \ test/IceUtil/% \ @@ -69,9 +74,11 @@ cpp11_projects = test/Common \ test/IceSSL/% \ test/IceDiscovery/% \ test/IceBox/% \ - test/Glacier2/application \ - test/Glacier2/sessionHelper \ - test/IceGrid/simple + test/IceGrid/% \ + test/IceStorm/% \ + test/Glacier2/% \ + test/IceGrid/% \ + test/IceBridge/simple cpp11_excludes = test/Ice/gc @@ -95,7 +102,7 @@ endif # the cpp11 name to the target directory if building outside the build # directory. # -cpp11_cppflags = -DICE_CPP11_MAPPING -std=c++11 +cpp11_cppflags = -DICE_CPP11_MAPPING -std=c++17 cpp11_ldflags = $(cpp11_cppflags) cpp11_targetname = $(if $(or $(filter-out $($1_target),program),$(filter $(bindir)%,$($4_targetdir))),++11) cpp11_targetdir = $(if $(filter %/build,$5),cpp11) diff --git a/cpp/include/Glacier2/Application.h b/cpp/include/Glacier2/Application.h deleted file mode 100644 index bd4927fc4c5..00000000000 --- a/cpp/include/Glacier2/Application.h +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#ifndef GLACIER2_APPLICATION_H -#define GLACIER2_APPLICATION_H - -#include <Ice/Application.h> - -#include <Glacier2/Session.h> -#include <Glacier2/Router.h> - -namespace Glacier2 -{ - -/** - * - * This exception is raised if the session should be restarted. - * \headerfile Glacier2/Glacier2.h - * - **/ -class GLACIER2_API RestartSessionException : public IceUtil::ExceptionHelper<RestartSessionException> -{ -public: - - virtual std::string ice_id() const; -#ifndef ICE_CPP11_MAPPING - virtual RestartSessionException* ice_clone() const; -#endif -}; - -/** - * An extension of Ice::Application that makes it easy to write - * Glacier2 applications. - * - * Applications must create a derived class that implements the - * createSession and runWithSession methods. - * - * The base class invokes createSession to create a new - * Glacier2 session and then invokes runWithSession in - * which the subclass performs its application logic. The base class - * automatically destroys the session when runWithSession returns. - * - * If runWithSession calls restart or raises any of - * the exceptions Ice::ConnectionRefusedException, - * Ice::ConnectionLostException, Ice::UnknownLocalException, - * Ice::RequestFailedException, or Ice::TimeoutException, the base - * class destroys the current session and restarts the application - * with another call to createSession followed by runWithSession. - * - * The application can optionally override the sessionDestroyed - * callback method if it needs to take action when connectivity with - * the Glacier2 router is lost. - * - * A program can contain only one instance of this class. - * \headerfile Glacier2/Glacier2.h - **/ -class GLACIER2_API Application : public Ice::Application -{ -public: - - /** - * Initializes an instance that calls Ice::Communicator::shutdown if - * a signal is received. - **/ - Application(Ice::SignalPolicy = Ice::ICE_ENUM(SignalPolicy,HandleSignals)); - -#ifdef ICE_CPP11_MAPPING - Application(const Application&) = delete; - Application& operator=(const Application&) = delete; -#endif - - /** - * Creates a new Glacier2 session. A call to - * <code>createSession</code> always precedes a call to - * <code>runWithSession</code>. If <code>Ice::LocalException</code> - * is thrown from this method, the application is terminated. - * @return The Glacier2 session. - **/ - virtual Glacier2::SessionPrxPtr createSession() = 0; - - /** - * Called once the communicator has been initialized and the Glacier2 session - * has been established. A derived class must implement <code>runWithSession</code>, - * which is the application's starting method. - * - * @param argc The number of elements in argv. - * - * @param argv The argument vector for the application. <code>Application</code> - * scans the argument vector passed to <code>main</code> for options that are - * specific to the Ice run time and removes them; therefore, the vector passed - * to <code>run</code> is free from Ice-related options and contains only options - * and arguments that are application-specific. - * - * @return The <code>runWithSession</code> method should return zero for successful - * termination, and non-zero otherwise. <code>Application.main</code> returns the - * value returned by <code>runWithSession</code>. - **/ - virtual int runWithSession(int argc, char* argv[]) = 0; - - /** - * Called when the session refresh thread detects that the session has been - * destroyed. A subclass can override this method to take action after the - * loss of connectivity with the Glacier2 router. This method is called - * according to the Ice invocation dipsatch rules (in other words, it - * uses the same rules as an servant upcall or AMI callback). - **/ - virtual void sessionDestroyed(); - - /** - * Called to restart the application's Glacier2 session. This - * method never returns. The exception produce an application restart - * when called from the Application main thread. - * - * @throws RestartSessionException This exception is always thrown. - **/ - static void restart(); - - /** - * Returns the Glacier2 router proxy - * @return The router proxy. - **/ - static Glacier2::RouterPrxPtr router(); - - /** - * Returns the Glacier2 session proxy - * @return The session proxy. - **/ - static Glacier2::SessionPrxPtr session(); - - /** - * Returns the category to be used in the identities of all of the client's - * callback objects. Clients must use this category for the router to - * forward callback requests to the intended client. - * @return The category. - * @throws SessionNotExistException No session exists. - **/ - static std::string categoryForClient(); - - /** - * Create a new Ice identity for callback objects with the given - * identity name field. - * @return The identity. - **/ - static Ice::Identity createCallbackIdentity(const std::string&); - - /** - * Adds a servant to the callback object adapter's Active Servant Map with a UUID. - * @param servant The servant to add. - * @return The proxy for the servant. - **/ - static Ice::ObjectPrxPtr addWithUUID(const Ice::ObjectPtr& servant); - - /** - * Creates an object adapter for callback objects. - * @return The object adapter. - */ - static Ice::ObjectAdapterPtr objectAdapter(); - -protected: - - /** - * Helper function that implements the application logic. - */ - virtual int doMain(int argc, char* argv[], const Ice::InitializationData& initData, int version); - -private: - - bool doMain(Ice::StringSeq&, const Ice::InitializationData&, int&, int); - - // - // Run should not be overridden for Glacier2::Application. Instead - // runWithSession should be used. - // - int run(int, char*[]) - { - // This shouldn't be called. - assert(false); - return 0; - } - - static Ice::ObjectAdapterPtr _adapter; - static Glacier2::RouterPrxPtr _router; - static Glacier2::SessionPrxPtr _session; - static std::string _category; -}; - -} - -#endif diff --git a/cpp/src/Glacier2/Blobject.cpp b/cpp/src/Glacier2/Blobject.cpp index 3ee669ff860..cc99f2bbd06 100644 --- a/cpp/src/Glacier2/Blobject.cpp +++ b/cpp/src/Glacier2/Blobject.cpp @@ -16,8 +16,6 @@ namespace const string serverForwardContext = "Glacier2.Server.ForwardContext"; const string clientForwardContext = "Glacier2.Client.ForwardContext"; -const string serverAlwaysBatch = "Glacier2.Server.AlwaysBatch"; -const string clientAlwaysBatch = "Glacier2.Client.AlwaysBatch"; const string serverTraceRequest = "Glacier2.Server.Trace.Request"; const string clientTraceRequest = "Glacier2.Client.Trace.Request"; const string serverTraceOverride = "Glacier2.Server.Trace.Override"; @@ -25,16 +23,13 @@ const string clientTraceOverride = "Glacier2.Client.Trace.Override"; } -Glacier2::Blobject::Blobject(const InstancePtr& instance, const ConnectionPtr& reverseConnection, +Glacier2::Blobject::Blobject(shared_ptr<Instance> instance, shared_ptr<Connection> reverseConnection, const Context& context) : - _instance(instance), - _reverseConnection(reverseConnection), + _instance(move(instance)), + _reverseConnection(move(reverseConnection)), _forwardContext(_reverseConnection ? _instance->properties()->getPropertyAsInt(serverForwardContext) > 0 : _instance->properties()->getPropertyAsInt(clientForwardContext) > 0), - _alwaysBatch(_reverseConnection ? - _instance->properties()->getPropertyAsInt(serverAlwaysBatch) > 0 : - _instance->properties()->getPropertyAsInt(clientAlwaysBatch) > 0), _requestTraceLevel(_reverseConnection ? _instance->properties()->getPropertyAsInt(serverTraceRequest) : _instance->properties()->getPropertyAsInt(clientTraceRequest)), @@ -43,18 +38,15 @@ Glacier2::Blobject::Blobject(const InstancePtr& instance, const ConnectionPtr& r _instance->properties()->getPropertyAsInt(clientTraceOverride)), _context(context) { - RequestQueueThreadPtr t = _reverseConnection ? _instance->serverRequestQueueThread() : - _instance->clientRequestQueueThread(); + auto t = _reverseConnection ? _instance->serverRequestQueueThread() : _instance->clientRequestQueueThread(); if(t) { - const_cast<RequestQueuePtr&>(_requestQueue) = new RequestQueue(t, _instance, _reverseConnection); + const_cast<shared_ptr<RequestQueue>&>(_requestQueue) = make_shared<RequestQueue>(t, + _instance, + _reverseConnection); } } -Glacier2::Blobject::~Blobject() -{ -} - void Glacier2::Blobject::destroy() { @@ -65,7 +57,7 @@ Glacier2::Blobject::destroy() } void -Glacier2::Blobject::updateObserver(const Glacier2::Instrumentation::SessionObserverPtr& observer) +Glacier2::Blobject::updateObserver(const shared_ptr<Glacier2::Instrumentation::SessionObserver>& observer) { if(_requestQueue) { @@ -74,32 +66,11 @@ Glacier2::Blobject::updateObserver(const Glacier2::Instrumentation::SessionObser } void -Glacier2::Blobject::invokeResponse(bool ok, const pair<const Byte*, const Byte*>& outParams, - const AMD_Object_ice_invokePtr& amdCB) -{ - amdCB->ice_response(ok, outParams); -} - -void -Glacier2::Blobject::invokeSent(bool, const AMD_Object_ice_invokePtr& amdCB) -{ -#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) - amdCB->ice_response(true, pair<const Byte*, const Byte*>(static_cast<const Byte*>(nullptr), - static_cast<const Byte*>(nullptr))); -#else - amdCB->ice_response(true, pair<const Byte*, const Byte*>(0, 0)); -#endif -} - -void -Glacier2::Blobject::invokeException(const Exception& ex, const AMD_Object_ice_invokePtr& amdCB) -{ - amdCB->ice_exception(ex); -} - -void -Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amdCB, - const std::pair<const Byte*, const Byte*>& inParams, const Current& current) +Glacier2::Blobject::invoke(shared_ptr<ObjectPrx>& proxy, + const std::pair<const Byte*, const Byte*>& inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> exception, + const Current& current) { // // Set the correct facet on the proxy. @@ -115,14 +86,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amd // if(current.requestId == 0) { - if(_alwaysBatch && _requestQueue) - { - proxy = proxy->ice_batchOneway(); - } - else - { - proxy = proxy->ice_oneway(); - } + proxy = proxy->ice_oneway(); } else if(current.requestId > 0) { @@ -148,53 +112,27 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amd case 'o': { - if(_alwaysBatch && _requestQueue) - { - proxy = proxy->ice_batchOneway(); - } - else - { - proxy = proxy->ice_oneway(); - } + proxy = proxy->ice_oneway(); break; } case 'd': { - if(_alwaysBatch && _requestQueue) - { - proxy = proxy->ice_batchDatagram(); - } - else - { - proxy = proxy->ice_datagram(); - } + proxy = proxy->ice_datagram(); break; } case 'O': { - if(_requestQueue) - { - proxy = proxy->ice_batchOneway(); - } - else - { - proxy = proxy->ice_oneway(); - } + // Batch support has been removed. These requests will be forwarded as oneway + proxy = proxy->ice_oneway(); break; } case 'D': { - if(_requestQueue) - { - proxy = proxy->ice_batchDatagram(); - } - else - { - proxy = proxy->ice_datagram(); - } + // Batch support has been removed. These requests will be forwarded as datagram + proxy = proxy->ice_datagram(); break; } @@ -268,12 +206,12 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amd bool override; try { - override = _requestQueue->addRequest(new Request(proxy, inParams, current, _forwardContext, _context, - amdCB)); + override = _requestQueue->addRequest(make_shared<Request>(proxy, inParams, current, _forwardContext, + _context, move(response), exception)); } - catch(const ObjectNotExistException& ex) + catch(const ObjectNotExistException&) { - amdCB->ice_exception(ex); + exception(current_exception()); return; } @@ -309,21 +247,24 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amd else { // - // If we are in not in buffered mode, we send the request - // directly. + // If we are in not in buffered mode, we send the request directly. // - assert(!proxy->ice_isBatchOneway() && !proxy->ice_isBatchDatagram()); try { - Callback_Object_ice_invokePtr amiCB; + function<void(bool, pair<const Byte*, const Byte*>)> amiResponse = nullptr; + function<void(bool)> amiSent = nullptr; + if(proxy->ice_isTwoway()) { - amiCB = newCallback_Object_ice_invoke(this, &Blobject::invokeResponse, &Blobject::invokeException); + amiResponse = move(response); } else { - amiCB = newCallback_Object_ice_invoke(this, &Blobject::invokeException, &Blobject::invokeSent); + amiSent = [amdResponse = move(response)](bool) + { + amdResponse(true, {nullptr, nullptr}); + }; } if(_forwardContext) @@ -332,28 +273,32 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amd { Context ctx = current.ctx; ctx.insert(_context.begin(), _context.end()); - proxy->begin_ice_invoke(current.operation, current.mode, inParams, ctx, amiCB, amdCB); + proxy->ice_invokeAsync(current.operation, current.mode, inParams, + move(amiResponse), move(exception), move(amiSent), ctx); } else { - proxy->begin_ice_invoke(current.operation, current.mode, inParams, current.ctx, amiCB, amdCB); + proxy->ice_invokeAsync(current.operation, current.mode, inParams, + move(amiResponse), move(exception), move(amiSent), current.ctx); } } else { if(_context.size() > 0) { - proxy->begin_ice_invoke(current.operation, current.mode, inParams, _context, amiCB, amdCB); + proxy->ice_invokeAsync(current.operation, current.mode, inParams, + move(amiResponse), move(exception), move(amiSent), _context); } else { - proxy->begin_ice_invoke(current.operation, current.mode, inParams, amiCB, amdCB); + proxy->ice_invokeAsync(current.operation, current.mode, inParams, + move(amiResponse), move(exception), move(amiSent)); } } } - catch(const LocalException& ex) + catch(const LocalException&) { - amdCB->ice_exception(ex); + exception(current_exception()); } } } diff --git a/cpp/src/Glacier2/Blobject.h b/cpp/src/Glacier2/Blobject.h index c6d049704a3..824bbf3eff2 100644 --- a/cpp/src/Glacier2/Blobject.h +++ b/cpp/src/Glacier2/Blobject.h @@ -12,37 +12,35 @@ namespace Glacier2 { -class Blobject : public Ice::BlobjectArrayAsync +class Blobject : public Ice::BlobjectArrayAsync, public std::enable_shared_from_this<Blobject> { public: - Blobject(const InstancePtr&, const Ice::ConnectionPtr&, const Ice::Context&); - virtual ~Blobject(); + Blobject(std::shared_ptr<Instance>, std::shared_ptr<Ice::Connection>, const Ice::Context&); void destroy(); - virtual void updateObserver(const Glacier2::Instrumentation::SessionObserverPtr&); + virtual void updateObserver(const std::shared_ptr<Instrumentation::SessionObserver>&); - void invokeResponse(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&, - const Ice::AMD_Object_ice_invokePtr&); - void invokeSent(bool, const Ice::AMD_Object_ice_invokePtr&); - void invokeException(const Ice::Exception&, const Ice::AMD_Object_ice_invokePtr&); + void invokeException(std::exception_ptr, std::function<void(std::exception_ptr)>&&); protected: - void invoke(Ice::ObjectPrx&, const Ice::AMD_Object_ice_invokePtr&, - const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); + void invoke(std::shared_ptr<Ice::ObjectPrx>&, + const std::pair<const Ice::Byte*, const Ice::Byte*>&, + std::function<void(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&)>, + std::function<void(std::exception_ptr)>, + const Ice::Current&); - const InstancePtr _instance; - const Ice::ConnectionPtr _reverseConnection; + const std::shared_ptr<Instance> _instance; + const std::shared_ptr<Ice::Connection> _reverseConnection; private: const bool _forwardContext; - const bool _alwaysBatch; const int _requestTraceLevel; const int _overrideTraceLevel; - const RequestQueuePtr _requestQueue; + const std::shared_ptr<RequestQueue> _requestQueue; const Ice::Context _context; }; diff --git a/cpp/src/Glacier2/ClientBlobject.cpp b/cpp/src/Glacier2/ClientBlobject.cpp index cb074674a99..02230df64df 100644 --- a/cpp/src/Glacier2/ClientBlobject.cpp +++ b/cpp/src/Glacier2/ClientBlobject.cpp @@ -4,33 +4,30 @@ #include <Glacier2/ClientBlobject.h> #include <Glacier2/FilterManager.h> -#include <Glacier2/FilterI.h> +#include <Glacier2/FilterT.h> #include <Glacier2/RoutingTable.h> using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::ClientBlobject::ClientBlobject(const InstancePtr& instance, - const FilterManagerPtr& filters, +Glacier2::ClientBlobject::ClientBlobject(shared_ptr<Instance>instance, + shared_ptr<FilterManager> filters, const Ice::Context& sslContext, - const RoutingTablePtr& routingTable): + shared_ptr<RoutingTable>routingTable): - Glacier2::Blobject(instance, 0, sslContext), - _routingTable(routingTable), - _filters(filters), + Glacier2::Blobject(move(instance), nullptr, sslContext), + _routingTable(move(routingTable)), + _filters(move(filters)), _rejectTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")) { } -Glacier2::ClientBlobject::~ClientBlobject() -{ -} - void -Glacier2::ClientBlobject::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCB, - const std::pair<const Byte*, const Byte*>& inParams, - const Current& current) +Glacier2::ClientBlobject::ice_invokeAsync(pair<const Byte*, const Byte*> inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, + const Current& current) { bool matched = false; bool hasFilters = false; @@ -72,7 +69,7 @@ Glacier2::ClientBlobject::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& } } - ObjectPrx proxy = _routingTable->get(current.id); + auto proxy = _routingTable->get(current.id); if(!proxy) { // @@ -115,22 +112,23 @@ Glacier2::ClientBlobject::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& throw ObjectNotExistException(__FILE__, __LINE__, current.id, "", ""); } - invoke(proxy, amdCB, inParams, current); + + invoke(proxy, inParams, move(response), move(error), current); } -StringSetPtr +shared_ptr<StringSet> ClientBlobject::categories() { return _filters->categories(); } -StringSetPtr +shared_ptr<StringSet> ClientBlobject::adapterIds() { return _filters->adapterIds(); } -IdentitySetPtr +shared_ptr<IdentitySet> ClientBlobject::identities() { return _filters->identities(); diff --git a/cpp/src/Glacier2/ClientBlobject.h b/cpp/src/Glacier2/ClientBlobject.h index abc6e87fd66..f098e1cd62a 100644 --- a/cpp/src/Glacier2/ClientBlobject.h +++ b/cpp/src/Glacier2/ClientBlobject.h @@ -11,35 +11,32 @@ namespace Glacier2 { -class RoutingTable; -typedef IceUtil::Handle<RoutingTable> RoutingTablePtr; - -class ClientBlobject; -typedef IceUtil::Handle<ClientBlobject> ClientBlobjectPtr; - class FilterManager; -typedef IceUtil::Handle<FilterManager> FilterManagerPtr; +class RoutingTable; -class ClientBlobject : public Glacier2::Blobject +class ClientBlobject final : public Glacier2::Blobject { public: - ClientBlobject(const InstancePtr&, const FilterManagerPtr&, const Ice::Context&, const RoutingTablePtr&); - virtual ~ClientBlobject(); + ClientBlobject(std::shared_ptr<Instance>, std::shared_ptr<FilterManager>, const Ice::Context&, + std::shared_ptr<RoutingTable>); - virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, - const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); + void ice_invokeAsync(std::pair<const Ice::Byte*, const Ice::Byte*> inEncaps, + std::function<void(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&)> response, + std::function<void(std::exception_ptr)> error, + const Ice::Current& current) override; - StringSetPtr categories(); - StringSetPtr adapterIds(); - IdentitySetPtr identities(); + std::shared_ptr<StringSet> categories(); + std::shared_ptr<StringSet> adapterIds(); + std::shared_ptr<IdentitySet> identities(); private: - const RoutingTablePtr _routingTable; - const FilterManagerPtr _filters; + const std::shared_ptr<RoutingTable> _routingTable; + const std::shared_ptr<FilterManager> _filters; const int _rejectTraceLevel; }; + } #endif diff --git a/cpp/src/Glacier2/FilterI.cpp b/cpp/src/Glacier2/FilterI.cpp deleted file mode 100644 index 987efab6484..00000000000 --- a/cpp/src/Glacier2/FilterI.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include <Ice/Properties.h> -#include <Ice/Communicator.h> -#include <Glacier2/FilterI.h> diff --git a/cpp/src/Glacier2/FilterManager.cpp b/cpp/src/Glacier2/FilterManager.cpp index 67dfca80d6e..c17c126b272 100644 --- a/cpp/src/Glacier2/FilterManager.cpp +++ b/cpp/src/Glacier2/FilterManager.cpp @@ -8,7 +8,7 @@ #include <IceUtil/IceUtil.h> #include <IceUtil/StringUtil.h> #include <Glacier2/FilterManager.h> -#include <Glacier2/FilterI.h> +#include <Glacier2/FilterT.h> using namespace std; using namespace Ice; @@ -105,7 +105,7 @@ Glacier2::FilterManager::~FilterManager() void Glacier2::FilterManager::destroy() { - Ice::ObjectAdapterPtr adapter = _instance->serverObjectAdapter(); + auto adapter = _instance->serverObjectAdapter(); if(adapter) { try @@ -141,22 +141,22 @@ Glacier2::FilterManager::destroy() } } -Glacier2::FilterManager::FilterManager(const InstancePtr& instance, const Glacier2::StringSetIPtr& categories, - const Glacier2::StringSetIPtr& adapters, - const Glacier2::IdentitySetIPtr& identities) : - _categories(categories), - _adapters(adapters), - _identities(identities), - _instance(instance) +Glacier2::FilterManager::FilterManager(shared_ptr<Instance> instance, shared_ptr<Glacier2::StringSetI> categories, + shared_ptr<Glacier2::StringSetI> adapters, + shared_ptr<Glacier2::IdentitySetI> identities) : + _categories(move(categories)), + _adapters(move(adapters)), + _identities(move(identities)), + _instance(move(instance)) { try { - Ice::ObjectAdapterPtr adapter = _instance->serverObjectAdapter(); + auto adapter = _instance->serverObjectAdapter(); if(adapter) { - _categoriesPrx = Glacier2::StringSetPrx::uncheckedCast(adapter->addWithUUID(_categories)); - _adapterIdsPrx = Glacier2::StringSetPrx::uncheckedCast(adapter->addWithUUID(_adapters)); - _identitiesPrx = Glacier2::IdentitySetPrx::uncheckedCast(adapter->addWithUUID(_identities)); + _categoriesPrx = Ice::uncheckedCast<Glacier2::StringSetPrx>(adapter->addWithUUID(_categories)); + _adapterIdsPrx = Ice::uncheckedCast<Glacier2::StringSetPrx>(adapter->addWithUUID(_adapters)); + _identitiesPrx = Ice::uncheckedCast<Glacier2::IdentitySetPrx>(adapter->addWithUUID(_identities)); } } catch(...) @@ -166,10 +166,10 @@ Glacier2::FilterManager::FilterManager(const InstancePtr& instance, const Glacie } } -Glacier2::FilterManagerPtr -Glacier2::FilterManager::create(const InstancePtr& instance, const string& userId, const bool allowAddUser) +shared_ptr<Glacier2::FilterManager> +Glacier2::FilterManager::create(shared_ptr<Instance> instance, const string& userId, bool allowAddUser) { - PropertiesPtr props = instance->properties(); + auto props = instance->properties(); string allow = props->getProperty("Glacier2.Filter.Category.Accept"); vector<string> allowSeq; stringToSeq(allow, allowSeq); @@ -194,14 +194,15 @@ Glacier2::FilterManager::create(const InstancePtr& instance, const string& userI } } } - Glacier2::StringSetIPtr categoryFilter = new Glacier2::StringSetI(allowSeq); + + auto categoryFilter = make_shared<Glacier2::StringSetI>(allowSeq); // // TODO: refactor initialization of filters. // allow = props->getProperty("Glacier2.Filter.AdapterId.Accept"); stringToSeq(allow, allowSeq); - Glacier2::StringSetIPtr adapterIdFilter = new Glacier2::StringSetI(allowSeq); + auto adapterIdFilter = make_shared<Glacier2::StringSetI>(allowSeq); // // TODO: Object id's from configurations? @@ -209,7 +210,7 @@ Glacier2::FilterManager::create(const InstancePtr& instance, const string& userI IdentitySeq allowIdSeq; allow = props->getProperty("Glacier2.Filter.Identity.Accept"); stringToSeq(allow, allowIdSeq); - Glacier2::IdentitySetIPtr identityFilter = new Glacier2::IdentitySetI(allowIdSeq); + auto identityFilter = make_shared<Glacier2::IdentitySetI>(allowIdSeq); - return new Glacier2::FilterManager(instance, categoryFilter, adapterIdFilter, identityFilter); + return make_shared<Glacier2::FilterManager>(move(instance), move(categoryFilter), move(adapterIdFilter), move(identityFilter)); } diff --git a/cpp/src/Glacier2/FilterManager.h b/cpp/src/Glacier2/FilterManager.h index 3537ee2c93a..a3af12a949a 100644 --- a/cpp/src/Glacier2/FilterManager.h +++ b/cpp/src/Glacier2/FilterManager.h @@ -10,74 +10,73 @@ // this is the most expeditious approach for now. // #include <Glacier2/Instance.h> -#include <Glacier2/FilterI.h> +#include <Glacier2/FilterT.h> #include <Ice/ObjectAdapter.h> namespace Glacier2 { -class FilterManager; -typedef IceUtil::Handle<FilterManager> FilterManagerPtr; - -class FilterManager : public IceUtil::Shared +class FilterManager { public: + FilterManager(std::shared_ptr<Instance>, + std::shared_ptr<StringSetI>, + std::shared_ptr<StringSetI>, + std::shared_ptr<IdentitySetI>); virtual ~FilterManager(); void destroy(); - StringSetIPtr + std::shared_ptr<StringSetI> categories() const { return _categories; } - StringSetIPtr + std::shared_ptr<StringSetI> adapterIds() const { return _adapters; } - IdentitySetIPtr + std::shared_ptr<IdentitySetI> identities() const { return _identities; } - StringSetPrx + std::shared_ptr<StringSetPrx> categoriesPrx() const { return _categoriesPrx; } - StringSetPrx + std::shared_ptr<StringSetPrx> adapterIdsPrx() const { return _adapterIdsPrx; } - IdentitySetPrx + std::shared_ptr<IdentitySetPrx> identitiesPrx() const { return _identitiesPrx; } - static FilterManagerPtr - create(const InstancePtr&, const std::string&, const bool); + static std::shared_ptr<FilterManager> + create(std::shared_ptr<Instance>, const std::string&, bool); private: - StringSetPrx _categoriesPrx; - StringSetPrx _adapterIdsPrx; - IdentitySetPrx _identitiesPrx; - - const StringSetIPtr _categories; - const StringSetIPtr _adapters; - const IdentitySetIPtr _identities; - const InstancePtr _instance; + std::shared_ptr<StringSetPrx> _categoriesPrx; + std::shared_ptr<StringSetPrx> _adapterIdsPrx; + std::shared_ptr<IdentitySetPrx> _identitiesPrx; - FilterManager(const InstancePtr& , const StringSetIPtr&, const StringSetIPtr&, const IdentitySetIPtr&); -}; + const std::shared_ptr<StringSetI> _categories; + const std::shared_ptr<StringSetI> _adapters; + const std::shared_ptr<IdentitySetI> _identities; + const std::shared_ptr<Instance> _instance; }; +} #endif /* FILTER_MANAGER_H */ diff --git a/cpp/src/Glacier2/FilterI.h b/cpp/src/Glacier2/FilterT.h index e9c79e952f6..078d174f192 100644 --- a/cpp/src/Glacier2/FilterI.h +++ b/cpp/src/Glacier2/FilterT.h @@ -7,38 +7,28 @@ #include <Glacier2/Session.h> #include <Ice/Identity.h> + +#include <list> +#include <mutex> #include <string> #include <vector> -#include <list> - -#ifdef _MSC_VER -# pragma warning(disable:4505) // unreferenced local function has been removed -#endif namespace Glacier2 { template <typename T, class P> -class FilterT : public P, public IceUtil::Monitor<IceUtil::Mutex> +class FilterT : public P { public: - // - // These typedefs are a compiler workaround for GCC and iterators - // depending on nested templates. - // - typedef typename std::vector<T>::const_iterator const_iterator; - typedef typename std::vector<T>::iterator iterator; - typedef typename std::list<iterator>::iterator literator; - FilterT(const std::vector<T>&); // // Slice to C++ mapping. // - virtual void add(const std::vector<T>&, const Ice::Current&); - virtual void remove(const std::vector<T>&, const Ice::Current&); - virtual std::vector<T> get(const Ice::Current&); + virtual void add(std::vector<T>, const Ice::Current&) override; + virtual void remove(std::vector<T>, const Ice::Current&) override; + virtual std::vector<T> get(const Ice::Current&) override; // // Internal functions. @@ -46,7 +36,7 @@ public: bool match(const T& candidate) const { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + std::lock_guard<std::mutex> lg(_mutex); // // Empty vectors mean no filtering, so all matches will succeed. // @@ -61,13 +51,15 @@ public: bool empty() const { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + std::lock_guard<std::mutex> lg(_mutex); return _items.size() == 0; } private: std::vector<T> _items; + + mutable std::mutex _mutex; }; template<class T, class P> @@ -79,7 +71,7 @@ FilterT<T, P>::FilterT(const std::vector<T>& accept): } template<class T, class P> void -FilterT<T, P>::add(const std::vector<T>& additions, const Ice::Current&) +FilterT<T, P>::add(std::vector<T> additions, const Ice::Current&) { // // Sort the filter elements first, erasing duplicates. Then we can @@ -89,7 +81,7 @@ FilterT<T, P>::add(const std::vector<T>& additions, const Ice::Current&) sort(newItems.begin(), newItems.end()); newItems.erase(unique(newItems.begin(), newItems.end()), newItems.end()); - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + std::lock_guard<std::mutex> lg(_mutex); std::vector<T> merged(_items.size() + newItems.size()); merge(newItems.begin(), newItems.end(), _items.begin(), _items.end(), merged.begin()); merged.erase(unique(merged.begin(), merged.end()), merged.end()); @@ -97,7 +89,7 @@ FilterT<T, P>::add(const std::vector<T>& additions, const Ice::Current&) } template<class T, class P> void -FilterT<T, P>::remove(const std::vector<T>& deletions, const Ice::Current&) +FilterT<T, P>::remove(std::vector<T> deletions, const Ice::Current&) { // // Our removal algorithm depends on the filter elements to be @@ -107,7 +99,7 @@ FilterT<T, P>::remove(const std::vector<T>& deletions, const Ice::Current&) sort(toRemove.begin(), toRemove.end()); toRemove.erase(unique(toRemove.begin(), toRemove.end()), toRemove.end()); - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + std::lock_guard<std::mutex> lg(_mutex); // // Our vectors are both sorted, so if we keep track of our first @@ -117,18 +109,13 @@ FilterT<T, P>::remove(const std::vector<T>& deletions, const Ice::Current&) // itemwise. // - // - // The presence of the 'typename' is a GCC specific workaround. The - // iterator types apparently resolve to a 'void' in GCC type - // causing compiler errors. - // - const_iterator r = toRemove.begin(); - iterator mark = _items.begin(); - std::list<iterator> deleteList; + typename std::vector<T>::const_iterator r = toRemove.begin(); + typename std::vector<T>::iterator mark = _items.begin(); + std::list<typename std::vector<T>::iterator> deleteList; while(r != toRemove.end()) { - iterator i = mark; + typename std::vector<T>::iterator i = mark; while(i != _items.end() && r != toRemove.end()) { if(*r == *i) @@ -155,25 +142,22 @@ FilterT<T, P>::remove(const std::vector<T>& deletions, const Ice::Current&) ++r; } - for(literator i = deleteList.begin(); i != deleteList.end(); ++i) + for(const auto& item : deleteList) { - _items.erase(*i); + _items.erase(item); } } template<class T, class P> std::vector<T> FilterT<T, P>::get(const Ice::Current&) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + std::lock_guard<std::mutex> lg(_mutex); return _items; } -typedef FilterT<Ice::Identity, Glacier2::IdentitySet> IdentitySetI; -typedef IceUtil::Handle< FilterT<Ice::Identity, Glacier2::IdentitySet> > IdentitySetIPtr; +using IdentitySetI = FilterT<Ice::Identity, Glacier2::IdentitySet>; +using StringSetI = FilterT<std::string, Glacier2::StringSet>; -typedef FilterT<std::string, Glacier2::StringSet> StringSetI; -typedef IceUtil::Handle< FilterT<std::string, Glacier2::StringSet> > StringSetIPtr; - -}; +} #endif diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp index f608a86c3f7..902ca190edc 100644 --- a/cpp/src/Glacier2/Glacier2Router.cpp +++ b/cpp/src/Glacier2/Glacier2Router.cpp @@ -4,7 +4,6 @@ #include <Ice/UUID.h> #include <IceUtil/Options.h> -#include <IceUtil/FileUtil.h> #include <Ice/ConsoleUtil.h> #include <Ice/Service.h> #include <Glacier2/Instance.h> @@ -17,10 +16,69 @@ using namespace std; using namespace Ice; using namespace Glacier2; using namespace IceInternal; - namespace { +class ClientLocator final : public ServantLocator +{ +public: + + ClientLocator(shared_ptr<SessionRouterI> sessionRouter) : + _sessionRouter(move(sessionRouter)) + { + } + + shared_ptr<Object> + locate(const Current& current, shared_ptr<void>&) override + { + return _sessionRouter->getClientBlobject(current.con, current.id); + } + + void + finished(const Current&, const shared_ptr<Object>&, const shared_ptr<void>&) override + { + } + + void + deactivate(const string&) override + { + } + +private: + + const shared_ptr<SessionRouterI> _sessionRouter; +}; + +class ServerLocator final : public ServantLocator +{ +public: + + ServerLocator(shared_ptr<SessionRouterI> sessionRouter) : + _sessionRouter(move(sessionRouter)) + { + } + + shared_ptr<Object> + locate(const Current& current, shared_ptr<void>&) override + { + return _sessionRouter->getServerBlobject(current.id.category); + } + + void + finished(const Current&, const shared_ptr<Object>&, const shared_ptr<void>&) override + { + } + + void + deactivate(const string&) override + { + } + +private: + + const std::shared_ptr<SessionRouterI> _sessionRouter; +}; + class RouterService : public Service { public: @@ -29,35 +87,35 @@ public: protected: - virtual bool start(int, char*[], int&); - virtual bool stop(); - virtual CommunicatorPtr initializeCommunicator(int&, char*[], const InitializationData&, int); + bool start(int, char*[], int&) override; + bool stop() override; + shared_ptr<Communicator> initializeCommunicator(int&, char*[], const InitializationData&, int) override; private: void usage(const std::string&); - Glacier2::InstancePtr _instance; - SessionRouterIPtr _sessionRouter; + shared_ptr<Glacier2::Instance> _instance; + shared_ptr<SessionRouterI> _sessionRouter; }; class FinderI : public Ice::RouterFinder { public: - FinderI(const Glacier2::RouterPrx& router) : _router(router) + FinderI(shared_ptr<Glacier2::RouterPrx> router) : _router(move(router)) { } - virtual Ice::RouterPrx - getRouter(const Ice::Current&) + shared_ptr<Ice::RouterPrx> + getRouter(const Ice::Current&) override { return _router; } private: - const Glacier2::RouterPrx _router; + const shared_ptr<Glacier2::RouterPrx> _router; }; }; @@ -79,7 +137,7 @@ RouterService::start(int argc, char* argv[], int& status) vector<string> args; try { - args = opts.parse(argc, const_cast<const char**>(argv)); + args = opts.parse(argc, argv); } catch(const IceUtilInternal::BadOptException& e) { @@ -109,7 +167,7 @@ RouterService::start(int argc, char* argv[], int& status) return false; } - PropertiesPtr properties = communicator()->getProperties(); + auto properties = communicator()->getProperties(); // // Initialize the client object adapter. @@ -121,27 +179,19 @@ RouterService::start(int argc, char* argv[], int& status) return false; } - if(properties->getPropertyAsInt("Glacier2.SessionTimeout") > 0 && - properties->getProperty("Glacier2.Client.ACM.Timeout").empty()) - { - ostringstream os; - os << properties->getPropertyAsInt("Glacier2.SessionTimeout"); - properties->setProperty("Glacier2.Client.ACM.Timeout", os.str()); - } - if(properties->getProperty("Glacier2.Client.ACM.Close").empty()) { properties->setProperty("Glacier2.Client.ACM.Close", "4"); // Forcefull close on invocation and idle. } - ObjectAdapterPtr clientAdapter = communicator()->createObjectAdapter("Glacier2.Client"); + auto clientAdapter = communicator()->createObjectAdapter("Glacier2.Client"); // // Initialize the server object adapter only if server endpoints // are defined. // const string serverEndpointsProperty = "Glacier2.Server.Endpoints"; - ObjectAdapterPtr serverAdapter; + shared_ptr<ObjectAdapter> serverAdapter; if(!properties->getProperty(serverEndpointsProperty).empty()) { serverAdapter = communicator()->createObjectAdapter("Glacier2.Server"); @@ -156,8 +206,8 @@ RouterService::start(int argc, char* argv[], int& status) Glacier2Internal::setupNullPermissionsVerifier(communicator(), instanceName, verifierProperties); string verifierProperty = verifierProperties[0]; - PermissionsVerifierPrx verifier; - ObjectPrx obj; + shared_ptr<PermissionsVerifierPrx> verifier; + shared_ptr<ObjectPrx> obj; try { // @@ -178,7 +228,7 @@ RouterService::start(int argc, char* argv[], int& status) { try { - verifier = PermissionsVerifierPrx::checkedCast(obj); + verifier = Ice::checkedCast<PermissionsVerifierPrx>(obj); if(!verifier) { ServiceError err(this); @@ -195,7 +245,7 @@ RouterService::start(int argc, char* argv[], int& status) warn << "unable to contact permissions verifier `" << communicator()->getProperties()->getProperty(verifierProperty) << "'\n" << ex; } - verifier = PermissionsVerifierPrx::uncheckedCast(obj); + verifier = Ice::uncheckedCast<PermissionsVerifierPrx>(obj); } } @@ -204,7 +254,7 @@ RouterService::start(int argc, char* argv[], int& status) // string sessionManagerProperty = "Glacier2.SessionManager"; string sessionManagerPropertyValue = properties->getProperty(sessionManagerProperty); - SessionManagerPrx sessionManager; + shared_ptr<SessionManagerPrx> sessionManager; if(!sessionManagerPropertyValue.empty()) { try @@ -219,7 +269,7 @@ RouterService::start(int argc, char* argv[], int& status) } try { - sessionManager = SessionManagerPrx::checkedCast(obj); + sessionManager = Ice::checkedCast<SessionManagerPrx>(obj); if(!sessionManager) { error("session manager `" + sessionManagerPropertyValue + "' is invalid"); @@ -233,10 +283,10 @@ RouterService::start(int argc, char* argv[], int& status) ServiceWarning warn(this); warn << "unable to contact session manager `" << sessionManagerPropertyValue << "'\n" << ex; } - sessionManager = SessionManagerPrx::uncheckedCast(obj); + sessionManager = Ice::uncheckedCast<SessionManagerPrx>(obj); } sessionManager = - SessionManagerPrx::uncheckedCast(sessionManager->ice_connectionCached(false)->ice_locatorCacheTimeout( + Ice::uncheckedCast<SessionManagerPrx>(sessionManager->ice_connectionCached(false)->ice_locatorCacheTimeout( properties->getPropertyAsIntWithDefault("Glacier2.SessionManager.LocatorCacheTimeout", 600))); } @@ -244,7 +294,7 @@ RouterService::start(int argc, char* argv[], int& status) // Check for an SSL permissions verifier. // string sslVerifierProperty = verifierProperties[1]; - SSLPermissionsVerifierPrx sslVerifier; + shared_ptr<SSLPermissionsVerifierPrx> sslVerifier; try { @@ -262,7 +312,7 @@ RouterService::start(int argc, char* argv[], int& status) { try { - sslVerifier = SSLPermissionsVerifierPrx::checkedCast(obj); + sslVerifier = Ice::checkedCast<SSLPermissionsVerifierPrx>(obj); if(!sslVerifier) { ServiceError err(this); @@ -280,7 +330,7 @@ RouterService::start(int argc, char* argv[], int& status) << communicator()->getProperties()->getProperty(sslVerifierProperty) << "'\n" << ex; } - sslVerifier = SSLPermissionsVerifierPrx::uncheckedCast(obj); + sslVerifier = Ice::uncheckedCast<SSLPermissionsVerifierPrx>(obj); } } @@ -289,7 +339,7 @@ RouterService::start(int argc, char* argv[], int& status) // string sslSessionManagerProperty = "Glacier2.SSLSessionManager"; string sslSessionManagerPropertyValue = properties->getProperty(sslSessionManagerProperty); - SSLSessionManagerPrx sslSessionManager; + shared_ptr<SSLSessionManagerPrx> sslSessionManager; if(!sslSessionManagerPropertyValue.empty()) { try @@ -304,7 +354,7 @@ RouterService::start(int argc, char* argv[], int& status) } try { - sslSessionManager = SSLSessionManagerPrx::checkedCast(obj); + sslSessionManager = Ice::checkedCast<SSLSessionManagerPrx>(obj); if(!sslSessionManager) { error("ssl session manager `" + sslSessionManagerPropertyValue + "' is invalid"); @@ -319,10 +369,10 @@ RouterService::start(int argc, char* argv[], int& status) warn << "unable to contact ssl session manager `" << sslSessionManagerPropertyValue << "'\n" << ex; } - sslSessionManager = SSLSessionManagerPrx::uncheckedCast(obj); + sslSessionManager = Ice::uncheckedCast<SSLSessionManagerPrx>(obj); } sslSessionManager = - SSLSessionManagerPrx::uncheckedCast(sslSessionManager->ice_connectionCached(false)->ice_locatorCacheTimeout( + Ice::uncheckedCast<SSLSessionManagerPrx>(sslSessionManager->ice_connectionCached(false)->ice_locatorCacheTimeout( properties->getPropertyAsIntWithDefault("Glacier2.SSLSessionManager.LocatorCacheTimeout", 600))); } @@ -337,7 +387,7 @@ RouterService::start(int argc, char* argv[], int& status) // try { - _instance = new Glacier2::Instance(communicator(), clientAdapter, serverAdapter); + _instance = make_shared<Glacier2::Instance>(communicator(), clientAdapter, serverAdapter); } catch(const Ice::InitializationException& ex) { @@ -345,30 +395,48 @@ RouterService::start(int argc, char* argv[], int& status) return false; } + _sessionRouter = make_shared<SessionRouterI>(_instance, move(verifier), move(sessionManager), move(sslVerifier), + move(sslSessionManager)); + // - // Create the session router. The session router registers itself - // and all required servant locators, so no registration has to be - // done here. + // Registers session router and all required servant locators // - _sessionRouter = new SessionRouterI(_instance, verifier, sessionManager, sslVerifier, sslSessionManager); + try + { + // + // All other calls on the client object adapter are dispatched to + // a router servant based on connection information. + // + _instance->clientObjectAdapter()->addServantLocator(make_shared<ClientLocator>(_sessionRouter), ""); + + // + // 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(_instance->serverObjectAdapter()) + { + _instance->serverObjectAdapter()->addServantLocator(make_shared<ServerLocator>(_sessionRouter), ""); + } + } + catch(const Ice::ObjectAdapterDeactivatedException&) + { + // Ignore. + } + + _instance->setSessionRouter(_sessionRouter); // - // Th session router is used directly as servant for the main + // The session router is used directly as a servant for the main // Glacier2 router Ice object. // - Identity routerId; - routerId.category = instanceName; - routerId.name = "router"; - Glacier2::RouterPrx routerPrx = Glacier2::RouterPrx::uncheckedCast(clientAdapter->add(_sessionRouter, routerId)); + auto routerPrx = Ice::uncheckedCast<Glacier2::RouterPrx>(clientAdapter->add(_sessionRouter, {"router", instanceName})); // // Add the Ice router finder object to allow retrieving the router // proxy with just the endpoint information of the router. // - Identity finderId; - finderId.category = "Ice"; - finderId.name = "RouterFinder"; - clientAdapter->add(new FinderI(routerPrx), finderId); + clientAdapter->add(make_shared<FinderI>(routerPrx), {"RouterFinder", "Ice"}); if(_instance->getObserver()) { @@ -406,22 +474,22 @@ RouterService::stop() if(_sessionRouter) { _sessionRouter->destroy(); - _sessionRouter = 0; + _sessionRouter = nullptr; } if(_instance) { if(_instance->getObserver()) { - _instance->getObserver()->setObserverUpdater(0); + _instance->getObserver()->setObserverUpdater(nullptr); } _instance->destroy(); - _instance = 0; + _instance = nullptr; } return true; } -CommunicatorPtr +shared_ptr<Communicator> RouterService::initializeCommunicator(int& argc, char* argv[], const InitializationData& initializationData, int version) diff --git a/cpp/src/Glacier2/Instance.cpp b/cpp/src/Glacier2/Instance.cpp index 3d6d7cf4404..d9e1db9e790 100644 --- a/cpp/src/Glacier2/Instance.cpp +++ b/cpp/src/Glacier2/Instance.cpp @@ -20,64 +20,39 @@ const string clientBuffered = "Glacier2.Client.Buffered"; } -Glacier2::Instance::Instance(const Ice::CommunicatorPtr& communicator, const Ice::ObjectAdapterPtr& clientAdapter, - const Ice::ObjectAdapterPtr& serverAdapter) : - _communicator(communicator), - _properties(communicator->getProperties()), - _logger(communicator->getLogger()), - _clientAdapter(clientAdapter), - _serverAdapter(serverAdapter) +Glacier2::Instance::Instance(shared_ptr<Ice::Communicator> communicator, shared_ptr<Ice::ObjectAdapter> clientAdapter, + shared_ptr<Ice::ObjectAdapter> serverAdapter) : + _communicator(move(communicator)), + _properties(_communicator->getProperties()), + _logger(_communicator->getLogger()), + _clientAdapter(move(clientAdapter)), + _serverAdapter(move(serverAdapter)), + _proxyVerifier(make_shared<ProxyVerifier>(_communicator)) { - if(_properties->getPropertyAsIntWithDefault(serverBuffered, 1) > 0) + if(_properties->getPropertyAsIntWithDefault(serverBuffered, 0) > 0) { - IceUtil::Time sleepTime = IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(serverSleepTime)); - const_cast<RequestQueueThreadPtr&>(_serverRequestQueueThread) = new RequestQueueThread(sleepTime); - try - { - _serverRequestQueueThread->start(); - } - catch(const IceUtil::Exception&) - { - _serverRequestQueueThread->destroy(); - throw; - } + auto sleepTime = chrono::milliseconds(_properties->getPropertyAsInt(serverSleepTime)); + const_cast<shared_ptr<RequestQueueThread>&>(_serverRequestQueueThread) = make_shared<RequestQueueThread>(sleepTime); } - if(_properties->getPropertyAsIntWithDefault(clientBuffered, 1) > 0) + if(_properties->getPropertyAsIntWithDefault(clientBuffered, 0) > 0) { - IceUtil::Time sleepTime = IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(clientSleepTime)); - const_cast<RequestQueueThreadPtr&>(_clientRequestQueueThread) = new RequestQueueThread(sleepTime); - try - { - _clientRequestQueueThread->start(); - } - catch(const IceUtil::Exception&) - { - _clientRequestQueueThread->destroy(); - throw; - } + auto sleepTime = chrono::milliseconds(_properties->getPropertyAsInt(clientSleepTime)); + const_cast<shared_ptr<RequestQueueThread>&>(_clientRequestQueueThread) = make_shared<RequestQueueThread>(sleepTime); } - const_cast<ProxyVerifierPtr&>(_proxyVerifier) = new ProxyVerifier(communicator); - // - // If an Ice metrics observer is setup on the communicator, also - // enable metrics for IceStorm. + // If an Ice metrics observer is setup on the communicator, also enable metrics for Glacier2. // - IceInternal::CommunicatorObserverIPtr o = - IceInternal::CommunicatorObserverIPtr::dynamicCast(communicator->getObserver()); + auto o = dynamic_pointer_cast<IceInternal::CommunicatorObserverI>(_communicator->getObserver()); if(o) { - const_cast<Glacier2::Instrumentation::RouterObserverPtr&>(_observer) = - new RouterObserverI(o->getFacet(), - _properties->getPropertyWithDefault("Glacier2.InstanceName", "Glacier2")); + const_cast<shared_ptr<Instrumentation::RouterObserver>&>(_observer) = + make_shared<RouterObserverI>(o->getFacet(), + _properties->getPropertyWithDefault("Glacier2.InstanceName", "Glacier2")); } } -Glacier2::Instance::~Instance() -{ -} - void Glacier2::Instance::destroy() { @@ -91,11 +66,12 @@ Glacier2::Instance::destroy() _serverRequestQueueThread->destroy(); } - const_cast<SessionRouterIPtr&>(_sessionRouter) = 0; + _sessionRouter = nullptr; } void -Glacier2::Instance::setSessionRouter(const SessionRouterIPtr& sessionRouter) +Glacier2::Instance::setSessionRouter(shared_ptr<SessionRouterI> sessionRouter) { - const_cast<SessionRouterIPtr&>(_sessionRouter) = sessionRouter; + assert(_sessionRouter == nullptr); + _sessionRouter = move(sessionRouter); } diff --git a/cpp/src/Glacier2/Instance.h b/cpp/src/Glacier2/Instance.h index 514272222ab..309cc50640d 100644 --- a/cpp/src/Glacier2/Instance.h +++ b/cpp/src/Glacier2/Instance.h @@ -8,7 +8,6 @@ #include <Ice/CommunicatorF.h> #include <Ice/ObjectAdapterF.h> #include <Ice/PropertiesF.h> -#include <IceUtil/Time.h> #include <Glacier2/RequestQueue.h> #include <Glacier2/ProxyVerifier.h> @@ -18,45 +17,43 @@ namespace Glacier2 { -class Instance : public IceUtil::Shared +class Instance { public: - Instance(const Ice::CommunicatorPtr&, const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&); - ~Instance(); + Instance(std::shared_ptr<Ice::Communicator>, std::shared_ptr<Ice::ObjectAdapter>, + std::shared_ptr<Ice::ObjectAdapter>); - Ice::CommunicatorPtr communicator() const { return _communicator; } - Ice::ObjectAdapterPtr clientObjectAdapter() const { return _clientAdapter; } - Ice::ObjectAdapterPtr serverObjectAdapter() const { return _serverAdapter; } - Ice::PropertiesPtr properties() const { return _properties; } - Ice::LoggerPtr logger() const { return _logger; } + std::shared_ptr<Ice::Communicator> communicator() const { return _communicator; } + std::shared_ptr<Ice::ObjectAdapter> clientObjectAdapter() const { return _clientAdapter; } + std::shared_ptr<Ice::ObjectAdapter> serverObjectAdapter() const { return _serverAdapter; } + std::shared_ptr<Ice::Properties> properties() const { return _properties; } + std::shared_ptr<Ice::Logger> logger() const { return _logger; } - RequestQueueThreadPtr clientRequestQueueThread() const { return _clientRequestQueueThread; } - RequestQueueThreadPtr serverRequestQueueThread() const { return _serverRequestQueueThread; } - ProxyVerifierPtr proxyVerifier() const { return _proxyVerifier; } - SessionRouterIPtr sessionRouter() const { return _sessionRouter; } + std::shared_ptr<RequestQueueThread> clientRequestQueueThread() const { return _clientRequestQueueThread; } + std::shared_ptr<RequestQueueThread> serverRequestQueueThread() const { return _serverRequestQueueThread; } + std::shared_ptr<ProxyVerifier> proxyVerifier() const { return _proxyVerifier; } + std::shared_ptr<SessionRouterI> sessionRouter() const { return _sessionRouter; } - const Glacier2::Instrumentation::RouterObserverPtr& getObserver() const { return _observer; } + const std::shared_ptr<Glacier2::Instrumentation::RouterObserver>& getObserver() const { return _observer; } + + void setSessionRouter(std::shared_ptr<SessionRouterI>); void destroy(); private: - friend class SessionRouterI; - void setSessionRouter(const SessionRouterIPtr&); - - const Ice::CommunicatorPtr _communicator; - const Ice::PropertiesPtr _properties; - const Ice::LoggerPtr _logger; - const Ice::ObjectAdapterPtr _clientAdapter; - const Ice::ObjectAdapterPtr _serverAdapter; - const RequestQueueThreadPtr _clientRequestQueueThread; - const RequestQueueThreadPtr _serverRequestQueueThread; - const ProxyVerifierPtr _proxyVerifier; - const SessionRouterIPtr _sessionRouter; - const Glacier2::Instrumentation::RouterObserverPtr _observer; + const std::shared_ptr<Ice::Communicator> _communicator; + const std::shared_ptr<Ice::Properties> _properties; + const std::shared_ptr<Ice::Logger> _logger; + const std::shared_ptr<Ice::ObjectAdapter> _clientAdapter; + const std::shared_ptr<Ice::ObjectAdapter> _serverAdapter; + const std::shared_ptr<RequestQueueThread> _clientRequestQueueThread; + const std::shared_ptr<RequestQueueThread> _serverRequestQueueThread; + const std::shared_ptr<ProxyVerifier> _proxyVerifier; + std::shared_ptr<SessionRouterI> _sessionRouter; + const std::shared_ptr<Glacier2::Instrumentation::RouterObserver> _observer; }; -typedef IceUtil::Handle<Instance> InstancePtr; } // End namespace Glacier2 diff --git a/cpp/src/Glacier2/InstrumentationI.cpp b/cpp/src/Glacier2/InstrumentationI.cpp index d02f8e1f2fc..5996ef508b8 100644 --- a/cpp/src/Glacier2/InstrumentationI.cpp +++ b/cpp/src/Glacier2/InstrumentationI.cpp @@ -35,17 +35,17 @@ public: }; static Attributes attributes; - SessionHelper(const string& instanceName, const string& id, const ::Ice::ConnectionPtr& connection, int rtSize) : - _instanceName(instanceName), _id(id), _connection(connection), _routingTableSize(rtSize) + SessionHelper(const string& instanceName, const string& id, shared_ptr<Ice::Connection> connection, int rtSize) : + _instanceName(instanceName), _id(id), _connection(move(connection)), _routingTableSize(rtSize) { } - virtual string operator()(const string& attribute) const + string operator()(const string& attribute) const override { return attributes(this, attribute); } - virtual void initMetrics(const SessionMetricsPtr& v) const + void initMetrics(const shared_ptr<SessionMetrics>& v) const override { v->routingTableSize += _routingTableSize; } @@ -60,25 +60,25 @@ public: return _id; } - ::Ice::ConnectionInfoPtr + shared_ptr<Ice::ConnectionInfo> getConnectionInfo() const { return _connection->getInfo(); } - ::Ice::EndpointPtr + shared_ptr<Ice::Endpoint> getEndpoint() const { return _connection->getEndpoint(); } - const ::Ice::ConnectionPtr& + const shared_ptr<Ice::Connection>& getConnection() const { return _connection; } - const ::Ice::EndpointInfoPtr& + shared_ptr<Ice::EndpointInfo> getEndpointInfo() const { if(!_endpointInfo) @@ -92,9 +92,9 @@ private: const string& _instanceName; const string& _id; - const ::Ice::ConnectionPtr& _connection; + const shared_ptr<Ice::Connection>& _connection; const int _routingTableSize; - mutable ::Ice::EndpointInfoPtr _endpointInfo; + mutable shared_ptr<Ice::EndpointInfo> _endpointInfo; }; SessionHelper::Attributes SessionHelper::attributes; @@ -108,7 +108,7 @@ struct ForwardedUpdate { } - void operator()(const SessionMetricsPtr& v) + void operator()(const shared_ptr<SessionMetrics>& v) { if(client) { @@ -173,22 +173,22 @@ SessionObserverI::routingTableSize(int delta) forEach(add(&SessionMetrics::routingTableSize, delta)); } -RouterObserverI::RouterObserverI(const IceInternal::MetricsAdminIPtr& metrics, const string& instanceName) : - _metrics(metrics), _instanceName(instanceName), _sessions(metrics, "Session") +RouterObserverI::RouterObserverI(shared_ptr<IceInternal::MetricsAdminI> metrics, const string& instanceName) : + _metrics(move(metrics)), _instanceName(instanceName), _sessions(_metrics, "Session") { } void -RouterObserverI::setObserverUpdater(const ObserverUpdaterPtr& updater) +RouterObserverI::setObserverUpdater(const shared_ptr<ObserverUpdater>& updater) { _sessions.setUpdater(newUpdater(updater, &ObserverUpdater::updateSessionObservers)); } -SessionObserverPtr +shared_ptr<SessionObserver> RouterObserverI::getSessionObserver(const string& id, - const ::Ice::ConnectionPtr& connection, + const shared_ptr<Ice::Connection>& connection, int routingTableSize, - const SessionObserverPtr& old) + const shared_ptr<SessionObserver>& old) { if(_sessions.isEnabled()) { @@ -198,7 +198,7 @@ RouterObserverI::getSessionObserver(const string& id, } catch(const exception& ex) { - ::Ice::Error error(_metrics->getLogger()); + Ice::Error error(_metrics->getLogger()); error << "unexpected exception trying to obtain observer:\n" << ex; } } diff --git a/cpp/src/Glacier2/InstrumentationI.h b/cpp/src/Glacier2/InstrumentationI.h index d75f346a485..0631d46bdb5 100644 --- a/cpp/src/Glacier2/InstrumentationI.h +++ b/cpp/src/Glacier2/InstrumentationI.h @@ -13,37 +13,37 @@ namespace Glacier2 { -class SessionObserverI : public Glacier2::Instrumentation::SessionObserver, - public IceMX::ObserverT<IceMX::SessionMetrics> +class SessionObserverI final : public Glacier2::Instrumentation::SessionObserver, + public IceMX::ObserverT<IceMX::SessionMetrics> { public: - virtual void forwarded(bool); - virtual void queued(bool); - virtual void overridden(bool); - virtual void routingTableSize(int); + void forwarded(bool) override; + void queued(bool) override; + void overridden(bool) override; + void routingTableSize(int) override; }; -class RouterObserverI : public Glacier2::Instrumentation::RouterObserver +class RouterObserverI final : public Glacier2::Instrumentation::RouterObserver { public: - RouterObserverI(const IceInternal::MetricsAdminIPtr&, const std::string&); + RouterObserverI(std::shared_ptr<IceInternal::MetricsAdminI>, const std::string&); - virtual void setObserverUpdater(const Glacier2::Instrumentation::ObserverUpdaterPtr&); + void setObserverUpdater(const std::shared_ptr<Glacier2::Instrumentation::ObserverUpdater>&) override; - virtual Glacier2::Instrumentation::SessionObserverPtr getSessionObserver( - const std::string&, const Ice::ConnectionPtr&, int, const Glacier2::Instrumentation::SessionObserverPtr&); + std::shared_ptr<Glacier2::Instrumentation::SessionObserver> getSessionObserver(const std::string&, + const std::shared_ptr<Ice::Connection>&, int, + const std::shared_ptr<Glacier2::Instrumentation::SessionObserver>&) override; private: - const IceInternal::MetricsAdminIPtr _metrics; + const std::shared_ptr<IceInternal::MetricsAdminI> _metrics; const std::string _instanceName; IceMX::ObserverFactoryT<SessionObserverI> _sessions; }; -typedef IceUtil::Handle<RouterObserverI> RouterObserverIPtr; -}; +} #endif diff --git a/cpp/src/Glacier2/ProxyVerifier.cpp b/cpp/src/Glacier2/ProxyVerifier.cpp index cf80795a78e..50e90f546e8 100644 --- a/cpp/src/Glacier2/ProxyVerifier.cpp +++ b/cpp/src/Glacier2/ProxyVerifier.cpp @@ -101,28 +101,23 @@ class AddressMatcher { public: virtual ~AddressMatcher() {} - virtual bool match(const string&, string::size_type& pos) = 0; + virtual bool match(const string&, string::size_type& pos) = 0; virtual const char* toString() const = 0; - -protected: }; -class MatchesAny : public AddressMatcher +class MatchesAny final : public AddressMatcher { public: - MatchesAny() - { - } bool - match(const string&, string::size_type&) + match(const string&, string::size_type&) override { return true; } const char* - toString() const + toString() const override { return "(ANY)"; } @@ -133,7 +128,7 @@ public: // string starts with a set of characters followed by a wildcard or // numeric range. // -class StartsWithString : public AddressMatcher +class StartsWithString final : public AddressMatcher { public: StartsWithString(const string& criteria): @@ -143,7 +138,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { assert(pos == 0); bool result = strncmp(space.c_str(), _criteria.c_str(), _criteria.size()) == 0; @@ -155,7 +150,7 @@ public: } const char* - toString() const + toString() const override { return _description.c_str(); } @@ -169,7 +164,7 @@ private: // Match the end portion of a string. Occurs when a filter string starts // with a wildcard or numeric range, but ends with a string. // -class EndsWithString : public AddressMatcher +class EndsWithString final : public AddressMatcher { public: EndsWithString(const string& criteria): @@ -179,7 +174,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { if(space.size() - pos < _criteria.size()) { @@ -198,8 +193,8 @@ public: return true; } - virtual const char* - toString() const + const char* + toString() const override { return _description.c_str(); } @@ -209,7 +204,7 @@ private: string _description; }; -class MatchesString : public AddressMatcher +class MatchesString final : public AddressMatcher { public: MatchesString(const string& criteria): @@ -219,7 +214,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { if(strncmp(space.c_str(), _criteria.c_str(), _criteria.size()) == 0) { @@ -229,8 +224,8 @@ public: return false; } - virtual const char* - toString() const + const char* + toString() const override { return _description.c_str(); } @@ -244,7 +239,7 @@ private: // Match against somewhere within a string. Occurs when a filter // contains a string bounded by wildcards, or numeric ranges. e.g. *bar*.com. // -class ContainsString : public AddressMatcher +class ContainsString final : public AddressMatcher { public: ContainsString(const string& criteria): @@ -254,7 +249,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { string::size_type offset = space.find(_criteria, pos); if(offset == string::npos) @@ -265,8 +260,8 @@ public: return true; } - virtual const char* - toString() const + const char* + toString() const override { return _description.c_str(); } @@ -334,8 +329,8 @@ public: _description = ostr.str(); } - bool - match(const string & space, string::size_type& pos) + virtual bool + match(const string & space, string::size_type& pos) override { istringstream istr(space.substr(pos)); int val; @@ -366,7 +361,7 @@ public: } virtual const char* - toString() const + toString() const override { return _description.c_str(); } @@ -380,7 +375,7 @@ private: // // Occurs when a numeric range is preceded by a wildcard. // -class ContainsNumberMatch : public MatchesNumber +class ContainsNumberMatch final : public MatchesNumber { public: ContainsNumberMatch(const vector<int>& values, const vector<Range>& ranges): @@ -389,7 +384,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { while(true) { @@ -408,7 +403,7 @@ public: } }; -class EndsWithNumber : public MatchesNumber +class EndsWithNumber final : public MatchesNumber { public: EndsWithNumber(const vector<int>& values, const vector<Range>& ranges): @@ -417,7 +412,7 @@ public: } bool - match(const string& space, string::size_type& pos) + match(const string& space, string::size_type& pos) override { pos = space.find_last_not_of("0123456789", pos); if(pos == space.size()-1) @@ -440,7 +435,6 @@ public: class AddressMatcherFactory { public: - virtual ~AddressMatcherFactory() {} virtual AddressMatcher* create(const string& criteria) = 0; @@ -449,65 +443,65 @@ public: create(const vector<int>& ports, const vector<Range>& ranges) = 0; }; -class StartFactory : public AddressMatcherFactory +class StartFactory final : public AddressMatcherFactory { public: AddressMatcher* - create(const string& criteria) + create(const string& criteria) override { return new StartsWithString(criteria); } AddressMatcher* - create(const vector<int>& ports, const vector<Range>& ranges) + create(const vector<int>& ports, const vector<Range>& ranges) override { return new MatchesNumber(ports, ranges); } }; -class WildCardFactory : public AddressMatcherFactory +class WildCardFactory final : public AddressMatcherFactory { public: AddressMatcher* - create(const string& criteria) + create(const string& criteria) override { return new ContainsString(criteria); } AddressMatcher* - create(const vector<int>& ports, const vector<Range>& ranges) + create(const vector<int>& ports, const vector<Range>& ranges) override { return new ContainsNumberMatch(ports, ranges); } }; -class FollowingFactory : public AddressMatcherFactory +class FollowingFactory final : public AddressMatcherFactory { public: AddressMatcher* - create(const string& criteria) + create(const string& criteria) override { return new MatchesString(criteria); } AddressMatcher* - create(const vector<int>& ports, const vector<Range>& ranges) + create(const vector<int>& ports, const vector<Range>& ranges) override { return new MatchesNumber(ports, ranges); } }; -class EndsWithFactory : public AddressMatcherFactory +class EndsWithFactory final : public AddressMatcherFactory { public: AddressMatcher* - create(const string& criteria) + create(const string& criteria) override { return new EndsWithString(criteria); } AddressMatcher* - create(const vector<int>& ports, const vector<Range>& ranges) + create(const vector<int>& ports, const vector<Range>& ranges) override { return new EndsWithNumber(ports, ranges); } @@ -516,19 +510,19 @@ public: // // A proxy validation rule encapsulating an address filter. // -class AddressRule : public Glacier2::ProxyRule +class AddressRule final : public Glacier2::ProxyRule { public: - AddressRule(const CommunicatorPtr& communicator, const vector<AddressMatcher*>& address, MatchesNumber* port, + AddressRule(shared_ptr<Communicator> communicator, const vector<AddressMatcher*>& address, MatchesNumber* port, const int traceLevel) : - _communicator(communicator), + _communicator(move(communicator)), _addressRules(address), _portMatcher(port), _traceLevel(traceLevel) { } - ~AddressRule() + ~AddressRule() override { for(vector<AddressMatcher*>::const_iterator i = _addressRules.begin(); i != _addressRules.end(); ++i) { @@ -537,18 +531,17 @@ public: delete _portMatcher; } - virtual bool - check(const ObjectPrx& prx) const + bool + check(const shared_ptr<ObjectPrx>& prx) const override { EndpointSeq endpoints = prx->ice_getEndpoints(); if(endpoints.size() == 0) { return false; } - - for(EndpointSeq::const_iterator i = endpoints.begin(); i != endpoints.end(); ++i) + for(const auto& endpoint : endpoints) { - string info = (*i)->toString(); + string info = endpoint->toString(); string host; if(!extractPart("-h ", info, host)) { @@ -572,24 +565,25 @@ public: } pos = 0; - for(vector<AddressMatcher*>::const_iterator j = _addressRules.begin(); j != _addressRules.end(); ++j) + for(const auto& rule : _addressRules) { - if(!(*j)->match(host, pos)) + if(!rule->match(host, pos)) { if(_traceLevel >= 3) { Trace out(_communicator->getLogger(), "Glacier2"); - out << (*j)->toString() << " failed to match " << host << " at pos=" << pos << "\n"; + out << rule->toString() << " failed to match " << host << " at pos=" << pos << "\n"; } return false; } if(_traceLevel >= 3) { Trace out(_communicator->getLogger(), "Glacier2"); - out << (*j)->toString() << " matched " << host << " at pos=" << pos << "\n"; + out << rule->toString() << " matched " << host << " at pos=" << pos << "\n"; } } } + return true; } @@ -597,9 +591,9 @@ public: dump() const { consoleErr << "address("; - for(vector<AddressMatcher*>::const_iterator i = _addressRules.begin(); i != _addressRules.end(); ++i) + for(const auto& rule : _addressRules) { - consoleErr << (*i)->toString() << " "; + consoleErr << rule->toString() << " "; } if(_portMatcher != 0) { @@ -631,14 +625,14 @@ private: return true; } - CommunicatorPtr _communicator; + const shared_ptr<Communicator> _communicator; vector<AddressMatcher*> _addressRules; MatchesNumber* _portMatcher; const int _traceLevel; }; static void -parseProperty(const Ice::CommunicatorPtr& communicator, const string& property, vector<ProxyRule*>& rules, +parseProperty(const shared_ptr<Ice::Communicator>& communicator, const string& property, vector<ProxyRule*>& rules, const int traceLevel) { StartFactory startsWithFactory; @@ -803,7 +797,7 @@ parseProperty(const Ice::CommunicatorPtr& communicator, const string& property, // Helper function for checking a rule set. // static bool -match(const vector<ProxyRule*>& rules, const ObjectPrx& proxy) +match(const vector<ProxyRule*>& rules, const shared_ptr<ObjectPrx>& proxy) { for(vector<ProxyRule*>::const_iterator i = rules.begin(); i != rules.end(); ++i) { @@ -822,8 +816,8 @@ match(const vector<ProxyRule*>& rules, const ObjectPrx& proxy) class ProxyLengthRule : public ProxyRule { public: - ProxyLengthRule(const CommunicatorPtr communicator, const string& count, int traceLevel) : - _communicator(communicator), + ProxyLengthRule(shared_ptr<Communicator> communicator, const string& count, int traceLevel) : + _communicator(move(communicator)), _traceLevel(traceLevel) { istringstream s(count); @@ -838,7 +832,7 @@ public: } bool - check(const ObjectPrx& p) const + check(const shared_ptr<ObjectPrx>& p) const override { string s = p->ice_toString(); bool result = (s.size() > _count); @@ -852,27 +846,27 @@ public: } private: - const CommunicatorPtr _communicator; + const shared_ptr<Communicator> _communicator; const int _traceLevel; unsigned long _count; }; } // End proxy rule implementations. -Glacier2::ProxyVerifier::ProxyVerifier(const CommunicatorPtr& communicator): - _communicator(communicator), - _traceLevel(communicator->getProperties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")) +Glacier2::ProxyVerifier::ProxyVerifier(shared_ptr<Communicator> communicator): + _communicator(move(communicator)), + _traceLevel(_communicator->getProperties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")) { // // Evaluation order is dependant on how the rules are stored to the // rules vectors. // - string s = communicator->getProperties()->getProperty("Glacier2.Filter.Address.Accept"); + string s = _communicator->getProperties()->getProperty("Glacier2.Filter.Address.Accept"); if(s != "") { try { - Glacier2::parseProperty(communicator, s, _acceptRules, _traceLevel); + Glacier2::parseProperty(_communicator, s, _acceptRules, _traceLevel); } catch(const exception& ex) { @@ -882,12 +876,12 @@ Glacier2::ProxyVerifier::ProxyVerifier(const CommunicatorPtr& communicator): } } - s = communicator->getProperties()->getProperty("Glacier2.Filter.Address.Reject"); + s = _communicator->getProperties()->getProperty("Glacier2.Filter.Address.Reject"); if(s != "") { try { - Glacier2::parseProperty(communicator, s, _rejectRules, _traceLevel); + Glacier2::parseProperty(_communicator, s, _rejectRules, _traceLevel); } catch(const exception& ex) { @@ -897,12 +891,12 @@ Glacier2::ProxyVerifier::ProxyVerifier(const CommunicatorPtr& communicator): } } - s = communicator->getProperties()->getProperty("Glacier2.Filter.ProxySizeMax"); + s = _communicator->getProperties()->getProperty("Glacier2.Filter.ProxySizeMax"); if(s != "") { try { - _rejectRules.push_back(new ProxyLengthRule(communicator, s, _traceLevel)); + _rejectRules.push_back(new ProxyLengthRule(_communicator, s, _traceLevel)); } catch(const exception& ex) @@ -927,7 +921,7 @@ Glacier2::ProxyVerifier::~ProxyVerifier() } bool -Glacier2::ProxyVerifier::verify(const ObjectPrx& proxy) +Glacier2::ProxyVerifier::verify(const shared_ptr<ObjectPrx>& proxy) { // // No rules have been defined so we accept all. diff --git a/cpp/src/Glacier2/ProxyVerifier.h b/cpp/src/Glacier2/ProxyVerifier.h index b20d835ee2d..be8882bd9e2 100644 --- a/cpp/src/Glacier2/ProxyVerifier.h +++ b/cpp/src/Glacier2/ProxyVerifier.h @@ -24,31 +24,30 @@ public: // // Checks to see if the proxy passes. // - virtual bool check(const Ice::ObjectPrx&) const = 0; + virtual bool check(const std::shared_ptr<Ice::ObjectPrx>&) const = 0; }; -class ProxyVerifier : public IceUtil::Shared +class ProxyVerifier final { public: - ProxyVerifier(const Ice::CommunicatorPtr&); + ProxyVerifier(std::shared_ptr<Ice::Communicator>); ~ProxyVerifier(); // // Verifies that the proxy is permissible under the configured // rules. // - bool verify(const Ice::ObjectPrx&); + bool verify(const std::shared_ptr<Ice::ObjectPrx>&); private: - const Ice::CommunicatorPtr _communicator; + const std::shared_ptr<Ice::Communicator> _communicator; const int _traceLevel; std::vector<ProxyRule*> _acceptRules; std::vector<ProxyRule*> _rejectRules; }; -typedef IceUtil::Handle<ProxyVerifier> ProxyVerifierPtr; } #endif diff --git a/cpp/src/Glacier2/RequestQueue.cpp b/cpp/src/Glacier2/RequestQueue.cpp index 51dc1387289..9e7e2c7153b 100644 --- a/cpp/src/Glacier2/RequestQueue.cpp +++ b/cpp/src/Glacier2/RequestQueue.cpp @@ -10,15 +10,17 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::Request::Request(const ObjectPrx& proxy, const std::pair<const Byte*, const Byte*>& inParams, - const Current& current, bool forwardContext, const Ice::Context& sslContext, - const AMD_Object_ice_invokePtr& amdCB) : - _proxy(proxy), +Glacier2::Request::Request(shared_ptr<ObjectPrx> proxy, const std::pair<const Byte*, const Byte*>& inParams, + const Current& current, bool forwardContext, const Ice::Context& sslContext, + function<void(bool, pair<const Byte*, const Byte*>)> response, + function<void(exception_ptr)> exception) : + _proxy(move(proxy)), _inParams(inParams.first, inParams.second), _current(current), _forwardContext(forwardContext), _sslContext(sslContext), - _amdCB(amdCB) + _response(move(response)), + _exception(move(exception)) { Context::const_iterator p = current.ctx.find("_ovrd"); if(p != current.ctx.end()) @@ -28,96 +30,53 @@ Glacier2::Request::Request(const ObjectPrx& proxy, const std::pair<const Byte*, } void -Glacier2::Request::addBatchProxy(set<Ice::ObjectPrx>& batchProxies) -{ - set<Ice::ObjectPrx>::const_iterator p = batchProxies.find(_proxy); - if(p == batchProxies.end()) - { - batchProxies.insert(_proxy); - } - else if(p->get() != _proxy.get()) - { - const_cast<Ice::ObjectPrx&>(_proxy) = *p; - } -} - -Ice::AsyncResultPtr -Glacier2::Request::invoke(const Callback_Object_ice_invokePtr& cb) +Glacier2::Request::invoke(function<void(bool, pair<const Byte*, const Byte*>)>&& response, + function<void(exception_ptr)>&& exception, + std::function<void(bool)>&& sent) { pair<const Byte*, const Byte*> inPair; if(_inParams.size() == 0) { - inPair.first = inPair.second = 0; + inPair.first = inPair.second = nullptr; } else { - inPair.first = &_inParams[0]; + inPair.first = _inParams.data(); inPair.second = inPair.first + _inParams.size(); } - if(_proxy->ice_isBatchOneway() || _proxy->ice_isBatchDatagram()) + if(_forwardContext) { - ByteSeq outParams; - if(_forwardContext) + if(_sslContext.size() > 0) { - if(_sslContext.size() > 0) - { - Ice::Context ctx = _current.ctx; - ctx.insert(_sslContext.begin(), _sslContext.end()); - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, ctx); - } - else - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _current.ctx); - } + Ice::Context ctx = _current.ctx; + ctx.insert(_sslContext.begin(), _sslContext.end()); + _proxy->ice_invokeAsync(_current.operation, _current.mode, inPair, + move(response), move(exception), move(sent), ctx); } else { - if(_sslContext.size() > 0) - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _sslContext); - } - else - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams); - } + _proxy->ice_invokeAsync(_current.operation, _current.mode, inPair, + move(response), move(exception), move(sent), _current.ctx); } - return 0; } else { - Ice::AsyncResultPtr result; - if(_forwardContext) + if(_sslContext.size() > 0) { - if(_sslContext.size() > 0) - { - Ice::Context ctx = _current.ctx; - ctx.insert(_sslContext.begin(), _sslContext.end()); - result = _proxy->begin_ice_invoke(_current.operation, _current.mode, inPair, ctx, cb, this); - } - else - { - result = _proxy->begin_ice_invoke(_current.operation, _current.mode, inPair, _current.ctx, cb, this); - } + _proxy->ice_invokeAsync(_current.operation, _current.mode, inPair, + move(response), move(exception), move(sent), _sslContext); } else { - if(_sslContext.size() > 0) - { - result = _proxy->begin_ice_invoke(_current.operation, _current.mode, inPair, _sslContext, cb, this); - } - else - { - result = _proxy->begin_ice_invoke(_current.operation, _current.mode, inPair, cb, this); - } + _proxy->ice_invokeAsync(_current.operation, _current.mode, inPair, + move(response), move(exception), move(sent)); } - - return result; } } bool -Glacier2::Request::override(const RequestPtr& other) const +Glacier2::Request::override(const shared_ptr<Request>& other) const { // // Both override values have to be non-empty. @@ -147,26 +106,25 @@ Glacier2::Request::override(const RequestPtr& other) const // // We cannot override if the proxies differ. // - return _proxy == other->_proxy; + return Ice::targetEqualTo(_proxy, other->_proxy); } void -Glacier2::Request::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& outParams) +Glacier2::Request::response(bool ok, const pair<const Byte*, const Byte*>& outParams) { assert(_proxy->ice_isTwoway()); - _amdCB->ice_response(ok, outParams); + _response(ok, outParams); } void -Glacier2::Request::exception(const Ice::Exception& ex) +Glacier2::Request::exception(exception_ptr ex) { // - // Only for twoways, oneway or batch oneway dispatches are finished - // when queued, see queued(). + // Only for twoways, oneway dispatches are finished when queued, see queued(). // if(_proxy->ice_isTwoway()) { - _amdCB->ice_exception(ex); + _exception(ex); } } @@ -175,77 +133,60 @@ Glacier2::Request::queued() { if(!_proxy->ice_isTwoway()) { -#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) - _amdCB->ice_response(true, pair<const Byte*, const Byte*>(static_cast<const Byte*>(nullptr), - static_cast<const Byte*>(nullptr))); -#else - _amdCB->ice_response(true, pair<const Byte*, const Byte*>(0, 0)); -#endif + _response(true, { nullptr, nullptr }); } } -Glacier2::RequestQueue::RequestQueue(const RequestQueueThreadPtr& requestQueueThread, - const InstancePtr& instance, - const Ice::ConnectionPtr& connection) : - _requestQueueThread(requestQueueThread), - _instance(instance), - _connection(connection), - _callback(newCallback_Object_ice_invoke(this, &RequestQueue::response, &RequestQueue::exception, - &RequestQueue::sent)), - _flushCallback(newCallback_Connection_flushBatchRequests(this, &RequestQueue::exception, &RequestQueue::sent)), +Glacier2::RequestQueue::RequestQueue(shared_ptr<RequestQueueThread> requestQueueThread, + shared_ptr<Instance> instance, + shared_ptr<Ice::Connection> connection) : + _requestQueueThread(move(requestQueueThread)), + _instance(move(instance)), + _connection(move(connection)), _pendingSend(false), _destroyed(false) { } bool -Glacier2::RequestQueue::addRequest(const RequestPtr& request) +Glacier2::RequestQueue::addRequest(shared_ptr<Request> request) { - IceUtil::Mutex::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(_destroyed) { throw Ice::ObjectNotExistException(__FILE__, __LINE__); } + if(request->hasOverride()) { - for(deque<RequestPtr>::iterator p = _requests.begin(); p != _requests.end(); ++p) + for(auto& r : _requests) { // // If the new request overrides an old one, then abort the old // request and replace it with the new request. // - if(request->override(*p)) + if(request->override(r)) { if(_observer) { _observer->overridden(!_connection); } request->queued(); - *p = request; + r = move(request); return true; } } } - if(!_connection) - { - // - // If it's a batch request, we make sure we use a unique batch proxy object for the queued - // batch requests. We want all the requests for the same batch proxy to be queued on the - // same proxy object. - // - request->addBatchProxy(_batchProxies); - } - // // No override, we add the new request. // if(_requests.empty() && (!_connection || !_pendingSend)) { - _requestQueueThread->flushRequestQueue(this); // This might throw if the thread is destroyed. + _requestQueueThread->flushRequestQueue(shared_from_this()); // This might throw if the thread is destroyed. } - _requests.push_back(request); request->queued(); + _requests.push_back(move(request)); if(_observer) { _observer->queued(!_connection); @@ -256,7 +197,7 @@ Glacier2::RequestQueue::addRequest(const RequestPtr& request) void Glacier2::RequestQueue::flushRequests() { - IceUtil::Mutex::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(_connection) { if(_pendingSend) @@ -267,58 +208,39 @@ Glacier2::RequestQueue::flushRequests() } else { - for(deque<RequestPtr>::const_iterator p = _requests.begin(); p != _requests.end(); ++p) + for(const auto& request : _requests) { - try + if(_observer) { - if(_observer) + _observer->forwarded(!_connection); + } + auto self = shared_from_this(); + request->invoke( + [self, request](bool ok, const pair<const Byte*, const Byte*>& outParams) + { + self->response(ok, outParams, request); + }, + [self, request](exception_ptr e) { - _observer->forwarded(!_connection); + self->exception(e, request); } - assert(_callback); - (*p)->invoke(_callback); - } - catch(const Ice::LocalException&) - { - // Ignore, this can occur for batch requests. - } + ); } _requests.clear(); - - for(set<Ice::ObjectPrx>::const_iterator q = _batchProxies.begin(); q != _batchProxies.end(); ++q) - { - (*q)->begin_ice_flushBatchRequests(); - } - _batchProxies.clear(); - } - - if(_destroyed && _requests.empty()) - { - destroyInternal(); } } void Glacier2::RequestQueue::destroy() { - IceUtil::Mutex::Lock lock(*this); - + lock_guard<mutex> lg(_mutex); _destroyed = true; - - // - // Although the session has been destroyed, we cannot destroy this queue - // until all requests have completed. - // - if(_requests.empty()) - { - destroyInternal(); - } } void -Glacier2::RequestQueue::updateObserver(const Glacier2::Instrumentation::SessionObserverPtr& observer) +Glacier2::RequestQueue::updateObserver(shared_ptr<Glacier2::Instrumentation::SessionObserver> observer) { - IceUtil::Mutex::Lock lock(*this); + lock_guard<mutex> lg(_mutex); _observer = observer; } @@ -327,34 +249,45 @@ Glacier2::RequestQueue::flush() { assert(_connection); _pendingSend = false; - _pendingSendRequest = 0; + _pendingSendRequest = nullptr; - bool flushBatchRequests = false; - deque<RequestPtr>::iterator p; + deque<shared_ptr<Request>>::iterator p; for(p = _requests.begin(); p != _requests.end(); ++p) { - try + if(_observer) { - assert(_callback); - if(_observer) + _observer->forwarded(!_connection); + } + + shared_ptr<promise<void>> isSent = make_shared<promise<void>>(); + shared_ptr<promise<void>> completedExceptionally = make_shared<promise<void>>(); + + auto self = shared_from_this(); + auto request = *p; + + request->invoke( + [self, request](bool ok, const pair<const Byte*, const Byte*>& outParams) { - _observer->forwarded(!_connection); - } - Ice::AsyncResultPtr result = (*p)->invoke(_callback); - if(!result) + self->response(ok, outParams, request); + }, + [self, request, completedExceptionally](exception_ptr e) { - flushBatchRequests = true; - } - else if(!result->sentSynchronously() && !result->isCompleted()) + completedExceptionally->set_value(); + self->exception(e, request); + }, + [self, request, isSent](bool sentSynchronously) { - _pendingSend = true; - _pendingSendRequest = *p++; - break; + isSent->set_value(); + self->sent(sentSynchronously, request); } - } - catch(const Ice::LocalException&) + ); + + if((isSent->get_future().wait_for(0s) != future_status::ready) && + (completedExceptionally->get_future().wait_for(0s) != future_status::ready)) { - // Ignore, this can occur for batch requests. + _pendingSend = true; + _pendingSendRequest = *p++; + break; } } @@ -366,48 +299,21 @@ Glacier2::RequestQueue::flush() { _requests.erase(_requests.begin(), p); } - - if(flushBatchRequests) - { - Ice::AsyncResultPtr result = _connection->begin_flushBatchRequests(ICE_SCOPED_ENUM(CompressBatch, BasedOnProxy), _flushCallback); - if(!result->sentSynchronously() && !result->isCompleted()) - { - _pendingSend = true; - _pendingSendRequest = 0; - } - } } void -Glacier2::RequestQueue::destroyInternal() -{ - // - // Must be called with the mutex locked. - // - - // - // Remove cyclic references. - // - const_cast<Ice::Callback_Object_ice_invokePtr&>(_callback) = 0; - const_cast<Ice::Callback_Connection_flushBatchRequestsPtr&>(_flushCallback) = 0; -} - -void -Glacier2::RequestQueue::response(bool ok, const pair<const Byte*, const Byte*>& outParams, const RequestPtr& request) +Glacier2::RequestQueue::response(bool ok, const pair<const Byte*, const Byte*>& outParams, const shared_ptr<Request>& request) { assert(request); request->response(ok, outParams); } void -Glacier2::RequestQueue::exception(const Ice::Exception& ex, const RequestPtr& request) +Glacier2::RequestQueue::exception(exception_ptr ex, const shared_ptr<Request>& request) { - // - // If the connection has been lost, destroy the session. - // if(_connection) { - IceUtil::Mutex::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(request == _pendingSendRequest) { flush(); @@ -421,11 +327,11 @@ Glacier2::RequestQueue::exception(const Ice::Exception& ex, const RequestPtr& re } void -Glacier2::RequestQueue::sent(bool sentSynchronously, const RequestPtr& request) +Glacier2::RequestQueue::sent(bool sentSynchronously, const shared_ptr<Request>& request) { if(_connection && !sentSynchronously) { - IceUtil::Mutex::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(request == _pendingSendRequest) { flush(); @@ -433,11 +339,11 @@ Glacier2::RequestQueue::sent(bool sentSynchronously, const RequestPtr& request) } } -Glacier2::RequestQueueThread::RequestQueueThread(const IceUtil::Time& sleepTime) : - IceUtil::Thread("Glacier2 request queue thread"), - _sleepTime(sleepTime), +Glacier2::RequestQueueThread::RequestQueueThread(std::chrono::milliseconds sleepTime) : + _sleepTime(move(sleepTime)), _destroy(false), - _sleep(false) + _sleep(false), + _thread([this] { run(); }) { } @@ -451,28 +357,22 @@ void Glacier2::RequestQueueThread::destroy() { { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - + lock_guard<mutex> lg(_mutex); assert(!_destroy); _destroy = true; _sleep = false; - notify(); } - try - { - getThreadControl().join(); - } - catch(const IceUtil::ThreadNotStartedException&) - { - // Expected if start() failed. - } + _condVar.notify_one(); + + _thread.join(); } void -Glacier2::RequestQueueThread::flushRequestQueue(const RequestQueuePtr& queue) +Glacier2::RequestQueueThread::flushRequestQueue(shared_ptr<RequestQueue> queue) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); + if(_destroy) { throw Ice::ObjectNotExistException(__FILE__, __LINE__); @@ -480,20 +380,22 @@ Glacier2::RequestQueueThread::flushRequestQueue(const RequestQueuePtr& queue) if(_queues.empty() && !_sleep) { - notify(); + _condVar.notify_one(); } - _queues.push_back(queue); + _queues.push_back(move(queue)); } void Glacier2::RequestQueueThread::run() { + std::chrono::nanoseconds sleepDuration = 0ns; + while(true) { - vector<RequestQueuePtr> queues; + vector<shared_ptr<RequestQueue>> queues; { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + unique_lock<mutex> lock(_mutex); // // Wait indefinitely if there's no requests to @@ -505,24 +407,25 @@ Glacier2::RequestQueueThread::run() { if(_sleep) { - IceUtil::Time now = IceUtil::Time::now(IceUtil::Time::Monotonic); - if(!timedWait(_sleepDuration)) + auto now = chrono::steady_clock::now(); + + if(_condVar.wait_for(lock, sleepDuration) == cv_status::no_timeout) { - _sleepDuration = IceUtil::Time(); + sleepDuration = 0ns; } else { - _sleepDuration -= IceUtil::Time::now(IceUtil::Time::Monotonic) - now; + sleepDuration -= chrono::steady_clock::now() - now; } - if(_sleepDuration <= IceUtil::Time()) + if(sleepDuration <= 0ns) { _sleep = false; } } else { - wait(); + _condVar.wait(lock); } } @@ -539,16 +442,16 @@ Glacier2::RequestQueueThread::run() queues.swap(_queues); - if(_sleepTime > IceUtil::Time()) + if(_sleepTime > 0ms) { _sleep = true; - _sleepDuration = _sleepTime; + sleepDuration = _sleepTime; } } - for(vector<RequestQueuePtr>::const_iterator p = queues.begin(); p != queues.end(); ++p) + for(const auto& queue : queues) { - (*p)->flushRequests(); + queue->flushRequests(); } } } diff --git a/cpp/src/Glacier2/RequestQueue.h b/cpp/src/Glacier2/RequestQueue.h index 6ef8055cf61..631d90240c9 100644 --- a/cpp/src/Glacier2/RequestQueue.h +++ b/cpp/src/Glacier2/RequestQueue.h @@ -5,8 +5,6 @@ #ifndef REQUEST_H #define REQUEST_H -#include <IceUtil/Thread.h> -#include <IceUtil/Monitor.h> #include <Ice/Ice.h> #include <Glacier2/Instrumentation.h> @@ -17,99 +15,100 @@ namespace Glacier2 { class Instance; -typedef IceUtil::Handle<Instance> InstancePtr; - class Request; -typedef IceUtil::Handle<Request> RequestPtr; - class RequestQueueThread; -typedef IceUtil::Handle<RequestQueueThread> RequestQueueThreadPtr; -class Request : public Ice::LocalObject +class Request { public: - Request(const Ice::ObjectPrx&, const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&, bool, - const Ice::Context&, const Ice::AMD_Object_ice_invokePtr&); - - Ice::AsyncResultPtr invoke(const Ice::Callback_Object_ice_invokePtr& callback); - bool override(const RequestPtr&) const; - void addBatchProxy(std::set<Ice::ObjectPrx>&); + Request(std::shared_ptr<Ice::ObjectPrx>, + const std::pair<const Ice::Byte*, const Ice::Byte*>&, + const Ice::Current&, + bool, + const Ice::Context&, + std::function<void(bool, std::pair<const Ice::Byte*, const Ice::Byte*>)>, + std::function<void(std::exception_ptr)>); + + void invoke(std::function<void(bool, std::pair<const Ice::Byte*, const Ice::Byte*>)>&&, + std::function<void(std::exception_ptr)>&&, + std::function<void(bool)>&& = nullptr); + bool override(const std::shared_ptr<Request>&) const; bool hasOverride() const { return !_override.empty(); } private: friend class RequestQueue; void response(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&); - void exception(const Ice::Exception&); + void exception(std::exception_ptr); void queued(); - const Ice::ObjectPrx _proxy; + const std::shared_ptr<Ice::ObjectPrx> _proxy; const Ice::ByteSeq _inParams; const Ice::Current _current; const bool _forwardContext; const Ice::Context _sslContext; const std::string _override; - const Ice::AMD_Object_ice_invokePtr _amdCB; + std::function<void(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&)> _response; + std::function<void(std::exception_ptr)> _exception; }; -class RequestQueue : public IceUtil::Mutex, public IceUtil::Shared +class RequestQueue : public std::enable_shared_from_this<RequestQueue> { public: - RequestQueue(const RequestQueueThreadPtr&, const InstancePtr&, const Ice::ConnectionPtr&); + RequestQueue(std::shared_ptr<RequestQueueThread>, std::shared_ptr<Instance>, std::shared_ptr<Ice::Connection>); - bool addRequest(const RequestPtr&); + bool addRequest(std::shared_ptr<Request>); void flushRequests(); void destroy(); - void updateObserver(const Glacier2::Instrumentation::SessionObserverPtr&); + void updateObserver(std::shared_ptr<Glacier2::Instrumentation::SessionObserver>); private: - void destroyInternal(); - void flush(); - void response(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&, const RequestPtr&); - void exception(const Ice::Exception&, const RequestPtr&); - void sent(bool, const RequestPtr&); + void response(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&, const std::shared_ptr<Request>&); + void exception(std::exception_ptr, const std::shared_ptr<Request>&); + void sent(bool, const std::shared_ptr<Request>&); - const RequestQueueThreadPtr _requestQueueThread; - const InstancePtr _instance; - const Ice::ConnectionPtr _connection; - const Ice::Callback_Object_ice_invokePtr _callback; - const Ice::Callback_Connection_flushBatchRequestsPtr _flushCallback; + const std::shared_ptr<RequestQueueThread> _requestQueueThread; + const std::shared_ptr<Instance> _instance; + const std::shared_ptr<Ice::Connection> _connection; - std::deque<RequestPtr> _requests; - std::set<Ice::ObjectPrx> _batchProxies; + std::deque<std::shared_ptr<Request>> _requests; bool _pendingSend; - RequestPtr _pendingSendRequest; + std::shared_ptr<Request> _pendingSendRequest; bool _destroyed; - Glacier2::Instrumentation::SessionObserverPtr _observer; + std::shared_ptr<Glacier2::Instrumentation::SessionObserver> _observer; + + std::mutex _mutex; }; -typedef IceUtil::Handle<RequestQueue> RequestQueuePtr; -class RequestQueueThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> +class RequestQueueThread { public: - RequestQueueThread(const IceUtil::Time&); - virtual ~RequestQueueThread(); + RequestQueueThread(std::chrono::milliseconds); + ~RequestQueueThread(); - void flushRequestQueue(const RequestQueuePtr&); + void flushRequestQueue(std::shared_ptr<RequestQueue>); void destroy(); - virtual void run(); - private: + void run(); - const IceUtil::Time _sleepTime; + const std::chrono::milliseconds _sleepTime; bool _destroy; bool _sleep; - IceUtil::Time _sleepDuration; - std::vector<RequestQueuePtr> _queues; + + std::vector<std::shared_ptr<RequestQueue>> _queues; + + std::mutex _mutex; + std::condition_variable _condVar; + std::thread _thread; }; } diff --git a/cpp/src/Glacier2/RouterI.cpp b/cpp/src/Glacier2/RouterI.cpp index a26012ccecd..97601e52e52 100644 --- a/cpp/src/Glacier2/RouterI.cpp +++ b/cpp/src/Glacier2/RouterI.cpp @@ -2,35 +2,32 @@ // Copyright (c) ZeroC, Inc. All rights reserved. // -#include <IceUtil/Random.h> - #include <Glacier2/FilterManager.h> #include <Glacier2/RoutingTable.h> #include <Glacier2/RouterI.h> #include <Glacier2/Session.h> -#ifdef ICE_CPP11_COMPILER -# include<random> -#endif +#include<random> using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::RouterI::RouterI(const InstancePtr& instance, const ConnectionPtr& connection, const string& userId, - const SessionPrx& session, const Identity& controlId, const FilterManagerPtr& filters, - const Ice::Context& context) : - _instance(instance), - _routingTable(new RoutingTable(_instance->communicator(), _instance->proxyVerifier())), - _clientBlobject(new ClientBlobject(_instance, filters, context, _routingTable)), +Glacier2::RouterI::RouterI(shared_ptr<Instance> instance, shared_ptr<Connection> connection, + const string& userId, shared_ptr<SessionPrx> session, + const Identity& controlId, shared_ptr<FilterManager> filters, + const Context& context) : + _instance(move(instance)), + _routingTable(make_shared<RoutingTable>(_instance->communicator(), _instance->proxyVerifier())), + _clientBlobject(make_shared<ClientBlobject>(_instance, move(filters), context, _routingTable)), _clientBlobjectBuffered(_instance->clientRequestQueueThread()), _serverBlobjectBuffered(_instance->serverRequestQueueThread()), - _connection(connection), + _connection(move(connection)), _userId(userId), - _session(session), + _session(move(session)), _controlId(controlId), _context(context), - _timestamp(IceUtil::Time::now(IceUtil::Time::Monotonic)) + _timestamp(chrono::steady_clock::now()) { // // If Glacier2 will be used with pre 3.2 clients, then the client proxy must be set. @@ -38,37 +35,26 @@ Glacier2::RouterI::RouterI(const InstancePtr& instance, const ConnectionPtr& con // if(_instance->properties()->getPropertyAsInt("Glacier2.ReturnClientProxy") > 0) { - const_cast<Ice::ObjectPrx&>(_clientProxy) = + const_cast<shared_ptr<ObjectPrx>&>(_clientProxy) = _instance->clientObjectAdapter()->createProxy(stringToIdentity("dummy")); } if(_instance->serverObjectAdapter()) { - ObjectPrx& serverProxy = const_cast<ObjectPrx&>(_serverProxy); - Identity ident; - ident.name = "dummy"; - ident.category.resize(20); -#ifdef ICE_CPP11_COMPILER + 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 < ident.category.size(); ++i) - { - ident.category[i] = static_cast<unsigned char>(dist(gen)); - } -#else - char buf[20]; - IceUtilInternal::generateRandom(buf, sizeof(buf)); - for(unsigned int i = 0; i < sizeof(buf); ++i) + for(unsigned int i = 0; i < 20; ++i) { - const unsigned char c = static_cast<unsigned char>(buf[i]); // A value between 0-255 - ident.category[i] = 33 + c % (127-33); // We use ASCII 33-126 (from ! to ~, w/o space). + ident.category.push_back(static_cast<char>(dist(gen))); } -#endif - serverProxy = _instance->serverObjectAdapter()->createProxy(ident); - ServerBlobjectPtr& serverBlobject = const_cast<ServerBlobjectPtr&>(_serverBlobject); - serverBlobject = new ServerBlobject(_instance, _connection); + const_cast<shared_ptr<ObjectPrx>&>(_serverProxy) = _instance->serverObjectAdapter()->createProxy(ident); + + shared_ptr<ServerBlobject>& serverBlobject = const_cast<shared_ptr<ServerBlobject>&>(_serverBlobject); + serverBlobject = make_shared<ServerBlobject>(_instance, _connection); } if(_instance->getObserver()) @@ -77,25 +63,8 @@ Glacier2::RouterI::RouterI(const InstancePtr& instance, const ConnectionPtr& con } } -Glacier2::RouterI::~RouterI() -{ -} - -void -Glacier2::RouterI::updateObserver(const Glacier2::Instrumentation::RouterObserverPtr& observer) -{ - // Can only be called with the SessionRouterI mutex locked - - _observer = _routingTable->updateObserver(observer, _userId, _connection); - _clientBlobject->updateObserver(_observer); - if(_serverBlobject) - { - _serverBlobject->updateObserver(_observer); - } -} - void -Glacier2::RouterI::destroy(const Callback_Session_destroyPtr& asyncCB) +Glacier2::RouterI::destroy(function<void(exception_ptr)> error) { if(_session) { @@ -121,11 +90,11 @@ Glacier2::RouterI::destroy(const Callback_Session_destroyPtr& asyncCB) if(_context.size() > 0) { - _session->begin_destroy(_context, asyncCB); + _session->destroyAsync(nullptr, move(error), nullptr, _context); } else { - _session->begin_destroy(asyncCB); + _session->destroyAsync(nullptr, move(error), nullptr); } } @@ -138,15 +107,15 @@ Glacier2::RouterI::destroy(const Callback_Session_destroyPtr& asyncCB) _routingTable->destroy(); } -ObjectPrx -Glacier2::RouterI::getClientProxy(IceUtil::Optional<bool>& hasRoutingTable, const Current&) const +shared_ptr<ObjectPrx> +Glacier2::RouterI::getClientProxy(Ice::optional<bool>& hasRoutingTable, const Current&) const { // No mutex lock necessary, _clientProxy is immutable and is never destroyed. hasRoutingTable = true; return _clientProxy; } -ObjectPrx +shared_ptr<ObjectPrx> Glacier2::RouterI::getServerProxy(const Current&) const { // No mutex lock necessary, _serverProxy is immutable and is never destroyed. @@ -154,34 +123,35 @@ Glacier2::RouterI::getServerProxy(const Current&) const } ObjectProxySeq -Glacier2::RouterI::addProxies(const ObjectProxySeq& proxies, const Current& current) +Glacier2::RouterI::addProxies(ObjectProxySeq proxies, const Current& current) { - return _routingTable->add(proxies, current); + return _routingTable->add(move(proxies), current); } string -Glacier2::RouterI::getCategoryForClient(const Ice::Current&) const +Glacier2::RouterI::getCategoryForClient(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } void -Glacier2::RouterI::createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, - const Current&) +Glacier2::RouterI::createSessionAsync(string, string, + function<void(const shared_ptr<SessionPrx>& returnValue)>, + function<void(exception_ptr)>, const Current&) { assert(false); // Must not be called in this router implementation. } void -Glacier2::RouterI::createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, - const Current&) +Glacier2::RouterI::createSessionFromSecureConnectionAsync(function<void(const shared_ptr<SessionPrx>& returnValue)>, + function<void(exception_ptr)>, const Current&) { assert(false); // Must not be called in this router implementation. } void -Glacier2::RouterI::refreshSession_async(const AMD_Router_refreshSessionPtr&, const ::Ice::Current&) +Glacier2::RouterI::refreshSessionAsync(function<void()>, function<void(exception_ptr)>, const Current&) { assert(false); // Must not be called in this router implementation. } @@ -192,21 +162,21 @@ Glacier2::RouterI::destroySession(const Current&) assert(false); // Must not be called in this router implementation. } -Ice::Long +Long Glacier2::RouterI::getSessionTimeout(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } -Ice::Int +Int Glacier2::RouterI::getACMTimeout(const Current&) const { assert(false); // Must not be called in this router implementation. return 0; } -ClientBlobjectPtr +shared_ptr<ClientBlobject> Glacier2::RouterI::getClientBlobject() const { // Can only be called with the SessionRouterI mutex locked @@ -217,7 +187,7 @@ Glacier2::RouterI::getClientBlobject() const return _clientBlobject; } -ServerBlobjectPtr +shared_ptr<ServerBlobject> Glacier2::RouterI::getServerBlobject() const { // Can only be called with the SessionRouterI mutex locked @@ -228,13 +198,13 @@ Glacier2::RouterI::getServerBlobject() const return _serverBlobject; } -SessionPrx +shared_ptr<SessionPrx> Glacier2::RouterI::getSession() const { return _session; // No mutex lock necessary, _session is immutable. } -IceUtil::Time +chrono::steady_clock::time_point Glacier2::RouterI::getTimestamp() const { // Can only be called with the SessionRouterI mutex locked @@ -245,7 +215,20 @@ void Glacier2::RouterI::updateTimestamp() const { // Can only be called with the SessionRouterI mutex locked - _timestamp = IceUtil::Time::now(IceUtil::Time::Monotonic); + _timestamp = chrono::steady_clock::now(); +} + +void +Glacier2::RouterI::updateObserver(const shared_ptr<Glacier2::Instrumentation::RouterObserver>& 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 diff --git a/cpp/src/Glacier2/RouterI.h b/cpp/src/Glacier2/RouterI.h index 98fe25a2d3c..024e728ba93 100644 --- a/cpp/src/Glacier2/RouterI.h +++ b/cpp/src/Glacier2/RouterI.h @@ -14,69 +14,66 @@ namespace Glacier2 { class RoutingTable; -typedef IceUtil::Handle<RoutingTable> RoutingTablePtr; - class RouterI; -typedef IceUtil::Handle<RouterI> RouterIPtr; - class FilterManager; -typedef IceUtil::Handle<FilterManager> FilterManagerPtr; -class RouterI : public Router +class RouterI final : public Router { public: - RouterI(const InstancePtr&, const Ice::ConnectionPtr&, const std::string&, const SessionPrx&, const Ice::Identity&, - const FilterManagerPtr&, const Ice::Context&); - - virtual ~RouterI(); - - void destroy(const Callback_Session_destroyPtr&); - - virtual Ice::ObjectPrx getClientProxy(IceUtil::Optional<bool>&, const Ice::Current&) const; - virtual Ice::ObjectPrx getServerProxy(const Ice::Current&) const; - virtual Ice::ObjectProxySeq addProxies(const Ice::ObjectProxySeq&, const Ice::Current&); - virtual std::string getCategoryForClient(const Ice::Current&) const; - virtual void createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, - const Ice::Current&); - virtual void createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, - const Ice::Current&); - virtual void refreshSession_async(const AMD_Router_refreshSessionPtr&, const ::Ice::Current&); - virtual void destroySession(const ::Ice::Current&); - virtual Ice::Long getSessionTimeout(const ::Ice::Current&) const; - virtual Ice::Int getACMTimeout(const ::Ice::Current&) const; - - ClientBlobjectPtr getClientBlobject() const; - ServerBlobjectPtr getServerBlobject() const; - - SessionPrx getSession() const; - - IceUtil::Time getTimestamp() const; + RouterI(std::shared_ptr<Instance>, std::shared_ptr<Ice::Connection>, const std::string&, + std::shared_ptr<SessionPrx>, const Ice::Identity&, std::shared_ptr<FilterManager>, const Ice::Context&); + + void destroy(std::function<void(std::exception_ptr)>); + + std::shared_ptr<Ice::ObjectPrx> getClientProxy(Ice::optional<bool>&, const Ice::Current&) const override; + std::shared_ptr<Ice::ObjectPrx> getServerProxy(const Ice::Current&) const override; + Ice::ObjectProxySeq addProxies(Ice::ObjectProxySeq, const Ice::Current&) override; + std::string getCategoryForClient(const Ice::Current&) const override; + void createSessionAsync(std::string, std::string, + std::function<void(const std::shared_ptr<SessionPrx>& returnValue)>, + std::function<void(std::exception_ptr)>, const Ice::Current&) override; + void createSessionFromSecureConnectionAsync( + std::function<void(const std::shared_ptr<SessionPrx>& returnValue)>, + std::function<void(std::exception_ptr)>, const Ice::Current&) override; + void refreshSessionAsync(std::function<void()>, + std::function<void(std::exception_ptr)>, + const Ice::Current&) override; + void destroySession(const Ice::Current&) override; + long long int getSessionTimeout(const Ice::Current&) const override; + int getACMTimeout(const Ice::Current&) const override; + + std::shared_ptr<ClientBlobject> getClientBlobject() const; + std::shared_ptr<ServerBlobject> getServerBlobject() const; + + std::shared_ptr<SessionPrx> getSession() const; + + std::chrono::steady_clock::time_point getTimestamp() const; void updateTimestamp() const; - void updateObserver(const Glacier2::Instrumentation::RouterObserverPtr&); + void updateObserver(const std::shared_ptr<Glacier2::Instrumentation::RouterObserver>&); std::string toString() const; private: - const InstancePtr _instance; - const RoutingTablePtr _routingTable; - const Ice::ObjectPrx _clientProxy; - const Ice::ObjectPrx _serverProxy; - const ClientBlobjectPtr _clientBlobject; - const ServerBlobjectPtr _serverBlobject; + const std::shared_ptr<Instance> _instance; + const std::shared_ptr<RoutingTable> _routingTable; + const std::shared_ptr<Ice::ObjectPrx> _clientProxy; + const std::shared_ptr<Ice::ObjectPrx> _serverProxy; + const std::shared_ptr<ClientBlobject> _clientBlobject; + const std::shared_ptr<ServerBlobject> _serverBlobject; const bool _clientBlobjectBuffered; const bool _serverBlobjectBuffered; - const Ice::ConnectionPtr _connection; + const std::shared_ptr<Ice::Connection> _connection; const std::string _userId; - const SessionPrx _session; + const std::shared_ptr<SessionPrx> _session; const Ice::Identity _controlId; const Ice::Context _context; - const IceUtil::Mutex _timestampMutex; - mutable IceUtil::Time _timestamp; + const std::mutex _timestampMutex; + mutable std::chrono::steady_clock::time_point _timestamp; - Glacier2::Instrumentation::SessionObserverPtr _observer; + std::shared_ptr<Glacier2::Instrumentation::SessionObserver> _observer; }; } diff --git a/cpp/src/Glacier2/RoutingTable.cpp b/cpp/src/Glacier2/RoutingTable.cpp index a38b5b05f78..4308f0dbeec 100644 --- a/cpp/src/Glacier2/RoutingTable.cpp +++ b/cpp/src/Glacier2/RoutingTable.cpp @@ -9,39 +9,39 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::RoutingTable::RoutingTable(const CommunicatorPtr& communicator, const ProxyVerifierPtr& verifier) : - _communicator(communicator), +Glacier2::RoutingTable::RoutingTable(shared_ptr<Communicator> communicator, shared_ptr<ProxyVerifier> verifier) : + _communicator(move(communicator)), _traceLevel(_communicator->getProperties()->getPropertyAsInt("Glacier2.Trace.RoutingTable")), _maxSize(_communicator->getProperties()->getPropertyAsIntWithDefault("Glacier2.RoutingTable.MaxSize", 1000)), - _verifier(verifier) + _verifier(move(verifier)) { } void Glacier2::RoutingTable::destroy() { - IceUtil::Mutex::Lock sync(*this); + lock_guard<mutex> lg(_mutex); if(_observer) { - _observer->routingTableSize(-static_cast<Ice::Int>(_map.size())); + _observer->routingTableSize(-static_cast<int>(_map.size())); } _observer.detach(); } -Glacier2::Instrumentation::SessionObserverPtr -Glacier2::RoutingTable::updateObserver(const Glacier2::Instrumentation::RouterObserverPtr& obsv, +shared_ptr<Glacier2::Instrumentation::SessionObserver> +Glacier2::RoutingTable::updateObserver(const shared_ptr<Glacier2::Instrumentation::RouterObserver>& obsv, const string& userId, - const Ice::ConnectionPtr& connection) + const shared_ptr<Ice::Connection>& connection) { - IceUtil::Mutex::Lock sync(*this); - _observer.attach(obsv->getSessionObserver(userId, connection, static_cast<Ice::Int>(_map.size()), _observer.get())); + lock_guard<mutex> lg(_mutex); + _observer.attach(obsv->getSessionObserver(userId, connection, static_cast<int>(_map.size()), _observer.get())); return _observer.get(); } ObjectProxySeq Glacier2::RoutingTable::add(const ObjectProxySeq& unfiltered, const Current& current) { - IceUtil::Mutex::Lock sync(*this); + lock_guard<mutex> lg(_mutex); size_t sz = _map.size(); @@ -51,26 +51,25 @@ Glacier2::RoutingTable::add(const ObjectProxySeq& unfiltered, const Current& cur // in a rejection. // ObjectProxySeq proxies; - for(ObjectProxySeq::const_iterator prx = unfiltered.begin(); prx != unfiltered.end(); ++prx) + for(const auto& prx : unfiltered) { - if(!*prx) // We ignore null proxies. + if(!prx) // We ignore null proxies. { continue; } - if(!_verifier->verify(*prx)) + if(!_verifier->verify(prx)) { - current.con->close(ICE_SCOPED_ENUM(ConnectionClose, Forcefully)); + current.con->close(ConnectionClose::Forcefully); throw ObjectNotExistException(__FILE__, __LINE__); } - ObjectPrx proxy = (*prx)->ice_twoway()->ice_secure(false)->ice_facet(""); // We add proxies in default form. + auto proxy = prx->ice_twoway()->ice_secure(false)->ice_facet(""); // We add proxies in default form. proxies.push_back(proxy); } ObjectProxySeq evictedProxies; - for(ObjectProxySeq::const_iterator prx = proxies.begin(); prx != proxies.end(); ++prx) + for(const auto& proxy : proxies) { - ObjectPrx proxy = *prx; EvictorMap::iterator p = _map.find(proxy->ice_getIdentity()); if(p == _map.end()) @@ -81,8 +80,8 @@ Glacier2::RoutingTable::add(const ObjectProxySeq& unfiltered, const Current& cur out << "adding proxy to routing table:\n" << _communicator->proxyToString(proxy); } - EvictorEntryPtr entry = new EvictorEntry; - p = _map.insert(_map.begin(), pair<const Identity, EvictorEntryPtr>(proxy->ice_getIdentity(), entry)); + auto entry = make_shared<EvictorEntry>(); + p = _map.insert(_map.begin(), {proxy->ice_getIdentity(), entry}); EvictorQueue::iterator q = _queue.insert(_queue.end(), p); entry->proxy = proxy; entry->pos = q; @@ -95,7 +94,7 @@ Glacier2::RoutingTable::add(const ObjectProxySeq& unfiltered, const Current& cur out << "proxy already in routing table:\n" << _communicator->proxyToString(proxy); } - EvictorEntryPtr entry = p->second; + auto entry = p->second; _queue.erase(entry->pos); EvictorQueue::iterator q = _queue.insert(_queue.end(), p); entry->pos = q; @@ -120,13 +119,13 @@ Glacier2::RoutingTable::add(const ObjectProxySeq& unfiltered, const Current& cur if(_observer) { - _observer->routingTableSize(static_cast<Ice::Int>(_map.size()) - static_cast<Ice::Int>(sz)); + _observer->routingTableSize(static_cast<int>(_map.size()) - static_cast<int>(sz)); } return evictedProxies; } -ObjectPrx +shared_ptr<ObjectPrx> Glacier2::RoutingTable::get(const Identity& ident) { if(ident.name.empty()) @@ -134,7 +133,7 @@ Glacier2::RoutingTable::get(const Identity& ident) return 0; } - IceUtil::Mutex::Lock sync(*this); + lock_guard<mutex> lg(_mutex); EvictorMap::iterator p = _map.find(ident); @@ -144,7 +143,7 @@ Glacier2::RoutingTable::get(const Identity& ident) } else { - EvictorEntryPtr entry = p->second; + auto entry = p->second; _queue.erase(entry->pos); EvictorQueue::iterator q = _queue.insert(_queue.end(), p); entry->pos = q; diff --git a/cpp/src/Glacier2/RoutingTable.h b/cpp/src/Glacier2/RoutingTable.h index 97b858bdf0f..805f0a963db 100644 --- a/cpp/src/Glacier2/RoutingTable.h +++ b/cpp/src/Glacier2/RoutingTable.h @@ -17,41 +17,37 @@ namespace Glacier2 { -class RoutingTable; -typedef IceUtil::Handle<RoutingTable> RoutingTablePtr; - -class RoutingTable : public IceUtil::Shared, public IceUtil::Mutex +class RoutingTable final { public: - RoutingTable(const Ice::CommunicatorPtr&, const ProxyVerifierPtr&); + RoutingTable(std::shared_ptr<Ice::Communicator>, std::shared_ptr<ProxyVerifier>); void destroy(); - Glacier2::Instrumentation::SessionObserverPtr - updateObserver(const Glacier2::Instrumentation::RouterObserverPtr&, const std::string&, const Ice::ConnectionPtr&); + std::shared_ptr<Glacier2::Instrumentation::SessionObserver> + updateObserver(const std::shared_ptr<Glacier2::Instrumentation::RouterObserver>&, + const std::string&, const std::shared_ptr<Ice::Connection>&); // Returns evicted proxies. Ice::ObjectProxySeq add(const Ice::ObjectProxySeq&, const Ice::Current&); - Ice::ObjectPrx get(const Ice::Identity&); // Returns null if no proxy can be found. + std::shared_ptr<Ice::ObjectPrx> get(const Ice::Identity&); // Returns null if no proxy can be found. private: - const Ice::CommunicatorPtr _communicator; + const std::shared_ptr<Ice::Communicator> _communicator; const int _traceLevel; const int _maxSize; - const ProxyVerifierPtr _verifier; + const std::shared_ptr<ProxyVerifier> _verifier; struct EvictorEntry; - typedef IceUtil::Handle<EvictorEntry> EvictorEntryPtr; - - typedef std::map<Ice::Identity, EvictorEntryPtr> EvictorMap; - typedef std::list<EvictorMap::iterator> EvictorQueue; + using EvictorMap = std::map<Ice::Identity, std::shared_ptr<EvictorEntry>>; + using EvictorQueue = std::list<EvictorMap::iterator>; friend struct EvictorEntry; - struct EvictorEntry : public IceUtil::Shared + struct EvictorEntry { - Ice::ObjectPrx proxy; + std::shared_ptr<Ice::ObjectPrx> proxy; EvictorQueue::iterator pos; }; @@ -59,6 +55,8 @@ private: EvictorQueue _queue; IceInternal::ObserverHelperT<Glacier2::Instrumentation::SessionObserver> _observer; + + std::mutex _mutex; }; } diff --git a/cpp/src/Glacier2/ServerBlobject.cpp b/cpp/src/Glacier2/ServerBlobject.cpp index 1d666af5a37..5dcda4c2a35 100644 --- a/cpp/src/Glacier2/ServerBlobject.cpp +++ b/cpp/src/Glacier2/ServerBlobject.cpp @@ -8,22 +8,19 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::ServerBlobject::ServerBlobject(const InstancePtr& instance, const ConnectionPtr& connection) : - Glacier2::Blobject(instance, connection, Ice::Context()) -{ -} - -Glacier2::ServerBlobject::~ServerBlobject() +Glacier2::ServerBlobject::ServerBlobject(shared_ptr<Instance> instance, shared_ptr<Connection> connection) : + Glacier2::Blobject(move(instance), move(connection), Ice::Context()) { } void -Glacier2::ServerBlobject::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCB, - const std::pair<const Byte*, const Byte*>& inParams, - const Current& current) +Glacier2::ServerBlobject::ice_invokeAsync(pair<const Byte*, const Byte*> inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, + const Current& current) { - ObjectPrx proxy = _reverseConnection->createProxy(current.id); + auto proxy = _reverseConnection->createProxy(current.id); assert(proxy); - invoke(proxy, amdCB, inParams, current); + invoke(proxy, inParams, move(response), move(error), current); } diff --git a/cpp/src/Glacier2/ServerBlobject.h b/cpp/src/Glacier2/ServerBlobject.h index 6fee81867d5..807cf76768a 100644 --- a/cpp/src/Glacier2/ServerBlobject.h +++ b/cpp/src/Glacier2/ServerBlobject.h @@ -10,18 +10,16 @@ namespace Glacier2 { -class ServerBlobject; -typedef IceUtil::Handle<ServerBlobject> ServerBlobjectPtr; - -class ServerBlobject : public Glacier2::Blobject +class ServerBlobject final : public Glacier2::Blobject { public: - ServerBlobject(const InstancePtr&, const Ice::ConnectionPtr&); - virtual ~ServerBlobject(); + ServerBlobject(std::shared_ptr<Instance>, std::shared_ptr<Ice::Connection>); - virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, - const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); + void ice_invokeAsync(std::pair<const Ice::Byte*, const Ice::Byte*> inEncaps, + std::function<void(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&)> response, + std::function<void(std::exception_ptr)> error, + const Ice::Current& current) override; }; } diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp index b76ce4e3a9b..3f4dbbf99f6 100644 --- a/cpp/src/Glacier2/SessionRouterI.cpp +++ b/cpp/src/Glacier2/SessionRouterI.cpp @@ -1,3 +1,4 @@ + // // Copyright (c) ZeroC, Inc. All rights reserved. // @@ -17,87 +18,20 @@ using namespace Glacier2; namespace { -class PingCallback : public IceUtil::Shared -{ -public: - - PingCallback(const SessionRouterIPtr& router, - const AMD_Router_refreshSessionPtr& callback, - const Ice::ConnectionPtr& connection) : _router(router), - _callback(callback), - _connection(connection) - { - } - - void - finished(const Ice::AsyncResultPtr& r) - { - Ice::ObjectPrx o = r->getProxy(); - try - { - o->end_ice_ping(r); - _callback->ice_response(); - } - catch(const Ice::Exception&) - { - _callback->ice_exception(SessionNotExistException()); - _router->destroySession(_connection); - } - } - -private: - const SessionRouterIPtr _router; - const AMD_Router_refreshSessionPtr _callback; - const Ice::ConnectionPtr _connection; -}; - -class ACMPingCallback : public IceUtil::Shared +shared_ptr<IPConnectionInfo> +getIPConnectionInfo(const shared_ptr<ConnectionInfo>& info) { -public: - - ACMPingCallback(const SessionRouterIPtr& router, const Ice::ConnectionPtr& connection) : - _router(router), _connection(connection) + for(shared_ptr<ConnectionInfo> p = info; p; p = p->underlying) { - } - - void - finished(const Ice::AsyncResultPtr& r) - { - Ice::ObjectPrx o = r->getProxy(); - try - { - o->end_ice_ping(r); - } - catch(const Ice::Exception&) - { - // - // Close the connection otherwise the peer has no way to know that - // the session has gone. - // - _connection->close(ICE_SCOPED_ENUM(ConnectionClose, Forcefully)); - _router->destroySession(_connection); - } - } - -private: - - const SessionRouterIPtr _router; - const Ice::ConnectionPtr _connection; -}; - -Ice::IPConnectionInfoPtr -getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) -{ - for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying) - { - Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(p); + auto ipInfo = dynamic_pointer_cast<IPConnectionInfo>(p); if(ipInfo) { return ipInfo; } } - return ICE_NULLPTR; + + return nullptr; } } @@ -105,44 +39,44 @@ getIPConnectionInfo(const Ice::ConnectionInfoPtr& info) namespace Glacier2 { -class SessionControlI : public SessionControl +class SessionControlI final : public SessionControl { public: - SessionControlI(const SessionRouterIPtr& sessionRouter, const ConnectionPtr& connection, - const FilterManagerPtr& filterManager) : - _sessionRouter(sessionRouter), - _connection(connection), - _filters(filterManager) + SessionControlI(shared_ptr<SessionRouterI> sessionRouter, shared_ptr<Connection> connection, + shared_ptr<FilterManager> filterManager) : + _sessionRouter(move(sessionRouter)), + _connection(move(connection)), + _filters(move(filterManager)) { } - virtual StringSetPrx - categories(const Current&) + shared_ptr<StringSetPrx> + categories(const Current&) override { return _filters->categoriesPrx(); } - virtual StringSetPrx - adapterIds(const Current&) + shared_ptr<StringSetPrx> + adapterIds(const Current&) override { return _filters->adapterIdsPrx(); } - virtual IdentitySetPrx - identities(const Current&) + shared_ptr<IdentitySetPrx> + identities(const Current&) override { return _filters->identitiesPrx(); } - virtual int - getSessionTimeout(const Current& current) + int + getSessionTimeout(const Current& current) override { return static_cast<int>(_sessionRouter->getSessionTimeout(current)); } - virtual void - destroy(const Current&) + void + destroy(const Current&) override { _sessionRouter->destroySession(_connection); _filters->destroy(); @@ -150,79 +84,22 @@ public: private: - const SessionRouterIPtr _sessionRouter; - const ConnectionPtr _connection; - const FilterManagerPtr _filters; + const shared_ptr<SessionRouterI> _sessionRouter; + const shared_ptr<Connection> _connection; + const shared_ptr<FilterManager> _filters; }; -class ClientLocator : public ServantLocator +class UserPasswordCreateSession final : public CreateSession { public: - ClientLocator(const SessionRouterIPtr& sessionRouter) : - _sessionRouter(sessionRouter) - { - } - - virtual ObjectPtr - locate(const Current& current, LocalObjectPtr&) - { - return _sessionRouter->getClientBlobject(current.con, current.id); - } - - virtual void - finished(const Current&, const ObjectPtr&, const LocalObjectPtr&) - { - } - - virtual void - deactivate(const std::string&) - { - } - -private: - - const SessionRouterIPtr _sessionRouter; -}; - -class ServerLocator : public ServantLocator -{ -public: - - ServerLocator(const SessionRouterIPtr& sessionRouter) : - _sessionRouter(sessionRouter) - { - } - - virtual ObjectPtr - locate(const Current& current, LocalObjectPtr&) - { - return _sessionRouter->getServerBlobject(current.id.category); - } - - virtual void - finished(const Current&, const ObjectPtr&, const LocalObjectPtr&) - { - } - - virtual void - deactivate(const std::string&) - { - } - -private: - - const SessionRouterIPtr _sessionRouter; -}; - -class UserPasswordCreateSession : public CreateSession -{ -public: - - UserPasswordCreateSession(const AMD_Router_createSessionPtr& amdCB, const string& user, const string& password, - const Ice::Current& current, const SessionRouterIPtr& sessionRouter) : + UserPasswordCreateSession(function<void(const shared_ptr<SessionPrx>&)> response, + function<void(exception_ptr)> exception, + const string& user, const string& password, + const Ice::Current& current, const shared_ptr<SessionRouterI>& sessionRouter) : CreateSession(sessionRouter, user, current), - _amdCB(amdCB), + _response(move(response)), + _exception(move(exception)), _password(password) { } @@ -232,85 +109,108 @@ public: { if(ok) { - authorized(_sessionRouter->_sessionManager); + authorized(_sessionRouter->_sessionManager != nullptr); } else { - exception(PermissionDeniedException(reason.empty() ? string("permission denied") : reason)); + exception(make_exception_ptr(PermissionDeniedException(reason.empty() ? string("permission denied") : reason))); } } void - checkPermissionsException(const Ice::Exception& ex) + checkPermissionsException(exception_ptr ex) { - if(dynamic_cast<const PermissionDeniedException*>(&ex)) + try + { + rethrow_exception(ex); + } + catch(const PermissionDeniedException&) { exception(ex); } - else + catch(...) { unexpectedAuthorizeException(ex); } } - virtual void - authorize() + void + authorize() override { assert(_sessionRouter->_verifier); - Ice::Context ctx = _current.ctx; + auto ctx = _current.ctx; ctx.insert(_context.begin(), _context.end()); - - _sessionRouter->_verifier->begin_checkPermissions(_user, _password, ctx, - newCallback_PermissionsVerifier_checkPermissions(this, - &UserPasswordCreateSession::checkPermissionsResponse, - &UserPasswordCreateSession::checkPermissionsException)); - } - - virtual FilterManagerPtr - createFilterManager() + auto self = static_pointer_cast<UserPasswordCreateSession>(shared_from_this()); + _sessionRouter->_verifier->checkPermissionsAsync(_user, _password, + [self](bool ok, const string& reason) + { + self->checkPermissionsResponse(ok, reason); + }, + [self](exception_ptr e) + { + self->checkPermissionsException(e); + }, + nullptr, + ctx); + } + + shared_ptr<FilterManager> + createFilterManager() override { return FilterManager::create(_instance, _user, true); } - virtual void - createSession() + void + createSession() override { - Ice::Context ctx = _current.ctx; + auto ctx = _current.ctx; ctx.insert(_context.begin(), _context.end()); - _sessionRouter->_sessionManager->begin_create(_user, _control, ctx, - newCallback_SessionManager_create( - static_cast<CreateSession*>(this), - &CreateSession::sessionCreated, - &CreateSession::createException)); + auto self = shared_from_this(); + _sessionRouter->_sessionManager->createAsync(_user, _control, + [self](shared_ptr<SessionPrx> response) + { + self->sessionCreated(move(response)); + }, + [self](exception_ptr e) + { + self->createException(e); + }, + nullptr, + ctx); + } - virtual void - finished(const SessionPrx& session) + void + finished(const shared_ptr<SessionPrx>& session) override { - _amdCB->ice_response(session); + _response(session); } - virtual void - finished(const Ice::Exception& ex) + void + finished(exception_ptr ex) override { - _amdCB->ice_exception(ex); + _exception(ex); } private: - const AMD_Router_createSessionPtr _amdCB; + const function<void(shared_ptr<SessionPrx>)> _response; + const function<void(exception_ptr)> _exception; const string _password; }; -class SSLCreateSession : public CreateSession +class SSLCreateSession final : public CreateSession { public: - SSLCreateSession(const AMD_Router_createSessionFromSecureConnectionPtr& amdCB, const string& user, - const SSLInfo& sslInfo, const Ice::Current& current, const SessionRouterIPtr& sessionRouter) : + SSLCreateSession(function<void(const shared_ptr<SessionPrx>& returnValue)> response, + function<void(exception_ptr)> exception, + const string& user, + const SSLInfo& sslInfo, const Ice::Current& current, const shared_ptr<SessionRouterI>& sessionRouter) : CreateSession(sessionRouter, user, current), - _amdCB(amdCB), + _response(move(response)), + _exception(move(exception)), _sslInfo(sslInfo) { } @@ -320,136 +220,108 @@ public: { if(ok) { - authorized(_sessionRouter->_sslSessionManager); + authorized(_sessionRouter->_sslSessionManager != nullptr); } else { - exception(PermissionDeniedException(reason.empty() ? string("permission denied") : reason)); + exception(make_exception_ptr(PermissionDeniedException(reason.empty() ? string("permission denied") : reason))); } } void - authorizeException(const Ice::Exception& ex) + authorizeException(exception_ptr ex) { - if(dynamic_cast<const PermissionDeniedException*>(&ex)) + try + { + rethrow_exception(ex); + } + catch(const PermissionDeniedException&) { exception(ex); } - else + catch(...) { unexpectedAuthorizeException(ex); } } - virtual void - authorize() + void + authorize() override { assert(_sessionRouter->_sslVerifier); - Ice::Context ctx = _current.ctx; + auto ctx = _current.ctx; ctx.insert(_context.begin(), _context.end()); - _sessionRouter->_sslVerifier->begin_authorize(_sslInfo, ctx, - newCallback_SSLPermissionsVerifier_authorize(this, - &SSLCreateSession::authorizeResponse, - &SSLCreateSession::authorizeException)); + + auto self = static_pointer_cast<SSLCreateSession>(shared_from_this()); + _sessionRouter->_sslVerifier->authorizeAsync(_sslInfo, + [self](bool ok, const string& reason) + { + self->authorizeResponse(ok, reason); + }, + [self](exception_ptr e) + { + self->authorizeException(e); + }, + nullptr, + ctx); } - virtual FilterManagerPtr - createFilterManager() + shared_ptr<FilterManager> + createFilterManager() override { return FilterManager::create(_instance, _user, false); } - virtual void - createSession() + void + createSession() override { - Ice::Context ctx = _current.ctx; + auto ctx = _current.ctx; ctx.insert(_context.begin(), _context.end()); - _sessionRouter->_sslSessionManager->begin_create(_sslInfo, _control, ctx, - newCallback_SSLSessionManager_create( - static_cast<CreateSession*>(this), - &CreateSession::sessionCreated, - &CreateSession::createException)); - } - virtual void - finished(const SessionPrx& session) - { - _amdCB->ice_response(session); + auto self = static_pointer_cast<SSLCreateSession>(shared_from_this()); + _sessionRouter->_sslSessionManager->createAsync(_sslInfo, _control, + [self](shared_ptr<SessionPrx> response) + { + self->sessionCreated(move(response)); + }, + [self](exception_ptr e) + { + self->createException(e); + }, + nullptr, + ctx); } - virtual void - finished(const Ice::Exception& ex) - { - _amdCB->ice_exception(ex); - } - -private: - - const AMD_Router_createSessionFromSecureConnectionPtr _amdCB; - const SSLInfo _sslInfo; -}; - -class CloseCallbackI : public Ice::CloseCallback -{ -public: - - CloseCallbackI(const SessionRouterIPtr& sessionRouter) : _sessionRouter(sessionRouter) - { - } - - virtual void - closed(const Ice::ConnectionPtr& connection) - { - try - { - _sessionRouter->destroySession(connection); - } - catch(const Ice::Exception&) - { - } - } - -private: - - const SessionRouterIPtr _sessionRouter; -}; - -class HeartbeatCallbackI : public Ice::HeartbeatCallback -{ -public: - - HeartbeatCallbackI(const SessionRouterIPtr& sessionRouter) : _sessionRouter(sessionRouter) + void + finished(const shared_ptr<SessionPrx>& session) override { + _response(session); } - virtual void - heartbeat(const Ice::ConnectionPtr& connection) + void + finished(exception_ptr ex) override { - try - { - _sessionRouter->refreshSession(connection); - } - catch(const Ice::Exception&) - { - } + _exception(ex); } private: - const SessionRouterIPtr _sessionRouter; + const function<void(const shared_ptr<SessionPrx>)> _response; + const function<void(exception_ptr)> _exception; + const SSLInfo _sslInfo; }; } -CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const string& user, const Ice::Current& current) : +CreateSession::CreateSession(shared_ptr<SessionRouterI> sessionRouter, const string& user, const Ice::Current& current) : _instance(sessionRouter->_instance), - _sessionRouter(sessionRouter), + _sessionRouter(move(sessionRouter)), _user(user), _current(current) { // Clear reserved contexts potentially set by client - Ice::Context ctx = _current.ctx; + auto ctx = _current.ctx; ctx.erase("_con.type"); ctx.erase("_con.remotePort"); ctx.erase("_con.remoteAddress"); @@ -463,7 +335,7 @@ CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const strin { _context["_con.type"] = current.con->type(); { - Ice::IPConnectionInfoPtr info = getIPConnectionInfo(current.con->getInfo()); + auto info = getIPConnectionInfo(current.con->getInfo()); if(info) { ostringstream os; @@ -476,7 +348,7 @@ CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const strin _context["_con.localAddress"] = info->localAddress; } } { - IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(current.con->getInfo()); + auto info = dynamic_pointer_cast<IceSSL::ConnectionInfo>(current.con->getInfo()); if(info) { _context["_con.cipher"] = info->cipher; @@ -494,21 +366,21 @@ CreateSession::create() { try { - if(_sessionRouter->startCreateSession(this, _current.con)) + if(_sessionRouter->startCreateSession(shared_from_this(), _current.con)) { authorize(); } } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { - finished(ex); + finished(current_exception()); } } void -CreateSession::addPendingCallback(const CreateSessionPtr& callback) +CreateSession::addPendingCallback(shared_ptr<CreateSession> callback) { - _pendingCallbacks.push_back(callback); + _pendingCallbacks.push_back(move(callback)); } void @@ -527,52 +399,62 @@ CreateSession::authorized(bool createSession) { if(_instance->serverObjectAdapter()) { - Ice::ObjectPtr obj = new SessionControlI(_sessionRouter, _current.con, _filterManager); - _control = SessionControlPrx::uncheckedCast(_instance->serverObjectAdapter()->addWithUUID(obj)); + auto obj = make_shared<SessionControlI>(_sessionRouter, _current.con, _filterManager); + _control = uncheckedCast<SessionControlPrx>(_instance->serverObjectAdapter()->addWithUUID(obj)); } this->createSession(); } else { - sessionCreated(0); + sessionCreated(nullptr); } } void -CreateSession::unexpectedAuthorizeException(const Ice::Exception& ex) +CreateSession::unexpectedAuthorizeException(exception_ptr ex) { + if(_sessionRouter->sessionTraceLevel() >= 1) { - Warning out(_instance->logger()); - out << "exception while verifying permissions:\n" << ex; + try + { + rethrow_exception(ex); + } + catch(const Ice::Exception& e) + { + Warning out(_instance->logger()); + out << "exception while verifying permissions:\n" << e; + } } - exception(PermissionDeniedException("internal server error")); + + exception(make_exception_ptr(PermissionDeniedException("internal server error"))); + } void -CreateSession::createException(const Ice::Exception& sex) +CreateSession::createException(exception_ptr sex) { try { - sex.ice_throw(); + rethrow_exception(sex); } - catch(const CannotCreateSessionException& ex) + catch(const CannotCreateSessionException&) { - exception(ex); + exception(current_exception()); } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { - unexpectedCreateSessionException(ex); + unexpectedCreateSessionException(current_exception()); } } void -CreateSession::sessionCreated(const SessionPrx& session) +CreateSession::sessionCreated(const shared_ptr<SessionPrx>& session) { // // Create the session router object. // - RouterIPtr router; + shared_ptr<RouterI> router; try { Ice::Identity ident; @@ -583,20 +465,20 @@ CreateSession::sessionCreated(const SessionPrx& session) if(_instance->properties()->getPropertyAsInt("Glacier2.AddConnectionContext") == 1) { - router = new RouterI(_instance, _current.con, _user, session, ident, _filterManager, _context); + router = make_shared<RouterI>(_instance, _current.con, _user, session, ident, _filterManager, _context); } else { - router = new RouterI(_instance, _current.con, _user, session, ident, _filterManager, Ice::Context()); + router = make_shared<RouterI>(_instance, _current.con, _user, session, ident, _filterManager, Ice::Context()); } } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { if(session) { - session->begin_destroy(); + session->destroyAsync(); } - unexpectedCreateSessionException(ex); + unexpectedCreateSessionException(current_exception()); return; } @@ -608,34 +490,41 @@ CreateSession::sessionCreated(const SessionPrx& session) _sessionRouter->finishCreateSession(_current.con, router); finished(session); } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { - finished(ex); + finished(current_exception()); } - for(vector<CreateSessionPtr>::const_iterator p = _pendingCallbacks.begin(); p != _pendingCallbacks.end(); ++p) + for(const auto& callback : _pendingCallbacks) { - (*p)->create(); + callback->create(); } } void -CreateSession::unexpectedCreateSessionException(const Ice::Exception& ex) +CreateSession::unexpectedCreateSessionException(exception_ptr ex) { if(_sessionRouter->sessionTraceLevel() >= 1) { - Trace out(_instance->logger(), "Glacier2"); - out << "exception while creating session with session manager:\n" << ex; + try + { + rethrow_exception(ex); + } + catch(const Ice::Exception& e) + { + Trace out(_instance->logger(), "Glacier2"); + out << "exception while creating session with session manager:\n" << e; + } } - exception(CannotCreateSessionException("internal server error")); + exception(make_exception_ptr(CannotCreateSessionException("internal server error"))); } void -CreateSession::exception(const Ice::Exception& ex) +CreateSession::exception(exception_ptr ex) { try { - _sessionRouter->finishCreateSession(_current.con, 0); + _sessionRouter->finishCreateSession(_current.con, nullptr); } catch(const Ice::Exception&) { @@ -654,150 +543,86 @@ CreateSession::exception(const Ice::Exception& ex) } } - for(vector<CreateSessionPtr>::const_iterator p = _pendingCallbacks.begin(); p != _pendingCallbacks.end(); ++p) + for(const auto& callback : _pendingCallbacks) { - (*p)->create(); + callback->create(); } } -SessionRouterI::SessionRouterI(const InstancePtr& instance, - const PermissionsVerifierPrx& verifier, - const SessionManagerPrx& sessionManager, - const SSLPermissionsVerifierPrx& sslVerifier, - const SSLSessionManagerPrx& sslSessionManager) : - _instance(instance), +SessionRouterI::SessionRouterI(shared_ptr<Instance> instance, + shared_ptr<PermissionsVerifierPrx> verifier, + shared_ptr<SessionManagerPrx> sessionManager, + shared_ptr<SSLPermissionsVerifierPrx> sslVerifier, + shared_ptr<SSLSessionManagerPrx> sslSessionManager) : + _instance(move(instance)), _sessionTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Trace.Session")), _rejectTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")), - _verifier(verifier), - _sessionManager(sessionManager), - _sslVerifier(sslVerifier), - _sslSessionManager(sslSessionManager), - _sessionTimeout(IceUtil::Time::seconds(_instance->properties()->getPropertyAsInt("Glacier2.SessionTimeout"))), - _closeCallback(new CloseCallbackI(this)), - _heartbeatCallback(new HeartbeatCallbackI(this)), - _sessionThread(_sessionTimeout > IceUtil::Time() ? new SessionThread(this, _sessionTimeout) : 0), - _routersByConnectionHint(_routersByConnection.end()), - _routersByCategoryHint(_routersByCategory.end()), - _sessionDestroyCallback(newCallback_Session_destroy(this, &SessionRouterI::sessionDestroyException)), + _verifier(move(verifier)), + _sessionManager(move(sessionManager)), + _sslVerifier(move(sslVerifier)), + _sslSessionManager(move(sslSessionManager)), + _routersByConnectionHint(_routersByConnection.cend()), + _routersByCategoryHint(_routersByCategory.cend()), _destroy(false) { - if(_sessionThread) - { - __setNoDelete(true); - try - { - _sessionThread->start(); - } - catch(const IceUtil::Exception&) - { - _sessionThread->destroy(); - _sessionThread = 0; - __setNoDelete(false); - throw; - } - __setNoDelete(false); - } - - try - { - // - // All other calls on the client object adapter are dispatched to - // a router servant based on connection information. - // - _instance->clientObjectAdapter()->addServantLocator(new ClientLocator(this), ""); - - // - // 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(_instance->serverObjectAdapter()) - { - _instance->serverObjectAdapter()->addServantLocator(new ServerLocator(this), ""); - } - } - catch(const Ice::ObjectAdapterDeactivatedException&) - { - // Ignore. - } - - _instance->setSessionRouter(this); } SessionRouterI::~SessionRouterI() { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); assert(_destroy); assert(_routersByConnection.empty()); assert(_routersByCategory.empty()); assert(_pending.empty()); - assert(!_sessionThread); } void SessionRouterI::destroy() { - map<ConnectionPtr, RouterIPtr> routers; - SessionThreadPtr sessionThread; - Callback_Session_destroyPtr destroyCallback; + map<shared_ptr<Connection>, shared_ptr<RouterI>> routers; { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); assert(!_destroy); _destroy = true; - notify(); _routersByConnection.swap(routers); - _routersByConnectionHint = _routersByConnection.end(); + _routersByConnectionHint = _routersByConnection.cend(); _routersByCategory.clear(); - _routersByCategoryHint = _routersByCategory.end(); - - sessionThread = _sessionThread; - _sessionThread = 0; - - _closeCallback = 0; - _heartbeatCallback = 0; - - swap(destroyCallback, _sessionDestroyCallback); // Break cyclic reference count. + _routersByCategoryHint = _routersByCategory.cend(); } // - // We destroy the routers outside the thread synchronization, to + // We destroy the routers outside the thread synchronization to // avoid deadlocks. // - for(map<ConnectionPtr, RouterIPtr>::iterator p = routers.begin(); p != routers.end(); ++p) + for(auto& router : routers) { - p->second->destroy(destroyCallback); - } - - if(sessionThread) - { - sessionThread->destroy(); - sessionThread->getThreadControl().join(); + router.second->destroy([self = shared_from_this()](exception_ptr e) { self->sessionDestroyException(e); }); } } -ObjectPrx -SessionRouterI::getClientProxy(IceUtil::Optional<bool>& hasRoutingTable, const Current& current) const +shared_ptr<ObjectPrx> +SessionRouterI::getClientProxy(Ice::optional<bool>& hasRoutingTable, const Current& current) const { return getRouter(current.con, current.id)->getClientProxy(hasRoutingTable, current); // Forward to the per-client router. } -ObjectPrx +shared_ptr<ObjectPrx> SessionRouterI::getServerProxy(const Current& current) const { return getRouter(current.con, current.id)->getServerProxy(current); // Forward to the per-client router. } ObjectProxySeq -SessionRouterI::addProxies(const ObjectProxySeq& proxies, const Current& current) +SessionRouterI::addProxies(ObjectProxySeq proxies, const Current& current) { // // Forward to the per-client router. // - return getRouter(current.con, current.id)->addProxies(proxies, current); + return getRouter(current.con, current.id)->addProxies(move(proxies), current); } string @@ -815,26 +640,34 @@ SessionRouterI::getCategoryForClient(const Ice::Current& current) const } void -SessionRouterI::createSession_async(const AMD_Router_createSessionPtr& amdCB, const std::string& userId, - const std::string& password, const Current& current) +SessionRouterI::createSessionAsync(string userId, string password, + function<void(const shared_ptr<SessionPrx>&)> response, + function<void(exception_ptr)> exception, + const Current& current) { if(!_verifier) { - amdCB->ice_exception(PermissionDeniedException("no configured permissions verifier")); + exception(make_exception_ptr(PermissionDeniedException("no configured permissions verifier"))); return; } - CreateSessionPtr session = new UserPasswordCreateSession(amdCB, userId, password, current, this); + auto session = make_shared<UserPasswordCreateSession>(move(response), + move(exception), + move(userId), + move(password), + current, + shared_from_this()); session->create(); } void -SessionRouterI::createSessionFromSecureConnection_async( - const AMD_Router_createSessionFromSecureConnectionPtr& amdCB, const Current& current) +SessionRouterI::createSessionFromSecureConnectionAsync(function<void(const std::shared_ptr<SessionPrx>&)> response, + function<void(std::exception_ptr)> exception, + const Current& current) { if(!_sslVerifier) { - amdCB->ice_exception(PermissionDeniedException("no configured ssl permissions verifier")); + exception(make_exception_ptr(PermissionDeniedException("no configured ssl permissions verifier"))); return; } @@ -846,21 +679,23 @@ SessionRouterI::createSessionFromSecureConnection_async( // try { - IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(current.con->getInfo()); + auto info = dynamic_pointer_cast<IceSSL::ConnectionInfo>(current.con->getInfo()); if(!info) { - amdCB->ice_exception(PermissionDeniedException("not ssl connection")); + exception(make_exception_ptr(PermissionDeniedException("not ssl connection"))); return; } - Ice::IPConnectionInfoPtr ipInfo = getIPConnectionInfo(info); + + auto ipInfo = getIPConnectionInfo(info); sslinfo.remotePort = ipInfo->remotePort; sslinfo.remoteHost = ipInfo->remoteAddress; sslinfo.localPort = ipInfo->localPort; sslinfo.localHost = ipInfo->localAddress; sslinfo.cipher = info->cipher; - for(std::vector<IceSSL::CertificatePtr>::const_iterator i = info->certs.begin(); i != info->certs.end(); ++i) + + for(const auto& cert : info->certs) { - sslinfo.certs.push_back((*i)->encode()); + sslinfo.certs.push_back(cert->encode()); } if(info->certs.size() > 0) { @@ -869,16 +704,16 @@ SessionRouterI::createSessionFromSecureConnection_async( } catch(const IceSSL::CertificateEncodingException&) { - amdCB->ice_exception(PermissionDeniedException("certificate encoding exception")); + exception(make_exception_ptr(PermissionDeniedException("certificate encoding exception"))); return; } catch(const Ice::LocalException&) { - amdCB->ice_exception(PermissionDeniedException("connection exception")); + exception(make_exception_ptr(PermissionDeniedException("connection exception"))); return; } - CreateSessionPtr session = new SSLCreateSession(amdCB, userDN, sslinfo, current, this); + auto session = make_shared<SSLCreateSession>(move(response), move(exception), userDN, sslinfo, current, shared_from_this()); session->create(); } @@ -889,40 +724,51 @@ SessionRouterI::destroySession(const Current& current) } void -SessionRouterI::refreshSession_async(const AMD_Router_refreshSessionPtr& callback, const Ice::Current& current) +SessionRouterI::refreshSessionAsync(function<void()> response, function<void(exception_ptr)> exception, + const Ice::Current& current) { - RouterIPtr router; + shared_ptr<RouterI> router; { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); router = getRouterImpl(current.con, current.id, false); // getRouter updates the session timestamp. if(!router) { - callback->ice_exception(SessionNotExistException()); + exception(make_exception_ptr(SessionNotExistException())); return; } } - SessionPrx session = router->getSession(); + auto session = router->getSession(); if(session) { // // Ping the session to ensure it does not timeout. // - session->begin_ice_ping(Ice::newCallback( - new PingCallback(this, callback, current.con), &PingCallback::finished)); + + session->ice_pingAsync([responseCb = move(response)] + { + responseCb(); + }, + [exceptionCb = move(exception), + sessionRouter = shared_from_this(), + connection = current.con](exception_ptr e) + { + exceptionCb(e); + sessionRouter->destroySession(connection); + }); } else { - callback->ice_response(); + response(); } } void -SessionRouterI::refreshSession(const Ice::ConnectionPtr& con) +SessionRouterI::refreshSession(const shared_ptr<Connection>& con) { - RouterIPtr router; + shared_ptr<RouterI> router; { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); router = getRouterImpl(con, Ice::Identity(), false); // getRouter updates the session timestamp. if(!router) { @@ -930,37 +776,45 @@ SessionRouterI::refreshSession(const Ice::ConnectionPtr& con) // Close the connection otherwise the peer has no way to know that the // session has gone. // - con->close(ICE_SCOPED_ENUM(ConnectionClose, Forcefully)); + con->close(ConnectionClose::Forcefully); throw SessionNotExistException(); } } - SessionPrx session = router->getSession(); + auto session = router->getSession(); if(session) { // // Ping the session to ensure it does not timeout. // - session->begin_ice_ping(Ice::newCallback(new ACMPingCallback(this, con), &ACMPingCallback::finished)); + session->ice_pingAsync(nullptr, [sessionRouter = shared_from_this(), con](exception_ptr) + { + // + // Close the connection otherwise the peer has no way to know that + // the session has gone. + // + con->close(ConnectionClose::Forcefully); + sessionRouter->destroySession(con); + }); } } void -SessionRouterI::destroySession(const ConnectionPtr& connection) +SessionRouterI::destroySession(const shared_ptr<Connection>& connection) { - RouterIPtr router; + shared_ptr<RouterI> router; { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(_destroy) { throw ObjectNotExistException(__FILE__, __LINE__); } - map<ConnectionPtr, RouterIPtr>::iterator p; + map<shared_ptr<Connection>, shared_ptr<RouterI>>::const_iterator p; - if(_routersByConnectionHint != _routersByConnection.end() && _routersByConnectionHint->first == connection) + if(_routersByConnectionHint != _routersByConnection.cend() && _routersByConnectionHint->first == connection) { p = _routersByConnectionHint; } @@ -969,7 +823,7 @@ SessionRouterI::destroySession(const ConnectionPtr& connection) p = _routersByConnection.find(connection); } - if(p == _routersByConnection.end()) + if(p == _routersByConnection.cend()) { throw SessionNotExistException(); } @@ -984,7 +838,7 @@ SessionRouterI::destroySession(const ConnectionPtr& connection) string category = router->getServerProxy(Current())->ice_getIdentity().category; assert(!category.empty()); _routersByCategory.erase(category); - _routersByCategoryHint = _routersByCategory.end(); + _routersByCategoryHint = _routersByCategory.cend(); } } @@ -997,13 +851,13 @@ SessionRouterI::destroySession(const ConnectionPtr& connection) Trace out(_instance->logger(), "Glacier2"); out << "destroying session\n" << router->toString(); } - router->destroy(_sessionDestroyCallback); + router->destroy([self = shared_from_this()](exception_ptr e) { self->sessionDestroyException(e); }); } -Ice::Long -SessionRouterI::getSessionTimeout(const Ice::Current&) const +long long int +SessionRouterI::getSessionTimeout(const Ice::Current& current) const { - return _sessionTimeout.toSeconds(); + return current.con->getACM().timeout; } int @@ -1015,51 +869,49 @@ SessionRouterI::getACMTimeout(const Ice::Current& current) const void SessionRouterI::updateSessionObservers() { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); - Glacier2::Instrumentation::RouterObserverPtr observer = _instance->getObserver(); + const auto& observer = _instance->getObserver(); assert(observer); - for(map<ConnectionPtr, RouterIPtr>::iterator p = _routersByConnection.begin(); p != _routersByConnection.end(); ++p) + for(auto& router : _routersByConnection) { - p->second->updateObserver(observer); + router.second->updateObserver(observer); } } -RouterIPtr -SessionRouterI::getRouter(const ConnectionPtr& connection, const Ice::Identity& id, bool close) const +shared_ptr<RouterI> +SessionRouterI::getRouter(const shared_ptr<Connection>& connection, const Ice::Identity& id, bool close) const { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); return getRouterImpl(connection, id, close); } -Ice::ObjectPtr -SessionRouterI::getClientBlobject(const ConnectionPtr& connection, const Ice::Identity& id) const +shared_ptr<Object> +SessionRouterI::getClientBlobject(const shared_ptr<Connection>& connection, const Ice::Identity& id) const { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); return getRouterImpl(connection, id, true)->getClientBlobject(); } -Ice::ObjectPtr +shared_ptr<Object> SessionRouterI::getServerBlobject(const string& category) const { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(_destroy) { throw ObjectNotExistException(__FILE__, __LINE__); } - map<string, RouterIPtr>& routers = const_cast<map<string, RouterIPtr>&>(_routersByCategory); - - if(_routersByCategoryHint != routers.end() && _routersByCategoryHint->first == category) + if(_routersByCategoryHint != _routersByCategory.cend() && _routersByCategoryHint->first == category) { return _routersByCategoryHint->second->getServerBlobject(); } - map<string, RouterIPtr>::iterator p = routers.find(category); + auto p = _routersByCategory.find(category); - if(p != routers.end()) + if(p != _routersByCategory.cend()) { _routersByCategoryHint = p; return p->second->getServerBlobject(); @@ -1070,66 +922,8 @@ SessionRouterI::getServerBlobject(const string& category) const } } -void -SessionRouterI::expireSessions() -{ - vector<RouterIPtr> routers; - - { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - - if(_destroy) - { - return; - } - - assert(_sessionTimeout > IceUtil::Time()); - IceUtil::Time minTimestamp = IceUtil::Time::now(IceUtil::Time::Monotonic) - _sessionTimeout; - - map<ConnectionPtr, RouterIPtr>::iterator p = _routersByConnection.begin(); - - while(p != _routersByConnection.end()) - { - if(p->second->getTimestamp() < minTimestamp) - { - RouterIPtr router = p->second; - routers.push_back(router); - - _routersByConnection.erase(p++); - _routersByConnectionHint = p; - - if(_instance->serverObjectAdapter()) - { - string category = router->getServerProxy(Current())->ice_getIdentity().category; - assert(!category.empty()); - _routersByCategory.erase(category); - _routersByCategoryHint = _routersByCategory.end(); - } - } - else - { - ++p; - } - } - } - - // - // We destroy the expired routers outside the thread - // synchronization, to avoid deadlocks. - // - for(vector<RouterIPtr>::iterator p = routers.begin(); p != routers.end(); ++p) - { - if(_sessionTraceLevel >= 1) - { - Trace out(_instance->logger(), "Glacier2"); - out << "expiring session\n" << (*p)->toString(); - } - (*p)->destroy(_sessionDestroyCallback); - } -} - -RouterIPtr -SessionRouterI::getRouterImpl(const ConnectionPtr& connection, const Ice::Identity& id, bool close) const +shared_ptr<RouterI> +SessionRouterI::getRouterImpl(const shared_ptr<Connection>& connection, const Ice::Identity& id, bool close) const { // // The connection can be null if the client tries to forward requests to @@ -1141,17 +935,15 @@ SessionRouterI::getRouterImpl(const ConnectionPtr& connection, const Ice::Identi throw ObjectNotExistException(__FILE__, __LINE__); } - map<ConnectionPtr, RouterIPtr>& routers = const_cast<map<ConnectionPtr, RouterIPtr>&>(_routersByConnection); - - if(_routersByConnectionHint != routers.end() && _routersByConnectionHint->first == connection) + if(_routersByConnectionHint != _routersByConnection.cend() && _routersByConnectionHint->first == connection) { _routersByConnectionHint->second->updateTimestamp(); return _routersByConnectionHint->second; } - map<ConnectionPtr, RouterIPtr>::iterator p = routers.find(connection); + auto p = _routersByConnection.find(connection); - if(p != routers.end()) + if(p != _routersByConnection.cend()) { _routersByConnectionHint = p; p->second->updateTimestamp(); @@ -1165,26 +957,33 @@ SessionRouterI::getRouterImpl(const ConnectionPtr& connection, const Ice::Identi out << "rejecting request, no session is associated with the connection.\n"; out << "identity: " << identityToString(id); } - connection->close(ICE_SCOPED_ENUM(ConnectionClose, Forcefully)); + connection->close(ConnectionClose::Forcefully); throw ObjectNotExistException(__FILE__, __LINE__); } - return 0; + return nullptr; } void -SessionRouterI::sessionDestroyException(const Ice::Exception& ex) +SessionRouterI::sessionDestroyException(exception_ptr ex) { if(_sessionTraceLevel > 0) { - Trace out(_instance->logger(), "Glacier2"); - out << "exception while destroying session\n" << ex; + try + { + rethrow_exception(ex); + } + catch(const Ice::Exception& e) + { + Trace out(_instance->logger(), "Glacier2"); + out << "exception while destroying session\n" << e; + } } } bool -SessionRouterI::startCreateSession(const CreateSessionPtr& cb, const ConnectionPtr& connection) +SessionRouterI::startCreateSession(const shared_ptr<CreateSession>& cb, const shared_ptr<Connection>& connection) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); if(_destroy) { @@ -1195,8 +994,8 @@ SessionRouterI::startCreateSession(const CreateSessionPtr& cb, const ConnectionP // Check whether a session already exists for the connection. // { - map<ConnectionPtr, RouterIPtr>::iterator p; - if(_routersByConnectionHint != _routersByConnection.end() && + map<shared_ptr<Connection>, shared_ptr<RouterI>>::const_iterator p; + if(_routersByConnectionHint != _routersByConnection.cend() && _routersByConnectionHint->first == connection) { p = _routersByConnectionHint; @@ -1206,13 +1005,13 @@ SessionRouterI::startCreateSession(const CreateSessionPtr& cb, const ConnectionP p = _routersByConnection.find(connection); } - if(p != _routersByConnection.end()) + if(p != _routersByConnection.cend()) { throw CannotCreateSessionException("session exists"); } } - map<ConnectionPtr, CreateSessionPtr>::iterator p = _pending.find(connection); + auto p = _pending.find(connection); if(p != _pending.end()) { // @@ -1235,16 +1034,15 @@ SessionRouterI::startCreateSession(const CreateSessionPtr& cb, const ConnectionP } void -SessionRouterI::finishCreateSession(const ConnectionPtr& connection, const RouterIPtr& router) +SessionRouterI::finishCreateSession(const shared_ptr<Connection>& connection, const shared_ptr<RouterI>& router) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + lock_guard<mutex> lg(_mutex); // // Signal other threads that we are done with trying to // establish a session for our connection; // _pending.erase(connection); - notify(); if(!router) { @@ -1253,81 +1051,48 @@ SessionRouterI::finishCreateSession(const ConnectionPtr& connection, const Route if(_destroy) { - router->destroy(_sessionDestroyCallback); + router->destroy([self = shared_from_this()](exception_ptr e) { self->sessionDestroyException(e); }); throw CannotCreateSessionException("router is shutting down"); } - _routersByConnectionHint = _routersByConnection.insert( - _routersByConnectionHint, pair<const ConnectionPtr, RouterIPtr>(connection, router)); + _routersByConnectionHint = _routersByConnection.insert(_routersByConnectionHint, {connection, router}); if(_instance->serverObjectAdapter()) { string category = router->getServerProxy(Ice::emptyCurrent)->ice_getIdentity().category; assert(!category.empty()); - pair<map<string, RouterIPtr>::iterator, bool> rc = - _routersByCategory.insert(pair<const string, RouterIPtr>(category, router)); + auto rc = _routersByCategory.insert({category, router}); assert(rc.second); _routersByCategoryHint = rc.first; } - connection->setCloseCallback(_closeCallback); - connection->setHeartbeatCallback(_heartbeatCallback); - - if(_sessionTraceLevel >= 1) - { - Trace out(_instance->logger(), "Glacier2"); - out << "created session\n" << router->toString(); - } -} - -SessionRouterI::SessionThread::SessionThread(const SessionRouterIPtr& sessionRouter, - const IceUtil::Time& sessionTimeout) : - IceUtil::Thread("Glacier2 session thread"), - _sessionRouter(sessionRouter), - _sessionTimeout(sessionTimeout) -{ -} - -SessionRouterI::SessionThread::~SessionThread() -{ - assert(!_sessionRouter); -} - -void -SessionRouterI::SessionThread::destroy() -{ - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - _sessionRouter = 0; - notify(); -} - -void -SessionRouterI::SessionThread::run() -{ - while(true) - { - SessionRouterIPtr sessionRouter; - + connection->setCloseCallback([self = shared_from_this()](const shared_ptr<Connection>& c) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - - if(!_sessionRouter) + try + { + self->destroySession(c); + } + catch(const std::exception&) { - return; } - assert(_sessionTimeout > IceUtil::Time()); - timedWait(_sessionTimeout / 4); + }); - if(!_sessionRouter) + connection->setHeartbeatCallback([self = shared_from_this()](const shared_ptr<Connection>& c) + { + try { - return; + self->refreshSession(c); } + catch(const std::exception&) + { + } + }); - sessionRouter = _sessionRouter; - } - - sessionRouter->expireSessions(); + if(_sessionTraceLevel >= 1) + { + Trace out(_instance->logger(), "Glacier2"); + out << "created session\n" << router->toString(); } } diff --git a/cpp/src/Glacier2/SessionRouterI.h b/cpp/src/Glacier2/SessionRouterI.h index 5e67e75ac49..594b5f3c50f 100644 --- a/cpp/src/Glacier2/SessionRouterI.h +++ b/cpp/src/Glacier2/SessionRouterI.h @@ -5,9 +5,6 @@ #ifndef GLACIER2_SESSION_ROUTER_I_H #define GLACIER2_SESSION_ROUTER_I_H -#include <IceUtil/Thread.h> -#include <IceUtil/Monitor.h> - #include <Ice/Ice.h> #include <Glacier2/PermissionsVerifierF.h> @@ -19,161 +16,122 @@ namespace Glacier2 { -class RouterI; -typedef IceUtil::Handle<RouterI> RouterIPtr; - -class SessionRouterI; -typedef IceUtil::Handle<SessionRouterI> SessionRouterIPtr; - class FilterManager; -typedef IceUtil::Handle<FilterManager> FilterManagerPtr; - -class CreateSession; -typedef IceUtil::Handle<CreateSession> CreateSessionPtr; - class Instance; -typedef IceUtil::Handle<Instance> InstancePtr; - -class ClientBlobject; -typedef IceUtil::Handle<ClientBlobject> ClientBlobjectPtr; - -class ServerBlobject; -typedef IceUtil::Handle<ServerBlobject> ServerBlobjectPtr; +class RouterI; +class SessionRouterI; +class SSLCreateSession; +class UserPasswordCreateSession; -class CreateSession : public IceUtil::Shared +class CreateSession : public std::enable_shared_from_this<CreateSession> { public: - CreateSession(const SessionRouterIPtr&, const std::string&, const Ice::Current&); + CreateSession(std::shared_ptr<SessionRouterI>, const std::string&, const Ice::Current&); void create(); - void addPendingCallback(const CreateSessionPtr&); + void addPendingCallback(std::shared_ptr<CreateSession>); void authorized(bool); - void unexpectedAuthorizeException(const Ice::Exception&); + void unexpectedAuthorizeException(std::exception_ptr); - void sessionCreated(const SessionPrx&); - void unexpectedCreateSessionException(const Ice::Exception&); + void sessionCreated(const std::shared_ptr<SessionPrx>&); + void unexpectedCreateSessionException(std::exception_ptr); - void exception(const Ice::Exception&); + void exception(std::exception_ptr); - void createException(const Ice::Exception&); + void createException(std::exception_ptr); virtual void authorize() = 0; virtual void createSession() = 0; - virtual FilterManagerPtr createFilterManager() = 0; - virtual void finished(const SessionPrx&) = 0; - virtual void finished(const Ice::Exception&) = 0; + virtual std::shared_ptr<FilterManager> createFilterManager() = 0; + virtual void finished(const std::shared_ptr<SessionPrx>&) = 0; + virtual void finished(std::exception_ptr) = 0; protected: - const InstancePtr _instance; - const SessionRouterIPtr _sessionRouter; + const std::shared_ptr<Instance> _instance; + const std::shared_ptr<SessionRouterI> _sessionRouter; const std::string _user; const Ice::Current _current; Ice::Context _context; - std::vector<CreateSessionPtr> _pendingCallbacks; - SessionControlPrx _control; - FilterManagerPtr _filterManager; + std::vector<std::shared_ptr<CreateSession>> _pendingCallbacks; + std::shared_ptr<SessionControlPrx> _control; + std::shared_ptr<FilterManager> _filterManager; }; -class UserPasswordCreateSession; -typedef IceUtil::Handle<UserPasswordCreateSession> UserPasswordCreateSessionPtr; - -class SSLCreateSession; -typedef IceUtil::Handle<SSLCreateSession> SSLCreateSessionPtr; - -class SessionRouterI : public Router, - public Glacier2::Instrumentation::ObserverUpdater, - private IceUtil::Monitor<IceUtil::Mutex> +class SessionRouterI final : public Router, public Glacier2::Instrumentation::ObserverUpdater, + public std::enable_shared_from_this<SessionRouterI> { public: - SessionRouterI(const InstancePtr&, const PermissionsVerifierPrx&, const SessionManagerPrx&, - const SSLPermissionsVerifierPrx&, const SSLSessionManagerPrx&); - virtual ~SessionRouterI(); + SessionRouterI(std::shared_ptr<Instance>, std::shared_ptr<PermissionsVerifierPrx>, + std::shared_ptr<SessionManagerPrx>, std::shared_ptr<SSLPermissionsVerifierPrx>, + std::shared_ptr<SSLSessionManagerPrx>); + ~SessionRouterI() override; void destroy(); - virtual Ice::ObjectPrx getClientProxy(IceUtil::Optional<bool>&, const Ice::Current&) const; - virtual Ice::ObjectPrx getServerProxy(const Ice::Current&) const; - virtual Ice::ObjectProxySeq addProxies(const Ice::ObjectProxySeq&, const Ice::Current&); - virtual std::string getCategoryForClient(const Ice::Current&) const; - virtual void createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, - const Ice::Current&); - virtual void createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, - const Ice::Current&); - virtual void refreshSession_async(const AMD_Router_refreshSessionPtr&, const Ice::Current&); - virtual void destroySession(const ::Ice::Current&); - virtual Ice::Long getSessionTimeout(const ::Ice::Current&) const; - virtual Ice::Int getACMTimeout(const ::Ice::Current&) const; - - virtual void updateSessionObservers(); - - RouterIPtr getRouter(const Ice::ConnectionPtr&, const Ice::Identity&, bool = true) const; - - Ice::ObjectPtr getClientBlobject(const Ice::ConnectionPtr&, const Ice::Identity&) const; - Ice::ObjectPtr getServerBlobject(const std::string&) const; - - void expireSessions(); - - void refreshSession(const ::Ice::ConnectionPtr&); - void destroySession(const ::Ice::ConnectionPtr&); + std::shared_ptr<Ice::ObjectPrx> getClientProxy(Ice::optional<bool>&, const Ice::Current&) const override; + std::shared_ptr<Ice::ObjectPrx> getServerProxy(const Ice::Current&) const override; + Ice::ObjectProxySeq addProxies(Ice::ObjectProxySeq, const Ice::Current&) override; + std::string getCategoryForClient(const Ice::Current&) const override; + void createSessionAsync(std::string, std::string, + std::function<void(const std::shared_ptr<SessionPrx>&)>, + std::function<void(std::exception_ptr)>, const ::Ice::Current&) override; + void createSessionFromSecureConnectionAsync( + std::function<void(const std::shared_ptr<SessionPrx>&)>, + std::function<void(std::exception_ptr)>, const ::Ice::Current&) override; + void refreshSessionAsync(std::function<void()>, + std::function<void(std::exception_ptr)>, + const ::Ice::Current&) override; + void destroySession(const ::Ice::Current&) override; + long long int getSessionTimeout(const ::Ice::Current&) const override; + int getACMTimeout(const ::Ice::Current&) const override; + + void updateSessionObservers() override; + + std::shared_ptr<RouterI> getRouter(const std::shared_ptr<Ice::Connection>&, const Ice::Identity&, bool = true) const; + + std::shared_ptr<Ice::Object> getClientBlobject(const std::shared_ptr<Ice::Connection>&, const Ice::Identity&) const; + std::shared_ptr<Ice::Object> getServerBlobject(const std::string&) const; + + void refreshSession(const std::shared_ptr<Ice::Connection>&); + void destroySession(const std::shared_ptr<Ice::Connection>&); int sessionTraceLevel() const { return _sessionTraceLevel; } private: - RouterIPtr getRouterImpl(const Ice::ConnectionPtr&, const Ice::Identity&, bool) const; + std::shared_ptr<RouterI> getRouterImpl(const std::shared_ptr<Ice::Connection>&, const Ice::Identity&, bool) const; - void sessionDestroyException(const Ice::Exception&); + void sessionDestroyException(std::exception_ptr); + + bool startCreateSession(const std::shared_ptr<CreateSession>&, const std::shared_ptr<Ice::Connection>&); + void finishCreateSession(const std::shared_ptr<Ice::Connection>&, const std::shared_ptr<RouterI>&); - bool startCreateSession(const CreateSessionPtr&, const Ice::ConnectionPtr&); - void finishCreateSession(const Ice::ConnectionPtr&, const RouterIPtr&); friend class Glacier2::CreateSession; friend class Glacier2::UserPasswordCreateSession; friend class Glacier2::SSLCreateSession; - const InstancePtr _instance; + const std::shared_ptr<Instance> _instance; const int _sessionTraceLevel; const int _rejectTraceLevel; - const PermissionsVerifierPrx _verifier; - const SessionManagerPrx _sessionManager; - const SSLPermissionsVerifierPrx _sslVerifier; - const SSLSessionManagerPrx _sslSessionManager; - - IceUtil::Time _sessionTimeout; - Ice::CloseCallbackPtr _closeCallback; - Ice::HeartbeatCallbackPtr _heartbeatCallback; + const std::shared_ptr<PermissionsVerifierPrx> _verifier; + const std::shared_ptr<SessionManagerPrx> _sessionManager; + const std::shared_ptr<SSLPermissionsVerifierPrx> _sslVerifier; + const std::shared_ptr<SSLSessionManagerPrx> _sslSessionManager; - class SessionThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> - { - public: + std::map<std::shared_ptr<Ice::Connection>, std::shared_ptr<RouterI>> _routersByConnection; + mutable std::map<std::shared_ptr<Ice::Connection>, std::shared_ptr<RouterI>>::const_iterator _routersByConnectionHint; - SessionThread(const SessionRouterIPtr&, const IceUtil::Time&); - virtual ~SessionThread(); - void destroy(); + std::map<std::string, std::shared_ptr<RouterI>> _routersByCategory; + mutable std::map<std::string, std::shared_ptr<RouterI>>::const_iterator _routersByCategoryHint; - virtual void run(); - - private: - - SessionRouterIPtr _sessionRouter; - const IceUtil::Time _sessionTimeout; - }; - typedef IceUtil::Handle<SessionThread> SessionThreadPtr; - SessionThreadPtr _sessionThread; - - std::map<Ice::ConnectionPtr, RouterIPtr> _routersByConnection; - mutable std::map<Ice::ConnectionPtr, RouterIPtr>::iterator _routersByConnectionHint; - - std::map<std::string, RouterIPtr> _routersByCategory; - mutable std::map<std::string, RouterIPtr>::iterator _routersByCategoryHint; - - std::map<Ice::ConnectionPtr, CreateSessionPtr> _pending; - - Callback_Session_destroyPtr _sessionDestroyCallback; + std::map<std::shared_ptr<Ice::Connection>, std::shared_ptr<CreateSession>> _pending; bool _destroy; + + mutable std::mutex _mutex; }; } diff --git a/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp b/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp index fa7ceb7fa3a..72ebda86ba8 100644 --- a/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp +++ b/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp @@ -5,7 +5,6 @@ #include <Glacier2/PermissionsVerifier.h> #include <IceUtil/IceUtil.h> #include <Ice/Ice.h> -#include <Ice/UniqueRef.h> #include <IceUtil/FileUtil.h> #include <IceUtil/StringUtil.h> @@ -32,6 +31,471 @@ using namespace Ice; using namespace IceInternal; using namespace Glacier2; +#ifdef ICE_CPP11_MAPPING + +namespace +{ + +#if defined(__APPLE__) +template <typename T> +struct CFTypeRefDeleter +{ + using pointer = T; // This is used by std::unique_ptr to determine the type + void operator()(T ref) + { + CFRelease(ref); + } +}; +#endif + +class CryptPermissionsVerifierI final : public PermissionsVerifier +{ +public: + + CryptPermissionsVerifierI(const map<string, string>&); + + bool checkPermissions(string, string, string&, const Ice::Current&) const override; + +private: + + const map<string, string> _passwords; + mutex _cryptMutex; // for old thread-unsafe crypt() +}; + +class CryptPermissionsVerifierPlugin final : public Ice::Plugin +{ +public: + + CryptPermissionsVerifierPlugin(shared_ptr<Communicator>); + + void initialize() override; + void destroy() override; + +private: + + shared_ptr<Communicator> _communicator; +}; + +map<string, string> +retrievePasswordMap(const string& file) +{ + ifstream passwordFile(IceUtilInternal::streamFilename(file).c_str()); + if(!passwordFile) + { + string err = IceUtilInternal::lastErrorToString(); + throw Ice::InitializationException(__FILE__, __LINE__, "cannot open `" + file + "' for reading: " + err); + } + map<string, string> passwords; + + while(true) + { + string userId; + passwordFile >> userId; + if(!passwordFile) + { + break; + } + + string password; + passwordFile >> password; + if(!passwordFile) + { + break; + } + + assert(!userId.empty()); + assert(!password.empty()); + passwords.insert(make_pair(userId, password)); + } + return passwords; +} + +CryptPermissionsVerifierI::CryptPermissionsVerifierI(const map<string, string>& passwords) : + _passwords(passwords) +{ +} + +namespace +{ + +#if defined(__APPLE__) || defined(_WIN32) + +const string padBytes0 = ""; +const string padBytes1 = "="; +const string padBytes2 = "=="; + +inline string +paddingBytes(size_t length) +{ + switch(length % 4) + { + case 2: + { + return padBytes2; + } + case 3: + { + return padBytes1; + } + default: + { + return padBytes0; + } + } +} +#endif + +} +bool +CryptPermissionsVerifierI::checkPermissions(string userId, string password, string&, const Current&) const +{ + map<string, string>::const_iterator p = _passwords.find(userId); + + if(p == _passwords.end()) + { + return false; + } +#if defined(__GLIBC__) || defined(__FreeBSD__) + size_t i = p->second.rfind('$'); + string salt; + if(i == string::npos) + { + // + // Crypt DES + // + if(p->second.size() != 13) // DES passwords are 13 characters long. + { + return false; + } + salt = p->second.substr(0, 2); + } + else + { + salt = p->second.substr(0, i + 1); + if(salt.empty()) + { + return false; + } + } +# if defined(__GLIBC__) + struct crypt_data data; + data.initialized = 0; + return p->second == crypt_r(password.c_str(), salt.c_str(), &data); +# else + lock_guard<mutex> lg(_cryptMutex); + return p->second == crypt(password.c_str(), salt.c_str()); +# endif +#elif defined(__APPLE__) || defined(_WIN32) + // + // Pbkdf2 string format: + // + // $pbkdf2-digest$rounds$salt$checksum + // $pbkdf2$rounds$salt$checksum (SHA1 digest) + // + size_t beg = 0; + size_t end = 0; + + // + // Determine the digest algorithm + // +# if defined(__APPLE__) + CCPseudoRandomAlgorithm algorithmId = 0; +# else + LPCWSTR algorithmId = 0; +# endif + size_t checksumLength = 0; + + const string pbkdf2SHA1Token = "$pbkdf2$"; + + if(p->second.find(pbkdf2SHA1Token) == 0) + { +# if defined(__APPLE__) + algorithmId = kCCPRFHmacAlgSHA1; +# else + algorithmId = BCRYPT_SHA1_ALGORITHM; +# endif + checksumLength = 20; + beg = pbkdf2SHA1Token.size(); + } + else + { + // + // Pbkdf2 string format: + // + // $pbkdf2-digest$rounds$salt$checksum + // + const string pbkdf2Token = "$pbkdf2-"; + if(p->second.find(pbkdf2Token) != 0) + { + return false; // PBKDF2 start token not found + } + + beg = pbkdf2Token.size(); + end = p->second.find('$', beg); + if(end == string::npos) + { + return false; // Digest algorithm end token not found + } + + if(p->second.substr(beg, (end - beg)) == "sha256") + { +# if defined(__APPLE__) + algorithmId = kCCPRFHmacAlgSHA256; +# else + algorithmId = BCRYPT_SHA256_ALGORITHM; +# endif + checksumLength = 32; + } + else if(p->second.substr(beg, (end - beg)) == "sha512") + { +# if defined(__APPLE__) + algorithmId = kCCPRFHmacAlgSHA512; +# else + algorithmId = BCRYPT_SHA512_ALGORITHM; +# endif + checksumLength = 64; + } + else + { + return false; // Invalid digest algorithm + } + beg = end + 1; + } + // + // Determine the number of rounds + // + end = p->second.find('$', beg); + if(end == string::npos) + { + return false; // Rounds end token not found + } + + IceUtil::Int64 rounds = 0; + if(!IceUtilInternal::stringToInt64(p->second.substr(beg, (end - beg)), rounds)) + { + return false; // Invalid rounds value + } + + // + // Determine salt and checksum + // + beg = end + 1; + end = p->second.find('$', beg); + if(end == string::npos) + { + return false; // Salt value end token not found + } + + string salt = p->second.substr(beg, (end - beg)); + string checksum = p->second.substr(end + 1); + if(checksum.empty()) + { + return false; + } + + // + // passlib encoding is identical to base64 except that it uses . instead of +, + // and omits trailing padding = and whitepsace. + // + std::replace(salt.begin(), salt.end(), '.', '+'); + salt += paddingBytes(salt.size()); + + std::replace(checksum.begin(), checksum.end(), '.', '+'); + checksum += paddingBytes(checksum.size()); +# if defined(__APPLE__) + CFErrorRef error = nullptr; + unique_ptr<SecTransformRef, CFTypeRefDeleter<SecTransformRef>> decoder(SecDecodeTransformCreate(kSecBase64Encoding, &error)); + + if(error) + { + CFRelease(error); + return false; + } + + unique_ptr<CFDataRef, CFTypeRefDeleter<CFDataRef>> data(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast<const uint8_t*>(salt.c_str()), + static_cast<CFIndex>(salt.size()), + kCFAllocatorNull)); + + SecTransformSetAttribute(decoder.get(), kSecTransformInputAttributeName, data.get(), &error); + if(error) + { + CFRelease(error); + return false; + } + + unique_ptr<CFDataRef, CFTypeRefDeleter<CFDataRef>> saltBuffer(static_cast<CFDataRef>(SecTransformExecute(decoder.get(), &error))); + if(error) + { + CFRelease(error); + return false; + } + + vector<uint8_t> checksumBuffer1(checksumLength); + OSStatus status = CCKeyDerivationPBKDF(kCCPBKDF2, + password.c_str(), + password.size(), + CFDataGetBytePtr(saltBuffer.get()), + static_cast<size_t>(CFDataGetLength(saltBuffer.get())), + algorithmId, + static_cast<unsigned int>(rounds), + checksumBuffer1.data(), + checksumLength); + if(status != errSecSuccess) + { + return false; + } + + decoder.reset(SecDecodeTransformCreate(kSecBase64Encoding, &error)); + if(error) + { + CFRelease(error); + return false; + } + data.reset(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast<const uint8_t*>(checksum.c_str()), + static_cast<CFIndex>(checksum.size()), + kCFAllocatorNull)); + SecTransformSetAttribute(decoder.get(), kSecTransformInputAttributeName, data.get(), &error); + if(error) + { + CFRelease(error); + return false; + } + + data.reset(static_cast<CFDataRef>(SecTransformExecute(decoder.get(), &error))); + if(error) + { + CFRelease(error); + return false; + } + + vector<uint8_t> checksumBuffer2(CFDataGetBytePtr(data.get()), CFDataGetBytePtr(data.get()) + CFDataGetLength(data.get())); + return checksumBuffer1 == checksumBuffer2; +# else + DWORD saltLength = static_cast<DWORD>(salt.size()); + vector<BYTE> saltBuffer(saltLength); + + if(!CryptStringToBinary(salt.c_str(), static_cast<DWORD>(salt.size()), CRYPT_STRING_BASE64, &saltBuffer[0], &saltLength, 0, 0)) + { + return false; + } + saltBuffer.resize(saltLength); + + BCRYPT_ALG_HANDLE algorithmHandle = 0; + if(BCryptOpenAlgorithmProvider(&algorithmHandle, algorithmId, 0, BCRYPT_ALG_HANDLE_HMAC_FLAG) != 0) + { + return false; + } + + vector<BYTE> checksumBuffer1(checksumLength); + + vector<BYTE> passwordBuffer(password.begin(), password.end()); + + DWORD status = BCryptDeriveKeyPBKDF2(algorithmHandle, &passwordBuffer[0], + static_cast<DWORD>(passwordBuffer.size()), + &saltBuffer[0], saltLength, rounds, + &checksumBuffer1[0], static_cast<DWORD>(checksumLength), 0); + + BCryptCloseAlgorithmProvider(algorithmHandle, 0); + + if(status != 0) + { + return false; + } + + DWORD checksumBuffer2Length = static_cast<DWORD>(checksumLength); + vector<BYTE> checksumBuffer2(checksumLength); + + if(!CryptStringToBinary(checksum.c_str(), static_cast<DWORD>(checksum.size()), + CRYPT_STRING_BASE64, &checksumBuffer2[0], + &checksumBuffer2Length, 0, 0)) + { + return false; + } + return checksumBuffer1 == checksumBuffer2; +# endif +#else + // Fallback to plain crypt() - DES-style + + if(p->second.size() != 13) + { + return false; + } + string salt = p->second.substr(0, 2); + + lock_guard<mutex> lg(_cryptMutex); + return p->second == crypt(password.c_str(), salt.c_str()); + +#endif +} + +CryptPermissionsVerifierPlugin::CryptPermissionsVerifierPlugin(shared_ptr<Communicator> communicator) : + _communicator(move(communicator)) +{ +} + +void +CryptPermissionsVerifierPlugin::initialize() +{ + const string prefix = "Glacier2CryptPermissionsVerifier."; + const PropertyDict props = _communicator->getProperties()->getPropertiesForPrefix(prefix); + + if(!props.empty()) + { + ObjectAdapterPtr adapter = _communicator->createObjectAdapter(""); // colloc-only adapter + + // Each prop represents a property to set + the associated password file + for(const auto& prop : props) + { + string name = prop.first.substr(prefix.size()); + Identity id = { Ice::generateUUID(), "Glacier2CryptPermissionsVerifier" }; + auto prx = adapter->add(make_shared<CryptPermissionsVerifierI>(retrievePasswordMap(prop.second)), id); + _communicator->getProperties()->setProperty(name, _communicator->proxyToString(prx)); + } + + adapter->activate(); + } +} + +void +CryptPermissionsVerifierPlugin::destroy() +{ +} + +} + +#ifndef CRYPT_PERMISSIONS_VERIFIER_API +# ifdef CRYPT_PERMISSIONS_VERIFIER_API_EXPORTS +# define CRYPT_PERMISSIONS_VERIFIER_API ICE_DECLSPEC_EXPORT +# else +# define CRYPT_PERMISSIONS_VERIFIER_API /**/ +# endif +#endif + +// +// Plug-in factory function. +// +extern "C" +{ + +CRYPT_PERMISSIONS_VERIFIER_API Ice::Plugin* +createCryptPermissionsVerifier(const shared_ptr<Communicator>& communicator, const string& name, const StringSeq& args) +{ + if(args.size() > 0) + { + Error out(communicator->getLogger()); + out << "Plugin " << name << ": too many arguments"; + return 0; + } + + return new CryptPermissionsVerifierPlugin(communicator); +} + +} + +#else + namespace { @@ -574,3 +1038,5 @@ createCryptPermissionsVerifier(const CommunicatorPtr& communicator, const string } } + +#endif diff --git a/cpp/src/Glacier2Lib/Application.cpp b/cpp/src/Glacier2Lib/Application.cpp deleted file mode 100644 index ef330e41e88..00000000000 --- a/cpp/src/Glacier2Lib/Application.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include <Glacier2/Application.h> -#include <Ice/Ice.h> -#include <IceUtil/IceUtil.h> -#include <Ice/ArgVector.h> - -using namespace std; -using namespace Ice; - -Ice::ObjectAdapterPtr Glacier2::Application::_adapter; -Glacier2::RouterPrxPtr Glacier2::Application::_router; -Glacier2::SessionPrxPtr Glacier2::Application::_session; -string Glacier2::Application::_category; - -namespace -{ -#ifndef ICE_CPP11_MAPPING // C++98 -class CloseCallbackI : public Ice::CloseCallback -{ -public: - - CloseCallbackI(Glacier2::Application* app) : _app(app) - { - } - - virtual void - closed(const Ice::ConnectionPtr&) - { - _app->sessionDestroyed(); - } - -private: - - Glacier2::Application* _app; -}; -#endif -} - -string -Glacier2::RestartSessionException::ice_id() const -{ - return "::Glacier2::RestartSessionException"; -} - -#ifndef ICE_CPP11_MAPPING -Glacier2::RestartSessionException* -Glacier2::RestartSessionException::ice_clone() const -{ - return new RestartSessionException(*this); -} -#endif - -Glacier2::Application::Application(SignalPolicy signalPolicy) : - Ice::Application(signalPolicy) -{ -} - -Ice::ObjectAdapterPtr -Glacier2::Application::objectAdapter() -{ - if(!_router) - { - throw SessionNotExistException(); - } - - IceUtil::Mutex::Lock lock(_mutex); - if(!_adapter) - { - _adapter = communicator()->createObjectAdapterWithRouter("", _router); - _adapter->activate(); - } - return _adapter; -} - -Ice::ObjectPrxPtr -Glacier2::Application::addWithUUID(const Ice::ObjectPtr& servant) -{ - return objectAdapter()->add(servant, createCallbackIdentity(Ice::generateUUID())); -} - -Ice::Identity -Glacier2::Application::createCallbackIdentity(const string& name) -{ - Ice::Identity id; - id.name = name; - id.category = categoryForClient(); - return id; -} - -void -Glacier2::Application::sessionDestroyed() -{ -} - -void -Glacier2::Application::restart() -{ - throw RestartSessionException(); -} - -Glacier2::RouterPrxPtr -Glacier2::Application::router() -{ - return _router; -} - -Glacier2::SessionPrxPtr -Glacier2::Application::session() -{ - return _session; -} - -std::string -Glacier2::Application::categoryForClient() -{ - if(!_router) - { - throw SessionNotExistException(); - } - return _category; -} - -int -Glacier2::Application::doMain(int argc, char* argv[], const Ice::InitializationData& initData, int version) -{ - // Set the default properties for all Glacier2 applications. - initData.properties->setProperty("Ice.RetryIntervals", "-1"); - - bool restart; - int ret = 0; - do - { - // - // A copy of the initialization data and the string seq - // needs to be passed to doMainInternal, as these can be - // changed by the application. - // - Ice::InitializationData id(initData); - id.properties = id.properties->clone(); - Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); - - restart = doMain(args, id, ret, version); - } - while(restart); - return ret; -} - -bool -Glacier2::Application::doMain(Ice::StringSeq& args, const Ice::InitializationData& initData, int& status, int version) -{ - // - // Reset internal state variables from Ice.Application. The - // remainder are reset at the end of this method. - // - _callbackInProgress = false; - _destroyed = false; - _interrupted = false; - - bool restart = false; - bool sessionCreated = false; - status = 0; - - try - { - _communicator = Ice::initialize(args, initData, version); - _router = ICE_UNCHECKED_CAST(Glacier2::RouterPrx, communicator()->getDefaultRouter()); - - if(!_router) - { - Error out(getProcessLogger()); - out << _appName << ": no glacier2 router configured"; - status = 1; - } - else - { - // - // The default is to destroy when a signal is received. - // - if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) - { - destroyOnInterrupt(); - } - - // If createSession throws, we're done. - try - { - _session = createSession(); - sessionCreated = true; - } - catch(const Ice::LocalException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - status = 1; - } - - if(sessionCreated) - { - Ice::Int acmTimeout = 0; - try - { - acmTimeout = _router->getACMTimeout(); - } - catch(const Ice::OperationNotExistException&) - { - } - if(acmTimeout <= 0) - { - acmTimeout = static_cast<Ice::Int>(_router->getSessionTimeout()); - } - - if(acmTimeout > 0) - { - Ice::ConnectionPtr connection = _router->ice_getCachedConnection(); - assert(connection); - connection->setACM(acmTimeout, IceUtil::None, ICE_ENUM(ACMHeartbeat, HeartbeatAlways)); -#ifdef ICE_CPP11_MAPPING - connection->setCloseCallback( - [this](Ice::ConnectionPtr) - { - sessionDestroyed(); - }); -#else - connection->setCloseCallback(ICE_MAKE_SHARED(CloseCallbackI, this)); -#endif - } - - _category = _router->getCategoryForClient(); - IceInternal::ArgVector a(args); - status = runWithSession(a.argc, a.argv); - } - } - } - // We want to restart on those exceptions which indicate a - // break down in communications, but not those exceptions that - // indicate a programming logic error (ie: marshal, protocol - // failure, etc). - catch(const RestartSessionException&) - { - restart = true; - } - catch(const Ice::ConnectionRefusedException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - restart = true; - } - catch(const Ice::ConnectionLostException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - restart = true; - } - catch(const Ice::UnknownLocalException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - restart = true; - } - catch(const Ice::RequestFailedException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - restart = true; - } - catch(const Ice::TimeoutException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - restart = true; - } - catch(const Ice::LocalException& ex) - { - Error out(getProcessLogger()); - out << _appName << ": " << ex; - status = 1; - } - catch(const std::exception& ex) - { - Error out(getProcessLogger()); - out << _appName << ": std::exception " << ex; - status = 1; - } - catch(const std::string& ex) - { - Error out(getProcessLogger()); - out << _appName << ": c++ exception " << ex; - status = 1; - } - catch(const char* ex) - { - Error out(getProcessLogger()); - out << _appName << ": char* exception " << ex; - status = 1; - } - catch(...) - { - Error out(getProcessLogger()); - out << _appName << ": unknown exception"; - status = 1; - } - - // - // Don't want any new interrupt and at this point (post-run), - // it would not make sense to release a held signal to run - // shutdown or destroy. - // - if(_signalPolicy == ICE_ENUM(SignalPolicy, HandleSignals)) - { - ignoreInterrupt(); - } - - { - IceUtil::Mutex::Lock lock(_mutex); - while(_callbackInProgress) - { - _condVar.wait(lock); - } - if(_destroyed) - { - _communicator = 0; - } - else - { - _destroyed = true; - // - // And _communicator != 0, meaning will be destroyed - // next, _destroyed = true also ensures that any - // remaining callback won't do anything - // - } - _application = 0; - } - - if(sessionCreated && _router) - { - try - { - _router->destroySession(); - } - catch(const Ice::ConnectionLostException&) - { - // Expected if another thread invoked on an object from the session concurrently. - } - catch(const Glacier2::SessionNotExistException&) - { - // This can also occur. - } - catch(const exception& ex) - { - // Not expected. - Error out(getProcessLogger()); - out << "unexpected exception when destroying the session:\n" << ex; - } - _router = 0; - } - - if(_communicator) - { - _communicator->destroy(); - _communicator = 0; - } - - // - // Reset internal state. We cannot reset the Application state - // here, since _destroyed must remain true until we re-run - // this method. - // - _adapter = 0; - _router = 0; - _session = 0; - _category.clear(); - - return restart; -} diff --git a/cpp/src/Glacier2Lib/SessionHelper.cpp b/cpp/src/Glacier2Lib/SessionHelper.cpp index 4a3f384a2cb..8f154f7fc93 100644 --- a/cpp/src/Glacier2Lib/SessionHelper.cpp +++ b/cpp/src/Glacier2Lib/SessionHelper.cpp @@ -583,10 +583,10 @@ public: { if(!communicator->getDefaultRouter()) { - Ice::RouterFinderPrxPtr finder; + Ice::RouterFinderPrxPtr finder = + ICE_UNCHECKED_CAST(Ice::RouterFinderPrx, communicator->stringToProxy(_finder)); try { - finder = ICE_UNCHECKED_CAST(Ice::RouterFinderPrx, communicator->stringToProxy(_finder)); communicator->setDefaultRouter(finder->getRouter()); } catch(const Ice::CommunicatorDestroyedException& ex) @@ -1158,7 +1158,6 @@ Glacier2::SessionFactoryHelper::createInitData() initData.properties->setProperty("Ice.Default.Router", createProxyStr(_identity)); } -#ifndef ICE_OS_UWP // // If using a secure connection setup the IceSSL plug-in, if IceSSL // plug-in has already been setup we don't want to override the @@ -1169,8 +1168,6 @@ Glacier2::SessionFactoryHelper::createInitData() { initData.properties->setProperty("Ice.Plugin.IceSSL","IceSSL:createIceSSL"); } -#endif - return initData; } diff --git a/cpp/src/IceBox/Admin.cpp b/cpp/src/IceBox/Admin.cpp index eef5f77850e..40849a0a8ef 100644 --- a/cpp/src/IceBox/Admin.cpp +++ b/cpp/src/IceBox/Admin.cpp @@ -31,7 +31,7 @@ main(int argc, char* argv[]) try { - Ice::CtrlCHandler ctrlCHandler; + IceUtil::CtrlCHandler ctrlCHandler; Ice::CommunicatorHolder ich(argc, argv); communicator = ich.communicator(); diff --git a/cpp/src/IceBridge/IceBridge.cpp b/cpp/src/IceBridge/IceBridge.cpp index 5619360615d..18a23e4027e 100644 --- a/cpp/src/IceBridge/IceBridge.cpp +++ b/cpp/src/IceBridge/IceBridge.cpp @@ -13,124 +13,49 @@ using namespace Ice; namespace { - -// -// Represents a pending invocation. -// -class Invocation : public IceUtil::Shared -{ -public: - - Invocation(const AMD_Object_ice_invokePtr& cb) : - _cb(cb) - { - } - - void success(bool ok, const pair<const Byte*, const Byte*>& results) - { - _cb->ice_response(ok, results); - } - - void exception(const Exception& ex) - { - _cb->ice_exception(ex); - } - - void sent(bool) - { - _cb->ice_response(true, vector<Byte>()); // For oneway invocations - } - -private: - - const AMD_Object_ice_invokePtr _cb; -}; -typedef IceUtil::Handle<Invocation> InvocationPtr; - // -// Holds information about an incoming invocation that's been queued until an outgoing connection has +// Holds information about an incoming dispatch that's been queued until an outgoing connection has // been established. // -struct QueuedInvocation : public IceUtil::Shared +struct QueuedDispatch final { // - // The pointers in paramData refer to the Ice marshaling buffer and won't remain valid after - // ice_invoke_async completes, so we have to make a copy of the parameter data. + // The pointers in p refer to the Ice marshaling buffer and won't remain valid after + // ice_invokeAsync completes, so we have to make a copy of the in parameters // - QueuedInvocation(const AMD_Object_ice_invokePtr& c, const pair<const Byte*, const Byte*>& p, const Current& curr) : - cb(c), paramData(p.first, p.second), current(curr) + QueuedDispatch(pair<const Byte*, const Byte*> p, + function<void(bool, const pair<const Byte*, const Byte*>&)>&& r, + function<void(exception_ptr)>&& e, + const Current& c) : + inParams(p.first, p.second), response(move(r)), error(move(e)), current(c) { } - const AMD_Object_ice_invokePtr cb; - const vector<Byte> paramData; - const Current current; -}; -typedef IceUtil::Handle<QueuedInvocation> QueuedInvocationPtr; + QueuedDispatch(QueuedDispatch&&) = default; -// -// Relays heartbeat messages. -// -class HeartbeatCallbackI : public HeartbeatCallback -{ -public: - - HeartbeatCallbackI(const ConnectionPtr&); - - virtual void heartbeat(const ConnectionPtr&); - -private: - - const ConnectionPtr _connection; -}; - -class BridgeI; -typedef IceUtil::Handle<BridgeI> BridgeIPtr; - -class BridgeConnection; -typedef IceUtil::Handle<BridgeConnection> BridgeConnectionPtr; - -class CloseCallbackI : public CloseCallback -{ -public: - - CloseCallbackI(const BridgeIPtr&); - - virtual void closed(const ConnectionPtr&); - -private: - - const BridgeIPtr _bridge; -}; - -class GetConnectionCallback : public IceUtil::Shared -{ -public: - - GetConnectionCallback(const BridgeIPtr&, const BridgeConnectionPtr&); - void success(const ConnectionPtr&); - void exception(const Exception&); - -private: + // Make sure we don't copy this struct by accident + QueuedDispatch(const QueuedDispatch&) = delete; - const BridgeIPtr _bridge; - const BridgeConnectionPtr _bc; + const vector<Byte> inParams; + function<void(bool, const pair<const Byte*, const Byte*>&)> response; + function<void(exception_ptr)> error; + const Current current; }; // // Allows the bridge to be used as an Ice router. // -class RouterI : public Router +class RouterI final : public Router { public: - virtual ObjectPrx getClientProxy(IceUtil::Optional<bool>& hasRoutingTable, const Current&) const + shared_ptr<ObjectPrx> getClientProxy(Ice::optional<bool>& hasRoutingTable, const Current&) const override { hasRoutingTable = false; // We don't maintain a routing table, no need to call addProxies on this impl. - return 0; + return nullptr; } - virtual ObjectPrx getServerProxy(const Current& current) const + shared_ptr<ObjectPrx> getServerProxy(const Current& current) const override { // // We return a non-nil dummy proxy here so that a client is able to configure its @@ -139,107 +64,107 @@ public: return current.adapter->getCommunicator()->stringToProxy("dummy"); } - virtual ObjectProxySeq addProxies(const ObjectProxySeq&, const Current&) + ObjectProxySeq addProxies(ObjectProxySeq, const Current&) override { return ObjectProxySeq(); } }; -class FinderI : public RouterFinder +class FinderI final : public RouterFinder { public: - FinderI(const RouterPrx& router) : - _router(router) + FinderI(shared_ptr<RouterPrx> router) : + _router(move(router)) { } - virtual RouterPrx getRouter(const Current&) + shared_ptr<RouterPrx> getRouter(const Current&) override { return _router; } private: - const RouterPrx _router; + const shared_ptr<RouterPrx> _router; }; // -// Represents a pair of bridged connections. +// Represents a pair of connections (shared object) // -class BridgeConnection : public IceUtil::Shared +class BridgeConnection final { public: - BridgeConnection(const ObjectAdapterPtr&, const ObjectPrx&, const ConnectionPtr&); - - void outgoingSuccess(const ConnectionPtr&); - void outgoingException(const Exception&); + BridgeConnection(shared_ptr<ObjectAdapter>, shared_ptr<ObjectPrx>, shared_ptr<Connection>); - void closed(const ConnectionPtr&); - void dispatch(const AMD_Object_ice_invokePtr&, const pair<const Byte*, const Byte*>&, const Current&); + void outgoingSuccess(shared_ptr<Connection>); + void outgoingException(exception_ptr); + void closed(const shared_ptr<Connection>&); + void dispatch(pair<const Byte*, const Byte*>, + function<void(bool, const pair<const Byte*, const Byte*>&)>, + function<void(exception_ptr)>, + const Current&); private: - void send(const ConnectionPtr&, - const AMD_Object_ice_invokePtr&, - const pair<const Byte*, const Byte*>&, - const Current&); + void send(const shared_ptr<Connection>&, + pair<const Byte*, const Byte*>, + function<void(bool, const pair<const Byte*, const Byte*>&)>, + function<void(exception_ptr)>, + const Current& current); - const ObjectAdapterPtr _adapter; - const ObjectPrx _target; - const ConnectionPtr _incoming; + const shared_ptr<ObjectAdapter> _adapter; + const shared_ptr<ObjectPrx> _target; + const shared_ptr<Connection> _incoming; - IceUtil::Mutex _lock; - ConnectionPtr _outgoing; - IceInternal::UniquePtr<Exception> _exception; + std::mutex _lock; + shared_ptr<Connection> _outgoing; + exception_ptr _exception; // - // We maintain our own queue for invocations that arrive on the incoming connection before the outgoing + // We maintain our own queue for dispatches that arrive on the incoming connection before the outgoing // connection has been established. We don't want to forward these to proxies and let the proxies handle // the queuing because then the invocations could be sent out of order (e.g., when invocations are split // among twoway/oneway/datagram proxies). // - vector<QueuedInvocationPtr> _queue; + vector<QueuedDispatch> _queue; }; // // The main bridge servant. // -class BridgeI : public Ice::BlobjectArrayAsync +class BridgeI final : public Ice::BlobjectArrayAsync, public enable_shared_from_this<BridgeI> { public: - BridgeI(const ObjectAdapterPtr& adapter, const ObjectPrx& target); + BridgeI(shared_ptr<ObjectAdapter> adapter, shared_ptr<ObjectPrx> target); - virtual void ice_invoke_async(const AMD_Object_ice_invokePtr&, - const std::pair<const Byte*, const Byte*>&, - const Current&); + void ice_invokeAsync(pair<const Byte*, const Byte*> inEncaps, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, + const Current& current) override; - void closed(const ConnectionPtr&); - void outgoingSuccess(const BridgeConnectionPtr&, const ConnectionPtr&); - void outgoingException(const BridgeConnectionPtr&, const Exception&); + void closed(const shared_ptr<Connection>&); + void outgoingSuccess(const shared_ptr<BridgeConnection>&, shared_ptr<Connection>); + void outgoingException(const shared_ptr<BridgeConnection>&, exception_ptr); private: - const ObjectAdapterPtr _adapter; - const ObjectPrx _target; + const shared_ptr<ObjectAdapter> _adapter; + const shared_ptr<ObjectPrx> _target; - IceUtil::Mutex _lock; - map<ConnectionPtr, BridgeConnectionPtr> _connections; + std::mutex _lock; + map<shared_ptr<Connection>, shared_ptr<BridgeConnection>> _connections; }; -class BridgeService : public Service +class BridgeService final : public Service { -public: - - BridgeService(); - protected: - virtual bool start(int, char*[], int&); - virtual bool stop(); - virtual CommunicatorPtr initializeCommunicator(int&, char*[], const InitializationData&, int); + bool start(int, char*[], int&) override; + bool stop() override; + shared_ptr<Communicator> initializeCommunicator(int&, char*[], const InitializationData&, int) override; private: @@ -248,63 +173,17 @@ private: } -HeartbeatCallbackI::HeartbeatCallbackI(const ConnectionPtr& con) : - _connection(con) -{ -} - -void -HeartbeatCallbackI::heartbeat(const ConnectionPtr&) -{ - // - // When a connection receives a heartbeat message, we send one over its corresponding connection. - // - try - { - _connection->begin_heartbeat(); - } - catch(...) - { - } -} - -CloseCallbackI::CloseCallbackI(const BridgeIPtr& bridge) : - _bridge(bridge) -{ -} - -void -CloseCallbackI::closed(const ConnectionPtr& con) -{ - _bridge->closed(con); -} - -GetConnectionCallback::GetConnectionCallback(const BridgeIPtr& bridge, const BridgeConnectionPtr& bc) : - _bridge(bridge), _bc(bc) -{ -} - -void -GetConnectionCallback::success(const ConnectionPtr& outgoing) +BridgeConnection::BridgeConnection(shared_ptr<ObjectAdapter> adapter, + shared_ptr<ObjectPrx> target, + shared_ptr<Connection> inc) : + _adapter(move(adapter)), _target(move(target)), _incoming(move(inc)) { - _bridge->outgoingSuccess(_bc, outgoing); } void -GetConnectionCallback::exception(const Exception& ex) +BridgeConnection::outgoingSuccess(shared_ptr<Connection> outgoing) { - _bridge->outgoingException(_bc, ex); -} - -BridgeConnection::BridgeConnection(const ObjectAdapterPtr& adapter, const ObjectPrx& target, const ConnectionPtr& inc) : - _adapter(adapter), _target(target), _incoming(inc) -{ -} - -void -BridgeConnection::outgoingSuccess(const ConnectionPtr& outgoing) -{ - IceUtil::Mutex::Lock lock(_lock); + lock_guard<mutex> lg(_lock); assert(!_outgoing && outgoing); if(_exception) { @@ -312,17 +191,36 @@ BridgeConnection::outgoingSuccess(const ConnectionPtr& outgoing) // The incoming connection is already closed. There's no point in leaving the outgoing // connection open. // - outgoing->close(ICE_SCOPED_ENUM(ConnectionClose, Gracefully)); + outgoing->close(ConnectionClose::Gracefully); return; } - _outgoing = outgoing; + _outgoing = move(outgoing); // // Register hearbeat callbacks on both connections. // - _incoming->setHeartbeatCallback(new HeartbeatCallbackI(_outgoing)); - _outgoing->setHeartbeatCallback(new HeartbeatCallbackI(_incoming)); + _incoming->setHeartbeatCallback([con = _outgoing](const auto&) + { + try + { + con->heartbeatAsync(nullptr); + } + catch(...) + { + } + }); + + _outgoing->setHeartbeatCallback([con = _incoming](const auto&) + { + try + { + con->heartbeatAsync(nullptr); + } + catch(...) + { + } + }); // // Configure the outgoing connection for bidirectional requests. @@ -330,90 +228,92 @@ BridgeConnection::outgoingSuccess(const ConnectionPtr& outgoing) _outgoing->setAdapter(_adapter); // - // Flush any queued invocations. + // Flush any queued dispatches // - for(vector<QueuedInvocationPtr>::const_iterator p = _queue.begin(); p != _queue.end(); ++p) + for(auto& p : _queue) { - pair<const Byte*, const Byte*> paramData(&(*p)->paramData[0], &(*p)->paramData[0] + (*p)->paramData.size()); - send(outgoing, (*p)->cb, paramData, (*p)->current); + auto inParams = make_pair(p.inParams.data(), p.inParams.data() + p.inParams.size()); + send(_outgoing, inParams, move(p.response), move(p.error), p.current); } _queue.clear(); } void -BridgeConnection::outgoingException(const Exception& ex) +BridgeConnection::outgoingException(exception_ptr ex) { - IceUtil::Mutex::Lock lock(_lock); + lock_guard<mutex> lg(_lock); if(_exception) { return; } - _exception.reset(ex.ice_clone()); + _exception = ex; // // The outgoing connection failed so we close the incoming connection. closed() will eventually // be called for it when the connection's dispatch count reaches zero. // - _incoming->close(ICE_SCOPED_ENUM(ConnectionClose, Gracefully)); + _incoming->close(ConnectionClose::Gracefully); // - // Complete the queued incoming invocations, otherwise the incoming connection will never + // Complete the queued incoming dispatch, otherwise the incoming connection will never // complete its graceful closure. This is only necessary on the server side. // // The client will receive an UnknownLocalException whose reason member contains information // about the failure. // - for(vector<QueuedInvocationPtr>::iterator p = _queue.begin(); p != _queue.end(); ++p) + for(const auto& p : _queue) { - (*p)->cb->ice_exception(ex); + p.error(ex); } _queue.clear(); } void -BridgeConnection::closed(const ConnectionPtr& con) +BridgeConnection::closed(const shared_ptr<Connection>& con) { - IceUtil::Mutex::Lock lock(_lock); + lock_guard<mutex> lg(_lock); if(_exception) { return; // Nothing to do if the exception is already set, both connections have been closed already. } - ConnectionPtr toBeClosed = con == _incoming ? _outgoing : _incoming; + auto toBeClosed = con == _incoming ? _outgoing : _incoming; try { con->throwException(); } - catch(const Ice::CloseConnectionException& ex) + catch(const Ice::CloseConnectionException&) { - _exception.reset(ex.ice_clone()); + _exception = current_exception(); if(toBeClosed) { - toBeClosed->close(ICE_SCOPED_ENUM(ConnectionClose, Gracefully)); + toBeClosed->close(ConnectionClose::Gracefully); } } - catch(const Ice::Exception& ex) + catch(const std::exception&) { - _exception.reset(ex.ice_clone()); + _exception = current_exception(); if(toBeClosed) { - toBeClosed->close(ICE_SCOPED_ENUM(ConnectionClose, Forcefully)); + toBeClosed->close(ConnectionClose::Forcefully); } } // - // Even though the connection is already closed, we still need to "complete" the pending invocations so + // Even though the connection is already closed, we still need to "complete" the pending dispatches so // that the connection's dispatch count is updated correctly. // - for(vector<QueuedInvocationPtr>::iterator p = _queue.begin(); p != _queue.end(); ++p) + for(const auto& p : _queue) { - (*p)->cb->ice_exception(*_exception.get()); + p.error(_exception); } _queue.clear(); } void -BridgeConnection::dispatch(const AMD_Object_ice_invokePtr& cb, const pair<const Byte*, const Byte*>& paramData, +BridgeConnection::dispatch(pair<const Byte*, const Byte*> inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, const Current& current) { // @@ -421,10 +321,10 @@ BridgeConnection::dispatch(const AMD_Object_ice_invokePtr& cb, const pair<const // the server via the outgoing (bidirectional) connection. The current.con member tells us // the connection over which the request arrived. // - IceUtil::Mutex::Lock lock(_lock); + lock_guard<mutex> lg(_lock); if(_exception) { - cb->ice_exception(*_exception.get()); + error(_exception); } else if(!_outgoing) { @@ -432,18 +332,19 @@ BridgeConnection::dispatch(const AMD_Object_ice_invokePtr& cb, const pair<const // Queue the invocation until the outgoing connection is established. // assert(current.con == _incoming); - _queue.push_back(new QueuedInvocation(cb, paramData, current)); + _queue.emplace_back(inParams, move(response), move(error), current); } else { - send(current.con == _incoming ? _outgoing : _incoming, cb, paramData, current); + send(current.con == _incoming ? _outgoing : _incoming, inParams, move(response), move(error), current); } } void -BridgeConnection::send(const ConnectionPtr& dest, - const AMD_Object_ice_invokePtr& cb, - const pair<const Byte*, const Byte*>& paramData, +BridgeConnection::send(const shared_ptr<Connection>& dest, + pair<const Byte*, const Byte*> inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, const Current& current) { try @@ -451,60 +352,60 @@ BridgeConnection::send(const ConnectionPtr& dest, // // Create a proxy having the same identity as the request. // - ObjectPrx prx = dest->createProxy(current.id); + auto prx = dest->createProxy(current.id); - // - // Examine the request to determine whether it should be forwarded as a oneway or a twoway. - // - Callback_Object_ice_invokePtr d; if(!current.requestId) { + // Oneway request if(prx->ice_isTwoway()) { prx = prx->ice_oneway(); } - d = newCallback_Object_ice_invoke(new Invocation(cb), &Invocation::exception, &Invocation::sent); + prx->ice_invokeAsync(current.operation, current.mode, inParams, nullptr, error, + [response = move(response)](bool){ response(true, {nullptr, nullptr}); }, + current.ctx); } else { - d = newCallback_Object_ice_invoke(new Invocation(cb), &Invocation::success, &Invocation::exception); + // Twoway request + prx->ice_invokeAsync(current.operation, current.mode, inParams, move(response), error, + nullptr, current.ctx); } - prx->begin_ice_invoke(current.operation, current.mode, paramData, current.ctx, d); } - catch(const std::exception& ex) + catch(const std::exception&) { - cb->ice_exception(ex); + // can't move error parameter above since we need it here + error(current_exception()); } } -BridgeI::BridgeI(const ObjectAdapterPtr& adapter, const ObjectPrx& target) : - _adapter(adapter), _target(target) +BridgeI::BridgeI(shared_ptr<ObjectAdapter> adapter, shared_ptr<ObjectPrx> target) : + _adapter(move(adapter)), _target(move(target)) { } void -BridgeI::ice_invoke_async(const AMD_Object_ice_invokePtr& cb, - const std::pair<const Byte*, const Byte*>& paramData, - const Current& current) +BridgeI::ice_invokeAsync(pair<const Byte*, const Byte*> inParams, + function<void(bool, const pair<const Byte*, const Byte*>&)> response, + function<void(exception_ptr)> error, + const Current& current) { - BridgeConnectionPtr bc; - + shared_ptr<BridgeConnection> bc; { - IceUtil::Mutex::Lock lock(_lock); + lock_guard<mutex> lg(_lock); - map<ConnectionPtr, BridgeConnectionPtr>::iterator p = _connections.find(current.con); + auto p = _connections.find(current.con); if(p == _connections.end()) { // // The connection is unknown to us, it must be a new incoming connection. // - - EndpointInfoPtr info = current.con->getEndpoint()->getInfo(); + auto info = current.con->getEndpoint()->getInfo(); // // Create a target proxy that matches the configuration of the incoming connection. // - ObjectPrx target; + shared_ptr<ObjectPrx> target; if(info->datagram()) { target = _target->ice_datagram(); @@ -523,12 +424,14 @@ BridgeI::ice_invoke_async(const AMD_Object_ice_invokePtr& cb, // target = target->ice_connectionId(Ice::generateUUID()); - bc = new BridgeConnection(_adapter, target, current.con); - _connections.insert(make_pair(current.con, bc)); - current.con->setCloseCallback(new CloseCallbackI(this)); + bc = make_shared<BridgeConnection>(_adapter, target, current.con); + _connections.emplace(current.con, bc); + + auto self = shared_from_this(); + current.con->setCloseCallback([self](const auto& con) { self->closed(con); }); // - // Try to establish the outgoing connection. + // Try to establish the outgoing connection asynchronously // try { @@ -536,15 +439,13 @@ BridgeI::ice_invoke_async(const AMD_Object_ice_invokePtr& cb, // Begin the connection establishment process asynchronously. This can take a while to complete, // especially when using Bluetooth. // - Callback_Object_ice_getConnectionPtr d = - newCallback_Object_ice_getConnection(new GetConnectionCallback(this, bc), - &GetConnectionCallback::success, - &GetConnectionCallback::exception); - target->begin_ice_getConnection(d); + target->ice_getConnectionAsync( + [self, bc](auto outgoing) { self->outgoingSuccess(bc, move(outgoing)); }, + [self, bc](auto ex) { self->outgoingException(bc, ex); }); } - catch(const Exception& ex) + catch(const std::exception&) { - cb->ice_exception(ex); + error(current_exception()); return; } } @@ -557,19 +458,19 @@ BridgeI::ice_invoke_async(const AMD_Object_ice_invokePtr& cb, // // Delegate the invocation to the BridgeConnection object. // - bc->dispatch(cb, paramData, current); + bc->dispatch(inParams, move(response), move(error), current); } void -BridgeI::closed(const ConnectionPtr& con) +BridgeI::closed(const shared_ptr<Connection>& con) { // // Notify the BridgeConnection that a connection has closed. We also need to remove it from our map. // - BridgeConnectionPtr bc; + shared_ptr<BridgeConnection> bc; { - IceUtil::Mutex::Lock lock(_lock); - map<ConnectionPtr, BridgeConnectionPtr>::iterator p = _connections.find(con); + lock_guard<mutex> lg(_lock); + auto p = _connections.find(con); assert(p != _connections.end()); bc = p->second; _connections.erase(p); @@ -579,21 +480,21 @@ BridgeI::closed(const ConnectionPtr& con) } void -BridgeI::outgoingSuccess(const BridgeConnectionPtr& bc, const ConnectionPtr& outgoing) +BridgeI::outgoingSuccess(const shared_ptr<BridgeConnection>& bc, shared_ptr<Connection> outgoing) { // // An outgoing connection was established. Notify the BridgeConnection object. // { - IceUtil::Mutex::Lock lock(_lock); - _connections.insert(make_pair(outgoing, bc)); - outgoing->setCloseCallback(new CloseCallbackI(this)); + lock_guard<mutex> lg(_lock); + _connections.emplace(outgoing, bc); + outgoing->setCloseCallback([self = shared_from_this()](const auto& con) { self->closed(con); }); } - bc->outgoingSuccess(outgoing); + bc->outgoingSuccess(move(outgoing)); } void -BridgeI::outgoingException(const BridgeConnectionPtr& bc, const Exception& ex) +BridgeI::outgoingException(const shared_ptr<BridgeConnection>& bc, exception_ptr ex) { // // An outgoing connection attempt failed. Notify the BridgeConnection object. @@ -601,10 +502,6 @@ BridgeI::outgoingException(const BridgeConnectionPtr& bc, const Exception& ex) bc->outgoingException(ex); } -BridgeService::BridgeService() -{ -} - bool BridgeService::start(int argc, char* argv[], int& status) { @@ -644,7 +541,7 @@ BridgeService::start(int argc, char* argv[], int& status) return false; } - PropertiesPtr properties = communicator()->getProperties(); + auto properties = communicator()->getProperties(); const string targetProperty = "IceBridge.Target.Endpoints"; const string targetEndpoints = properties->getProperty(targetProperty); @@ -654,7 +551,7 @@ BridgeService::start(int argc, char* argv[], int& status) return false; } - Ice::ObjectPrx target; + shared_ptr<Ice::ObjectPrx> target; try { @@ -677,13 +574,14 @@ BridgeService::start(int argc, char* argv[], int& status) return false; } - ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceBridge.Source"); + auto adapter = communicator()->createObjectAdapter("IceBridge.Source"); - adapter->addDefaultServant(new BridgeI(adapter, target), ""); + adapter->addDefaultServant(make_shared<BridgeI>(adapter, move(target)), ""); string instanceName = properties->getPropertyWithDefault("IceBridge.InstanceName", "IceBridge"); - RouterPrx router = RouterPrx::uncheckedCast(adapter->add(new RouterI, stringToIdentity(instanceName + "/router"))); - adapter->add(new FinderI(router), stringToIdentity("Ice/RouterFinder")); + auto router = uncheckedCast<RouterPrx>(adapter->add(make_shared<RouterI>(), + stringToIdentity(instanceName + "/router"))); + adapter->add(make_shared<FinderI>(router), stringToIdentity("Ice/RouterFinder")); try { @@ -709,7 +607,7 @@ BridgeService::stop() return true; } -CommunicatorPtr +shared_ptr<Communicator> BridgeService::initializeCommunicator(int& argc, char* argv[], const InitializationData& initializationData, int version) { @@ -750,15 +648,11 @@ BridgeService::usage(const string& appName) } #ifdef _WIN32 - int wmain(int argc, wchar_t* argv[]) - #else - int main(int argc, char* argv[]) - #endif { BridgeService svc; diff --git a/cpp/src/IceDB/IceDB.cpp b/cpp/src/IceDB/IceDB.cpp index 03701eff884..a9604ec02b9 100644 --- a/cpp/src/IceDB/IceDB.cpp +++ b/cpp/src/IceDB/IceDB.cpp @@ -35,7 +35,13 @@ LMDBException::ice_print(ostream& out) const out << ": " << mdb_strerror(_error); } -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING +IceUtil::Exception* +LMDBException::ice_cloneImpl() const +{ + return new LMDBException(*this); +} +#else LMDBException* LMDBException::ice_clone() const { @@ -85,7 +91,13 @@ KeyTooLongException::ice_print(ostream& out) const out << "Max size = " << maxKeySize; } -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING +IceUtil::Exception* +KeyTooLongException::ice_cloneImpl() const +{ + return new KeyTooLongException(*this); +} +#else KeyTooLongException* KeyTooLongException::ice_clone() const { @@ -125,7 +137,13 @@ BadEnvException::ice_print(ostream& out) const out << ", IceDB max key size = " << maxKeySize; } -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING +IceUtil::Exception* +BadEnvException::ice_cloneImpl() const +{ + return new BadEnvException(*this); +} +#else BadEnvException* BadEnvException::ice_clone() const { @@ -223,7 +241,9 @@ Env::menv() const return _menv; } -Txn::Txn(const Env& env, unsigned int flags) +Txn::Txn(const Env& env, unsigned int flags) : + _mtxn(0), + _readOnly(flags == MDB_RDONLY) { const int rc = mdb_txn_begin(env.menv(), 0, flags, &_mtxn); if(rc != MDB_SUCCESS) @@ -266,7 +286,6 @@ Txn::mtxn() const ReadOnlyTxn::~ReadOnlyTxn() { - // Out of line to avoid weak vtable } ReadOnlyTxn::ReadOnlyTxn(const Env& env) : @@ -292,7 +311,6 @@ ReadOnlyTxn::renew() ReadWriteTxn::~ReadWriteTxn() { - // Out of line to avoid weak vtable } ReadWriteTxn::ReadWriteTxn(const Env& env) : @@ -322,10 +340,6 @@ DbiBase::DbiBase() : { } -DbiBase::~DbiBase() -{ -} - void DbiBase::clear(const ReadWriteTxn& txn) { @@ -387,8 +401,8 @@ DbiBase::del(const ReadWriteTxn& txn, MDB_val* key, MDB_val* data) return rc == MDB_SUCCESS; } -CursorBase::CursorBase(MDB_dbi dbi, const Txn& txn, bool readOnly) : - _readOnly(readOnly) +CursorBase::CursorBase(MDB_dbi dbi, const Txn& txn) : + _readOnly(txn.isReadOnly()) { const int rc = mdb_cursor_open(txn.mtxn(), dbi, &_mcursor); if(rc != MDB_SUCCESS) diff --git a/cpp/src/IceDB/IceDB.h b/cpp/src/IceDB/IceDB.h index 8019a9c30a9..29a6a95ff85 100644 --- a/cpp/src/IceDB/IceDB.h +++ b/cpp/src/IceDB/IceDB.h @@ -54,7 +54,9 @@ public: virtual std::string ice_id() const; virtual void ice_print(std::ostream&) const; -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING + virtual IceUtil::Exception* ice_cloneImpl() const; +#else virtual LMDBException* ice_clone() const; #endif virtual void ice_throw() const; @@ -82,7 +84,9 @@ public: virtual std::string ice_id() const; virtual void ice_print(std::ostream&) const; -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING + virtual IceUtil::Exception* ice_cloneImpl() const; +#else virtual KeyTooLongException* ice_clone() const; #endif virtual void ice_throw() const; @@ -108,7 +112,9 @@ public: virtual std::string ice_id() const; virtual void ice_print(std::ostream&) const; -#ifndef ICE_CPP11_MAPPING +#ifdef ICE_CPP11_MAPPING + virtual IceUtil::Exception* ice_cloneImpl() const; +#else virtual BadEnvException* ice_clone() const; #endif virtual void ice_throw() const; @@ -166,18 +172,23 @@ class ICE_DB_API Txn { public: - virtual ~Txn(); - void commit(); void rollback(); MDB_txn* mtxn() const; + bool isReadOnly() const + { + return _readOnly; + } + protected: - explicit Txn(const Env&, unsigned int); + Txn(const Env&, unsigned int); + ~Txn(); MDB_txn* _mtxn; + const bool _readOnly; private: @@ -190,9 +201,8 @@ class ICE_DB_API ReadOnlyTxn : public Txn { public: - virtual ~ReadOnlyTxn(); - explicit ReadOnlyTxn(const Env&); + ~ReadOnlyTxn(); void reset(); void renew(); @@ -202,9 +212,8 @@ class ICE_DB_API ReadWriteTxn : public Txn { public: - virtual ~ReadWriteTxn(); - explicit ReadWriteTxn(const Env&); + ~ReadWriteTxn(); }; class ICE_DB_API DbiBase @@ -214,8 +223,6 @@ public: void clear(const ReadWriteTxn&); MDB_dbi mdbi() const; - virtual ~DbiBase(); - protected: DbiBase(const Txn&, const std::string&, unsigned int, MDB_cmp_func*); @@ -343,14 +350,12 @@ class ICE_DB_API CursorBase public: void close(); - MDB_cursor* mcursor() const; - virtual ~CursorBase(); - protected: - CursorBase(MDB_dbi dbi, const Txn& txn, bool); + CursorBase(MDB_dbi dbi, const Txn& txn); + ~CursorBase(); bool get(MDB_val*, MDB_val*, MDB_cursor_op); void put(MDB_val*, MDB_val*, unsigned int); @@ -374,21 +379,13 @@ class Cursor : public CursorBase { public: - Cursor(const Dbi<K, D, C, H>& dbi, const ReadOnlyTxn& txn) : - CursorBase(dbi.mdbi(), txn, true), - _marshalingContext(dbi.marshalingContext()) - { - } - - Cursor(const Dbi<K, D, C, H>& dbi, const ReadWriteTxn& txn) : - CursorBase(dbi.mdbi(), txn, false), + Cursor(const Dbi<K, D, C, H>& dbi, const Txn& txn) : + CursorBase(dbi.mdbi(), txn), _marshalingContext(dbi.marshalingContext()) { } - Cursor(const Dbi<K, D, C, H>& dbi, const Txn& txn) : - CursorBase(dbi.mdbi(), txn, dynamic_cast<const ReadOnlyTxn*>(&txn) != 0), - _marshalingContext(dbi.marshalingContext()) + ~Cursor() { } diff --git a/cpp/src/IceXML/Parser.cpp b/cpp/src/IceXML/Parser.cpp index 21f2c737acc..5c29ed371b5 100644 --- a/cpp/src/IceXML/Parser.cpp +++ b/cpp/src/IceXML/Parser.cpp @@ -4,7 +4,9 @@ #include <IceXML/Parser.h> #include <IceUtil/FileUtil.h> + #include <expat.h> + #include <list> #include <fstream> @@ -24,12 +26,6 @@ IceXML::ParserException::ParserException(const char* file, int line, const strin { } -#ifndef ICE_CPP11_COMPILER -IceXML::ParserException::~ParserException() throw() -{ -} -#endif - string IceXML::ParserException::ice_id() const { @@ -50,14 +46,6 @@ IceXML::ParserException::ice_print(std::ostream& out) const } } -#ifndef ICE_CPP11_MAPPING -IceXML::ParserException* -IceXML::ParserException::ice_clone() const -{ - return new ParserException(*this); -} -#endif - string IceXML::ParserException::reason() const { @@ -67,16 +55,12 @@ IceXML::ParserException::reason() const // // Node // -IceXML::Node::Node(const NodePtr& parent, const string& name, const string& value, int line, int column) : +IceXML::Node::Node(const shared_ptr<Node>& parent, const string& name, const string& value, int line, int column) : _parent(parent), _name(name), _value(value), _line(line), _column(column) { } -IceXML::Node::~Node() -{ -} - -IceXML::NodePtr +shared_ptr<IceXML::Node> IceXML::Node::getParent() const { return _parent; @@ -113,7 +97,7 @@ IceXML::Node::getAttribute(const string&) const } bool -IceXML::Node::addChild(const NodePtr&) +IceXML::Node::addChild(const shared_ptr<Node>&) { return false; } @@ -139,16 +123,12 @@ IceXML::Node::getColumn() const // // Element // -IceXML::Element::Element(const NodePtr& parent, const string& name, const Attributes& attributes, int line, +IceXML::Element::Element(const shared_ptr<Node>& parent, const string& name, const Attributes& attributes, int line, int column) : Node(parent, name, "", line, column), _attributes(attributes) { } -IceXML::Element::~Element() -{ -} - IceXML::NodeList IceXML::Element::getChildren() const { @@ -173,7 +153,7 @@ IceXML::Element::getAttribute(const string& name) const } bool -IceXML::Element::addChild(const NodePtr& child) +IceXML::Element::addChild(const shared_ptr<Node>& child) { _children.push_back(child); return true; @@ -192,15 +172,11 @@ IceXML::Element::destroy() // // Text // -IceXML::Text::Text(const NodePtr& parent, const string& value, int line, int column) : +IceXML::Text::Text(const shared_ptr<Node>& parent, const string& value, int line, int column) : Node(parent, "", value, line, column) { } -IceXML::Text::~Text() -{ -} - // // Document // @@ -209,10 +185,6 @@ IceXML::Document::Document() : { } -IceXML::Document::~Document() -{ -} - IceXML::NodeList IceXML::Document::getChildren() const { @@ -220,7 +192,7 @@ IceXML::Document::getChildren() const } bool -IceXML::Document::addChild(const NodePtr& child) +IceXML::Document::addChild(const shared_ptr<Node>& child) { _children.push_back(child); return true; @@ -267,28 +239,28 @@ public: virtual void endElement(const string&, int, int); virtual void characters(const string&, int, int); - DocumentPtr getDocument() const; + shared_ptr<Document> getDocument() const; private: - list<NodePtr> _nodeStack; - DocumentPtr _document; + list<shared_ptr<Node>> _nodeStack; + shared_ptr<Document> _document; }; } IceXML::DocumentBuilder::DocumentBuilder() { - _document = new Document; + _document = make_shared<Document>(); _nodeStack.push_front(_document); } void IceXML::DocumentBuilder::startElement(const string& name, const Attributes& attributes, int line, int column) { - NodePtr parent = _nodeStack.front(); + auto parent = _nodeStack.front(); + auto element = make_shared<Element>(parent, name, attributes, line, column); - Element* element = new Element(parent, name, attributes, line, column); #ifdef NDEBUG parent->addChild(element); #else @@ -308,12 +280,12 @@ IceXML::DocumentBuilder::endElement(const string&, int, int) void IceXML::DocumentBuilder::characters(const string& data, int line, int column) { - NodePtr parent = _nodeStack.front(); - TextPtr text = new Text(parent, data, line, column); + auto parent = _nodeStack.front(); + auto text = make_shared<Text>(parent, data, line, column); parent->addChild(text); } -DocumentPtr +shared_ptr<Document> IceXML::DocumentBuilder::getDocument() const { return _document; @@ -372,7 +344,7 @@ characterDataHandler(void* data, const XML_Char* s, int len) // // Parser // -IceXML::DocumentPtr +shared_ptr<IceXML::Document> IceXML::Parser::parse(const string& file) { DocumentBuilder builder; @@ -380,7 +352,7 @@ IceXML::Parser::parse(const string& file) return builder.getDocument(); } -IceXML::DocumentPtr +shared_ptr<IceXML::Document> IceXML::Parser::parse(istream& in) { DocumentBuilder builder; diff --git a/cpp/src/IceXML/Parser.h b/cpp/src/IceXML/Parser.h index 71101b7a55a..ddade14a93a 100644 --- a/cpp/src/IceXML/Parser.h +++ b/cpp/src/IceXML/Parser.h @@ -5,8 +5,6 @@ #ifndef ICE_XML_PARSER_H #define ICE_XML_PARSER_H -#include <IceUtil/Shared.h> -#include <IceUtil/Handle.h> #include <IceUtil/Exception.h> #include <vector> @@ -37,21 +35,15 @@ namespace IceXML { -class ICE_XML_API ParserException : public IceUtil::ExceptionHelper<ParserException> +class ICE_XML_API ParserException final : public IceUtil::ExceptionHelper<ParserException> { public: ParserException(const std::string&); ParserException(const char*, int, const std::string&); -#ifndef ICE_CPP11_COMPILER - virtual ~ParserException() throw(); -#endif - virtual std::string ice_id() const; - virtual void ice_print(std::ostream&) const; -#ifndef ICE_CPP11_MAPPING - virtual ParserException* ice_clone() const; -#endif + std::string ice_id() const override; + void ice_print(std::ostream&) const override; std::string reason() const; @@ -61,36 +53,28 @@ private: static const char* _name; }; -class Node; -typedef IceUtil::Handle< Node > NodePtr; - -typedef std::vector<NodePtr> NodeList; - +class Document; class Element; -typedef IceUtil::Handle< Element > ElementPtr; - +class Node; class Text; -typedef IceUtil::Handle< Text > TextPtr; -class Document; -typedef IceUtil::Handle< Document > DocumentPtr; - -typedef std::map<std::string, std::string> Attributes; +using NodeList = std::vector<std::shared_ptr<Node>>; +using Attributes = std::map<std::string, std::string>; -class ICE_XML_API Node : public IceUtil::Shared +class ICE_XML_API Node { public: - virtual ~Node(); + virtual ~Node() = default; - virtual NodePtr getParent() const; + virtual std::shared_ptr<Node> getParent() const; virtual std::string getName() const; virtual std::string getValue() const; virtual NodeList getChildren() const; virtual Attributes getAttributes() const; virtual std::string getAttribute(const std::string&) const; - virtual bool addChild(const NodePtr&); + virtual bool addChild(const std::shared_ptr<Node>&); virtual void destroy(); @@ -99,29 +83,28 @@ public: protected: - Node(const NodePtr&, const std::string&, const std::string&, int, int); + Node(const std::shared_ptr<Node>&, const std::string&, const std::string&, int, int); - NodePtr _parent; + std::shared_ptr<Node> _parent; std::string _name; std::string _value; int _line; int _column; }; -class ICE_XML_API Element : public Node +class ICE_XML_API Element final : public Node { public: - Element(const NodePtr&, const std::string&, const Attributes&, int, int); - virtual ~Element(); + Element(const std::shared_ptr<Node>&, const std::string&, const Attributes&, int, int); - virtual NodeList getChildren() const; - virtual Attributes getAttributes() const; - virtual std::string getAttribute(const std::string&) const; + NodeList getChildren() const override; + Attributes getAttributes() const override; + std::string getAttribute(const std::string&) const override; - virtual bool addChild(const NodePtr&); + bool addChild(const std::shared_ptr<Node>&) override; - virtual void destroy(); + void destroy() override; private: @@ -129,12 +112,11 @@ private: Attributes _attributes; }; -class ICE_XML_API Text : public Node +class ICE_XML_API Text final : public Node { public: - Text(const NodePtr&, const std::string&, int, int); - virtual ~Text(); + Text(const std::shared_ptr<Node>&, const std::string&, int, int); }; class ICE_XML_API Document : public Node @@ -142,13 +124,12 @@ class ICE_XML_API Document : public Node public: Document(); - virtual ~Document(); - virtual NodeList getChildren() const; + NodeList getChildren() const override; - virtual bool addChild(const NodePtr&); + bool addChild(const std::shared_ptr<Node>&) override; - virtual void destroy(); + void destroy() override; private: @@ -171,8 +152,8 @@ class ICE_XML_API Parser { public: - static DocumentPtr parse(const std::string&); // The given filename must be UTF-8 encoded - static DocumentPtr parse(std::istream&); + static std::shared_ptr<Document> parse(const std::string&); // The given filename must be UTF-8 encoded + static std::shared_ptr<Document> parse(std::istream&); static void parse(const std::string&, Handler&); static void parse(std::istream&, Handler&); diff --git a/cpp/src/icegriddb/IceGridDB.cpp b/cpp/src/icegriddb/IceGridDB.cpp index f403d3e94bf..58c37588a2c 100644 --- a/cpp/src/icegriddb/IceGridDB.cpp +++ b/cpp/src/icegriddb/IceGridDB.cpp @@ -12,6 +12,7 @@ #include <IceGrid/DBTypes.h> #include <IceUtil/DisableWarnings.h> +#include <iterator> #include <fstream> using namespace std; @@ -64,33 +65,6 @@ private: string _serverVersion; }; -class ValueFactoryI : public Ice::ValueFactory -{ -public: - - ValueFactoryI(const string& serverVersion) : - _serverVersion(serverVersion) - { - } - - virtual Ice::ObjectPtr create(const string& type) - { - if(type == "::IceGrid::ServerDescriptor") - { - return new ServerDescriptorI(_serverVersion); - } - else if(type == "::IceGrid::IceBoxDescriptor") - { - return new IceBoxDescriptorI(_serverVersion); - } - return 0; - } - -private: - - string _serverVersion; -}; - } // @@ -120,7 +94,7 @@ struct StreamReader<IceGrid::ReplicaGroupDescriptor, Ice::InputStream> int run(const Ice::StringSeq&); -Ice::CommunicatorPtr communicator; +shared_ptr<Ice::Communicator> communicator; void destroyCommunicator(int) @@ -139,7 +113,7 @@ main(int argc, char* argv[]) try { - Ice::CtrlCHandler ctrlCHandler; + IceUtil::CtrlCHandler ctrlCHandler; Ice::CommunicatorHolder ich(argc, argv); communicator = ich.communicator(); @@ -301,9 +275,15 @@ run(const Ice::StringSeq& args) if(!serverVersion.empty()) { - Ice::ValueFactoryPtr factory = new ValueFactoryI(serverVersion); - communicator->getValueFactoryManager()->add(factory, "::IceGrid::ServerDescriptor"); - communicator->getValueFactoryManager()->add(factory, "::IceGrid::IceBoxDescriptor"); + communicator->getValueFactoryManager()->add([serverVersion](const string&) + { + return make_shared<ServerDescriptorI>(serverVersion); + }, IceGrid::ServerDescriptor::ice_staticId()); + + communicator->getValueFactoryManager()->add([serverVersion](const string&) + { + return make_shared<IceBoxDescriptorI>(serverVersion); + }, IceGrid::IceBoxDescriptor::ice_staticId()); } Ice::InputStream stream(communicator, dbContext.encoding, buf); |