DBUSCommunicator: Add clean up methods to remove messages filters
authorMichael Schuldt <michael.schuldt@bmw.de>
Mon, 21 May 2012 07:49:23 +0000 (09:49 +0200)
committerMichael Schuldt <michael.schuldt@bmw.de>
Wed, 23 May 2012 08:58:54 +0000 (10:58 +0200)
- This fixes an issue running multi instances of the DBUSCommunicator
- Now the DBUSCommunicator Tests are running successfully

LayerManagerPlugins/Communicators/DBUSCommunicator/include/DBUSCommunicator.h
LayerManagerPlugins/Communicators/DBUSCommunicator/include/DBUSMessageHandler.h
LayerManagerPlugins/Communicators/DBUSCommunicator/src/DBUSCommunicator.cpp
LayerManagerPlugins/Communicators/DBUSCommunicator/src/DBUSMessageHandler.cpp
LayerManagerPlugins/Communicators/DBUSCommunicator/test/DBUSCommunicatorTest.cpp

index 1c9bb77..63ec6b1 100644 (file)
@@ -190,6 +190,7 @@ public:
 
 private:
     void AddClientWatch(DBusConnection *conn, char* sender);
+    void RemoveClientWatch(DBusConnection *conn, char* sender);
     void RemoveApplicationReference(char* owner);
     static DBusHandlerResult processMessageFunc(DBusConnection* conn,DBusMessage* msg, void *user_data);
     static void unregisterMessageFunc(DBusConnection* conn, void *user_data);
index dad6429..acc222f 100644 (file)
@@ -42,7 +42,9 @@ public:
     void ReplyError(DBusMessage* msg, const char* errorname, const char* errorMsg);
     bool registerMessageFilter(  DBusHandleMessageFunction fMessageFunc,
                                  void* comInstance );
-
+    
+    void unregisterMessageFilter(  DBusHandleMessageFunction fMessageFunc,
+                                 void* comInstance );
     dbus_uint32_t getUInt();
     char getByte();
     dbus_bool_t getBool();
index e8b8f87..a1e990f 100644 (file)
@@ -173,15 +173,22 @@ bool DBUSCommunicator::start()
         } 
     }
     LOG_INFO("DBUSCommunicator", "Started dbus connector");
+    m_running = true;
     return result;
 }
 
 void DBUSCommunicator::stop()
 {
     LOG_INFO("DBUSCommunicator","stopping");
-
-    // deregister dbus messaging implicitly by deleting messageHandler
-    delete g_pDbusMessage;
+    if (m_running) 
+    {
+        g_pDbusMessage->unregisterMessageFilter(DBUSCommunicator::processMessageFunc,this);
+        // deregister dbus messaging implicitly by deleting messageHandler
+    }
+    if (g_pDbusMessage != NULL) 
+    {
+        delete g_pDbusMessage;
+    }
 }
 
 void DBUSCommunicator::ServiceConnect(DBusConnection* conn, DBusMessage* msg)
@@ -202,6 +209,7 @@ void DBUSCommunicator::ServiceDisconnect(DBusConnection* conn, DBusMessage* msg)
     g_pDbusMessage->initReceive(msg);
     char* owner = strdup(dbus_message_get_sender(msg));
     RemoveApplicationReference(owner);
+    RemoveClientWatch(conn,owner);
     g_pDbusMessage->initReply(msg);
     g_pDbusMessage->closeReply();
 }
@@ -740,7 +748,7 @@ void DBUSCommunicator::CreateLayer(DBusConnection* conn, DBusMessage* msg)
     (void)conn; // TODO: remove, only prevents warning
 
     uint id = GraphicalObject::INVALID_ID;
-       // use resolution of default screen as default width and height of layers
+    // use resolution of default screen as default width and height of layers
     uint* resolution = m_executor->getScreenResolution(DEFAULT_SCREEN);
     bool status = m_executor->execute(new LayerCreateCommand(resolution[0], resolution[1], &id));
     if (status)
@@ -762,7 +770,7 @@ void DBUSCommunicator::CreateLayerFromId(DBusConnection* conn, DBusMessage* msg)
     uint id = GraphicalObject::INVALID_ID;
     g_pDbusMessage->initReceive(msg);
     id = g_pDbusMessage->getUInt();
-       // use resolution of default screen as default width and height of layers
+    // use resolution of default screen as default width and height of layers
     uint* resolution = m_executor->getScreenResolution(DEFAULT_SCREEN);
     bool status = m_executor->execute(new LayerCreateCommand(resolution[0], resolution[1], &id));
     if (status)
@@ -1969,11 +1977,27 @@ void DBUSCommunicator::AddClientWatch(DBusConnection *conn, char* sender)
     }
 }
 
