Fixed occasional deadlock that occurred when dbus connection got
authorPhilip Rauwolf <rauwolf@itestra.de>
Fri, 1 Mar 2013 11:49:35 +0000 (12:49 +0100)
committerPhilip Rauwolf <rauwolf@itestra.de>
Fri, 1 Mar 2013 11:50:07 +0000 (12:50 +0100)
destroyed

src/CommonAPI/DBus/DBusConnection.cpp
src/CommonAPI/DBus/DBusServiceRegistry.cpp
src/CommonAPI/DBus/DBusServiceRegistry.h

index e0a32e0..68af24c 100644 (file)
@@ -92,15 +92,16 @@ bool DBusConnection::connect(DBusError& dbusError) {
 
 void DBusConnection::disconnect() {
     if (isConnected()) {
-        stopDispatching_ = true;
-
         if (!dbusSignalMatchRulesMap_.empty()) {
             dbus_connection_remove_filter(libdbusConnection_, &onLibdbusSignalFilterThunk, this);
         }
 
+        dbus_connection_close(libdbusConnection_);
+
+        stopDispatching_ = true;
+
         dispatchThread_.join();
 
-        dbus_connection_close(libdbusConnection_);
         dbus_connection_unref(libdbusConnection_);
         libdbusConnection_ = NULL;
 
@@ -119,8 +120,8 @@ DBusProxyConnection::ConnectionStatusEvent& DBusConnection::getConnectionStatusE
 const std::shared_ptr<DBusServiceRegistry> DBusConnection::getDBusServiceRegistry() {
     std::shared_ptr<DBusServiceRegistry> serviceRegistry = dbusServiceRegistry_.lock();
     if (!serviceRegistry) {
-       auto blub = this->shared_from_this();
-        serviceRegistry = std::make_shared<DBusServiceRegistry>(blub);
+        serviceRegistry = std::make_shared<DBusServiceRegistry>(this->shared_from_this());
+        serviceRegistry->init();
         dbusServiceRegistry_ = serviceRegistry;
     }
 
index f883797..a54116c 100644 (file)
@@ -16,25 +16,28 @@ namespace DBus {
 DBusServiceRegistry::DBusServiceRegistry(std::shared_ptr<DBusProxyConnection> dbusProxyConnection):
                 dbusDaemonProxy_(std::make_shared<CommonAPI::DBus::DBusDaemonProxy>(dbusProxyConnection)),
                 dbusServicesStatus_(AvailabilityStatus::UNKNOWN) {
+}
+
+DBusServiceRegistry::~DBusServiceRegistry() {
+    dbusDaemonProxy_->getNameOwnerChangedEvent().unsubscribe(dbusDaemonProxyNameOwnerChangedEventSubscription_);
+    dbusDaemonProxy_->getProxyStatusEvent().unsubscribe(dbusDaemonProxyStatusEventSubscription_);
+    std::cout << "Crushing stuff" << std::endl;
+}
 
+void DBusServiceRegistry::init() {
     dbusDaemonProxyStatusEventSubscription_ =
                     dbusDaemonProxy_->getProxyStatusEvent().subscribeCancellableListener(
-                                    std::bind(&DBusServiceRegistry::onDBusDaemonProxyStatusEvent, this, std::placeholders::_1));
+                                    std::bind(&DBusServiceRegistry::onDBusDaemonProxyStatusEvent, this->shared_from_this(), std::placeholders::_1));
 
     dbusDaemonProxyNameOwnerChangedEventSubscription_ =
                     dbusDaemonProxy_->getNameOwnerChangedEvent().subscribeCancellableListener(
                     std::bind(&DBusServiceRegistry::onDBusDaemonProxyNameOwnerChangedEvent,
-                              this,
+                              this->shared_from_this(),
                               std::placeholders::_1,
                               std::placeholders::_2,
                               std::placeholders::_3));
 }
 
-DBusServiceRegistry::~DBusServiceRegistry() {
-    dbusDaemonProxy_->getNameOwnerChangedEvent().unsubscribe(dbusDaemonProxyNameOwnerChangedEventSubscription_);
-    dbusDaemonProxy_->getProxyStatusEvent().unsubscribe(dbusDaemonProxyStatusEventSubscription_);
-}
-
 bool DBusServiceRegistry::waitDBusServicesAvailable(std::unique_lock<std::mutex>& lock, std::chrono::milliseconds& timeout) {
     bool dbusServicesStatusIsKnown = (dbusServicesStatus_ != AvailabilityStatus::UNKNOWN);
 
@@ -324,7 +327,7 @@ SubscriptionStatus DBusServiceRegistry::onDBusDaemonProxyStatusEvent(const Avail
             dbusServicesStatus_ = AvailabilityStatus::UNKNOWN;
             dbusDaemonProxy_->listNamesAsync(std::bind(
                             &DBusServiceRegistry::onListNamesCallback,
-                            this,
+                            this->shared_from_this(),
                             std::placeholders::_1,
                             std::placeholders::_2));
             break;
@@ -478,7 +481,7 @@ void DBusServiceRegistry::resolveDBusServiceInstances(DBusServiceList::iterator&
 
     // search for remote instances
     DBusDaemonProxy::GetManagedObjectsAsyncCallback callback = std::bind(&DBusServiceRegistry::onGetManagedObjectsCallback,
-                                                                         this,
+                                                                         this->shared_from_this(),
                                                                          std::placeholders::_1,
                                                                          std::placeholders::_2,
                                                                          dbusServiceName);
index 1db2dfd..510c339 100644 (file)
@@ -42,7 +42,7 @@ class DBusProxyConnection;
 class DBusDaemonProxy;
 
 
-class DBusServiceRegistry {
+class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegistry> {
  public:
     enum class DBusServiceState {
         UNKNOWN,
@@ -65,6 +65,8 @@ class DBusServiceRegistry {
 
     virtual ~DBusServiceRegistry();
 
+    void init();
+
     bool isServiceInstanceAlive(const std::string& dbusInterfaceName, const std::string& dbusConnectionName, const std::string& dbusObjectPath);
 
     Subscription subscribeAvailabilityListener(const std::string& commonApiAddress,