From 49ce723e4888acbeb98e96d2e3daac327d11cff3 Mon Sep 17 00:00:00 2001 From: Johannes Schanda Date: Tue, 11 Jun 2013 17:34:44 +0200 Subject: Multiple connection names from one factory - Corrects the obsolete check for multiple connection name claims when registering stubs - Moves claimedNames set in to DBusConnection - DBusConnection now handles whether or not it needs to claim or release names, users can safely call the provided methods without external checks - when releasing the last stub using a particular connection name, the name is released also --- src/CommonAPI/DBus/DBusConnection.cpp | 58 ++++++++++++++++++++++---------- src/CommonAPI/DBus/DBusConnection.h | 4 ++- src/CommonAPI/DBus/DBusFactory.cpp | 10 ++---- src/CommonAPI/DBus/DBusFactory.h | 1 - src/CommonAPI/DBus/DBusProxyConnection.h | 3 ++ src/CommonAPI/DBus/DBusStubAdapter.cpp | 1 + 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index 01cd689..b549884 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -67,7 +67,8 @@ DBusConnection::DBusConnection(BusType busType) : pauseDispatching_(false), dispatchThread_(NULL), dbusObjectMessageHandler_(), - watchContext_(NULL) { + watchContext_(NULL), + connectionNameCount_() { dbus_threads_init_default(); } @@ -79,7 +80,8 @@ DBusConnection::DBusConnection(::DBusConnection* libDbusConnection) : pauseDispatching_(false), dispatchThread_(NULL), dbusObjectMessageHandler_(), - watchContext_(NULL) { + watchContext_(NULL), + connectionNameCount_() { dbus_threads_init_default(); } @@ -338,30 +340,52 @@ const std::shared_ptr DBusConnection::getDBusObjectManager() bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName) const { DBusError dbusError; + bool isServiceNameAcquired = false; + std::lock_guard dbusConnectionLock(libdbusConnectionGuard_); + auto conIter = connectionNameCount_.find(serviceName); + if (conIter == connectionNameCount_.end()) { + suspendDispatching(); - suspendDispatching(); - - const int libdbusStatus = dbus_bus_request_name(libdbusConnection_, - serviceName.c_str(), - DBUS_NAME_FLAG_DO_NOT_QUEUE, - &dbusError.libdbusError_); + const int libdbusStatus = dbus_bus_request_name(libdbusConnection_, + serviceName.c_str(), + DBUS_NAME_FLAG_DO_NOT_QUEUE, + &dbusError.libdbusError_); - resumeDispatching(); + resumeDispatching(); - const bool isServiceNameAcquired = (libdbusStatus == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER); + isServiceNameAcquired = (libdbusStatus == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER); + if (isServiceNameAcquired) { + connectionNameCount_.insert({serviceName, (uint16_t)1}); + } + } else { + conIter->second = conIter->second + 1; + isServiceNameAcquired = true; + } return isServiceNameAcquired; } bool DBusConnection::releaseServiceName(const std::string& serviceName) const { DBusError dbusError; - suspendDispatching(); - const int libdbusStatus = dbus_bus_release_name(libdbusConnection_, - serviceName.c_str(), - &dbusError.libdbusError_); - resumeDispatching(); - const bool isServiceNameReleased = (libdbusStatus == DBUS_RELEASE_NAME_REPLY_RELEASED); - + bool isServiceNameReleased = false; + std::lock_guard dbusConnectionLock(libdbusConnectionGuard_); + auto conIter = connectionNameCount_.find(serviceName); + if (conIter != connectionNameCount_.end()) { + if (conIter->second == 1) { + suspendDispatching(); + const int libdbusStatus = dbus_bus_release_name(libdbusConnection_, + serviceName.c_str(), + &dbusError.libdbusError_); + resumeDispatching(); + isServiceNameReleased = (libdbusStatus == DBUS_RELEASE_NAME_REPLY_RELEASED); + if (isServiceNameReleased) { + connectionNameCount_.erase(conIter); + } + } else { + conIter->second = conIter->second - 1; + isServiceNameReleased = true; + } + } return isServiceNameReleased; } diff --git a/src/CommonAPI/DBus/DBusConnection.h b/src/CommonAPI/DBus/DBusConnection.h index 5f19d7b..83d02a4 100644 --- a/src/CommonAPI/DBus/DBusConnection.h +++ b/src/CommonAPI/DBus/DBusConnection.h @@ -166,7 +166,7 @@ class DBusConnection: public DBusProxyConnection, public std::enable_shared_from static void onWakeupMainContext(void* data); ::DBusConnection* libdbusConnection_; - std::mutex libdbusConnectionGuard_; + mutable std::mutex libdbusConnectionGuard_; std::mutex signalGuard_; std::mutex objectManagerGuard_; std::mutex serviceRegistryGuard_; @@ -192,6 +192,8 @@ class DBusConnection: public DBusProxyConnection, public std::enable_shared_from static DBusObjectPathVTable libdbusObjectPathVTable_; DBusObjectPathMessageHandler dbusObjectMessageHandler_; + + mutable std::unordered_map connectionNameCount_; }; std::shared_ptr DBusConnection::getBus(const BusType& busType) { diff --git a/src/CommonAPI/DBus/DBusFactory.cpp b/src/CommonAPI/DBus/DBusFactory.cpp index f28ef2f..39bfb7a 100644 --- a/src/CommonAPI/DBus/DBusFactory.cpp +++ b/src/CommonAPI/DBus/DBusFactory.cpp @@ -45,7 +45,6 @@ void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAd DBusFactory::DBusFactory(std::shared_ptr runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr mainLoopContext) : CommonAPI::Factory(runtime, middlewareInfo), dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()), - acquiredConnectionName_(""), mainLoopContext_(mainLoopContext) { bool startDispatchThread = !mainLoopContext_; dbusConnection_->connect(startDispatchThread); @@ -158,13 +157,8 @@ bool DBusFactory::registerAdapter(std::shared_ptr stubBase, DBusAddressTranslator::getInstance().searchForDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath); - if(acquiredConnectionName_ == "") { - bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName); - if(!isServiceNameAcquired) { - return false; - } - acquiredConnectionName_ = connectionName; - } else if (acquiredConnectionName_ != connectionName) { + bool isServiceNameAcquired = dbusConnection_->requestServiceNameAndBlock(connectionName); + if (!isServiceNameAcquired) { return false; } diff --git a/src/CommonAPI/DBus/DBusFactory.h b/src/CommonAPI/DBus/DBusFactory.h index 7516d9a..3775944 100644 --- a/src/CommonAPI/DBus/DBusFactory.h +++ b/src/CommonAPI/DBus/DBusFactory.h @@ -60,7 +60,6 @@ class DBusFactory: public Factory { SubscriptionStatus isServiceInstanceAliveCallbackThunk(Factory::IsServiceInstanceAliveCallback callback, const AvailabilityStatus& status); std::shared_ptr dbusConnection_; - std::string acquiredConnectionName_; std::shared_ptr mainLoopContext_; }; diff --git a/src/CommonAPI/DBus/DBusProxyConnection.h b/src/CommonAPI/DBus/DBusProxyConnection.h index 19140f2..c346c44 100644 --- a/src/CommonAPI/DBus/DBusProxyConnection.h +++ b/src/CommonAPI/DBus/DBusProxyConnection.h @@ -95,6 +95,9 @@ class DBusProxyConnection { virtual void registerObjectPath(const std::string& objectPath) = 0; virtual void unregisterObjectPath(const std::string& objectPath) = 0; + virtual bool requestServiceNameAndBlock(const std::string& serviceName) const = 0; + virtual bool releaseServiceName(const std::string& serviceName) const = 0; + typedef std::function DBusObjectPathMessageHandler; virtual void setObjectPathMessageHandler(DBusObjectPathMessageHandler) = 0; diff --git a/src/CommonAPI/DBus/DBusStubAdapter.cpp b/src/CommonAPI/DBus/DBusStubAdapter.cpp index 050ed40..90e04b4 100644 --- a/src/CommonAPI/DBus/DBusStubAdapter.cpp +++ b/src/CommonAPI/DBus/DBusStubAdapter.cpp @@ -47,6 +47,7 @@ void DBusStubAdapter::deinit() { if (isInitialized_) { dbusConnection_->getDBusObjectManager()->unregisterDBusStubAdapter(dbusInterfaceHandlerToken_); + dbusConnection_->releaseServiceName(dbusBusName_); isInitialized_ = false; } } -- cgit v1.2.1