+void DBUSCommunicator::RemoveClientWatch(DBusConnection *conn, char* sender) 
+{
+    DBusError err;
+    dbus_error_init(&err);
+    char rule[1024];
+    sprintf(rule,"type='signal',sender='%s',interface='%s',member='%s',arg0='%s'",DBUS_INTERFACE_DBUS,DBUS_INTERFACE_DBUS,"NameOwnerChanged",sender);
+    
+    dbus_bus_remove_match(conn,rule,&err);
+    if (dbus_error_is_set(&err))
+    {
+        LOG_ERROR("DBUSCommunicator", "Could not remove client watch "<< err.message);
+        dbus_error_free(&err);
+    }
+}
+
 DBusHandlerResult DBUSCommunicator::delegateMessage(DBusConnection* conn, DBusMessage* msg) 
 {
     DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
     LOG_DEBUG("DBUSCommunicator","message received");
     const char *n = dbus_message_get_member(msg);
+    char* owner = strdup(dbus_message_get_sender(msg));
     bool found = false;
     int i = 0;
 
@@ -2014,6 +2038,7 @@ DBusHandlerResult DBUSCommunicator::delegateMessage(DBusConnection* conn, DBusMe
         } else if ( *newName == '\0' ) 
         {
             LOG_DEBUG("DBUSCommunicator","Client Disconnect detected " << name);
+            RemoveClientWatch(conn,owner);
             RemoveApplicationReference(name);
         }
     }
index 28053f2..94d671a 100644 (file)
@@ -63,6 +63,7 @@ DBUSMessageHandler::~DBUSMessageHandler()
         LOG_ERROR("DBUSMessageHandler","there was an dbus error");
     }
     dbus_connection_unregister_object_path(m_pConnection,DBUS_SERVICE_OBJECT_PATH);
+    
     LOG_INFO("DBUSMessageHandler","Ask about owner name");
     dbus_bus_name_has_owner(m_pConnection, DBUS_SERVICE_PREFIX, &err);
     errorset = dbus_error_is_set(&err);
@@ -85,6 +86,11 @@ bool DBUSMessageHandler::registerMessageFilter(  DBusHandleMessageFunction fMess
     return result;
 }
 
+void DBUSMessageHandler::unregisterMessageFilter(  DBusHandleMessageFunction fMessageFunc,
+                                                 void* comInstance )
+{
+    dbus_connection_remove_filter ( m_pConnection , fMessageFunc, comInstance);
+}
 
 bool DBUSMessageHandler::registerPathFunction(  DBusObjectPathMessageFunction fMessageFunc,
                                                 DBusObjectPathUnregisterFunction fUnregisterFunc, 
index 81b7384..af5955f 100644 (file)
@@ -115,7 +115,6 @@ TEST_F(DBUSCommunicatorTest, ListAllLayerIDS) {
 
 TEST_F(DBUSCommunicatorTest, listAlllayerGroupIDS) {
     std::list<int> defaultlist;
-    // Sets the default return value for type Bar.
     DefaultValue<Scene*>::Set((Scene*) &this->layerlist);
     DefaultValue<std::list<int> >::Set(defaultlist);
     EXPECT_CALL(this->layerlist, getLayerGroupIDs(NotNull(),NotNull()) ).Times(1);
@@ -124,7 +123,6 @@ TEST_F(DBUSCommunicatorTest, listAlllayerGroupIDS) {
 
 TEST_F(DBUSCommunicatorTest, listAllSurfaceGroupIDS) {
     std::list<int> defaultlist;
-    // Sets the default return value for type Bar.
     DefaultValue<Scene*>::Set((Scene*) &this->layerlist);
     DefaultValue<std::list<int> >::Set(defaultlist);
     EXPECT_CALL(this->layerlist, getSurfaceGroupIDs(NotNull(),NotNull() )).Times(1);
@@ -135,7 +133,6 @@ TEST_F(DBUSCommunicatorTest, listSurfacesOfSurfacegroup) {
 
     std::list<int> defaultlist;
     DefaultValue<Scene*>::Set((Scene*) &this->layerlist);
-    // Sets the default return value for type Bar.
     DefaultValue<std::list<int> >::Set(defaultlist);
     DefaultValue<SurfaceGroup*>::Set(new SurfaceGroup());
     EXPECT_CALL(this->layerlist, getSurfaceGroup(Eq(84567u) )).Times(1);
@@ -146,7 +143,6 @@ TEST_F(DBUSCommunicatorTest, listSurfacesOfSurfacegroup) {
 TEST_F(DBUSCommunicatorTest, listlayersOflayergroup) {
 
     std::list<int> defaultlist;
-    // Sets the default return value for type Bar.
     DefaultValue<Scene*>::Set((Scene*) &this->layerlist);
     DefaultValue<std::list<int> >::Set(defaultlist);
     DefaultValue<LayerGroup*>::Set(new LayerGroup());