LayerManagerService: added support for client specific command queues
authorTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Tue, 4 Dec 2012 13:04:18 +0000 (05:04 -0800)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Wed, 9 Jan 2013 13:34:03 +0000 (05:34 -0800)
all asynchronous commands get enqueued and are executed by the client
using the commit command.
Now there is a separate command queue for each connected client and a client
can only commit commands, that have been sent by this client.

Signed-off-by: Timo Lotterbach <timo.lotterbach@bmw-carit.de>
LayerManagerCommands/src/CommitCommand.cpp
LayerManagerPlugins/Communicators/GenericCommunicator/test/mock_CommandExecutor.h
LayerManagerService/include/ICommandExecutor.h
LayerManagerService/include/Layermanager.h
LayerManagerService/include/Scene.h
LayerManagerService/src/Layermanager.cpp

index 9532e2c..09bf039 100644 (file)
@@ -26,10 +26,11 @@ ExecutionResult CommitCommand::execute(ICommandExecutor* executor)
     bool success = true;
     bool redraw = false;
 
-    Scene* scene = (executor->getScene());
+    unsigned int commitCommandPid = getSenderPid();
 
-    CommandListIterator iter = scene->m_toBeCommittedList.begin();
-    CommandListIterator iterEnd = scene->m_toBeCommittedList.end();
+    CommandList& clientCommandQueue = executor->getEnqueuedCommands(commitCommandPid);
+    CommandListIterator iter = clientCommandQueue.begin();
+    CommandListIterator iterEnd = clientCommandQueue.end();
 
     for (; iter != iterEnd; ++iter)
     {
@@ -57,7 +58,7 @@ ExecutionResult CommitCommand::execute(ICommandExecutor* executor)
             delete command;
         }
     }
-    scene->m_toBeCommittedList.clear();
+    clientCommandQueue.clear();
 
     ExecutionResult returnValue = ExecutionFailed;
 
index 1719911..cbf1f80 100644 (file)
@@ -64,6 +64,8 @@ class MockCommandExecutor : public ICommandExecutor {
   MOCK_METHOD0(getClientNotificationQueue, NotificationQueue&());
 
   MOCK_METHOD0(getHealth, HealthCondition());
+
+  MOCK_METHOD1(getEnqueuedCommands, CommandList&(unsigned int clientPid));
 };
 
 #endif /* MockCommandExecutor_H_ */
index 59f143d..8c31a93 100644 (file)
@@ -26,6 +26,7 @@
 #include "ApplicationReferenceMap.h"
 #include "LayerType.h"
 #include "ObjectType.h"
+#include "CommandList.h"
 #include "NotificationQueue.h"
 #include <pthread.h>
 
@@ -254,7 +255,15 @@ public:
      * \return reference to current list of updated scene elements
      */
     virtual NotificationQueue& getClientNotificationQueue() = 0;
-    
+
+    /**
+     * \brief get the list of enqueued commands for a client
+     * \ingroup ServiceAPI
+     * \param[in] clientPid process id of client
+     * \return Reference to command list for client
+     */
+    virtual CommandList& getEnqueuedCommands(unsigned int clientPid) = 0;
+
     /**
      * \brief get system health state
      * \ingroup ServiceAPI
index 963479d..0e38bc7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "ICommandExecutor.h"
 #include "NotificationQueue.h"
+#include "CommandList.h"
 #include <pthread.h>
 
 class Scene;
@@ -35,6 +36,7 @@ class IPlugin;
 class Configuration;
 class PluginManager;
 
+typedef std::map<unsigned int, CommandList> CommandListMap;
 typedef std::map<unsigned int, const char*> PidToProcessNameTable;
 typedef std::list<IPlugin*> PluginList;
 
@@ -82,6 +84,8 @@ public:
 
     virtual HealthCondition getHealth();
 
+    virtual CommandList& getEnqueuedCommands(unsigned int clientPid);
+
 private:
     void printDebugInformation() const;
     bool startAllRenderers(const int width, const int height, const char *displayName);
@@ -100,6 +104,7 @@ private:
     NotificationQueue m_clientNotificationQueue;
     ApplicationReferenceMap* m_pApplicationReferenceMap;
     PidToProcessNameTable m_pidToProcessNameTable;
+    CommandListMap m_EnqueuedCommands;
     IHealth* m_pHealth;
     pthread_t m_pWatchdogThread;
     bool mHealthState;
@@ -150,4 +155,9 @@ inline NotificationQueue& Layermanager::getClientNotificationQueue()
     return m_clientNotificationQueue;
 }
 
+inline CommandList& Layermanager::getEnqueuedCommands(unsigned int clientPid)
+{
+    return m_EnqueuedCommands[clientPid];
+}
+
 #endif /* _LAYERMANAGER_H_ */
index 6a9229c..f5b1575 100644 (file)
@@ -92,7 +92,6 @@ private:
     void removeSurfaceFromAllSurfaceGroups(Surface* surface);
 
 private:
-    CommandList m_toBeCommittedList;
     ShaderMap m_shaderMap;
     pthread_mutex_t m_layerListMutex;
     LayerGroupMap m_layerGroupMap;
index 428b5c6..79f95da 100644 (file)
@@ -20,6 +20,7 @@
 #include "Layermanager.h"
 #include "Log.h"
 #include <iomanip>
+#include "CommandList.h"
 #include "LayerList.h"
 #include "ICommand.h"
 #include "ICommunicator.h"
@@ -206,6 +207,15 @@ void Layermanager::removeApplicationReference(t_ilm_client_handle client)
         LOG_INFO("LayerManagerService", "Disconnect from application " << getSenderName(client) << "(" << pid << ")");
         m_pApplicationReferenceMap->erase(client);
         m_pidToProcessNameTable.erase(pid);
+
+        // if pid = 0, the client did not send ServiceConnect.
+        // since many client may use this configuration, we must
+        // not discard any pending commands here: we could discard
+        // commands of currently running applications
+        if (0 != pid)
+        {
+            m_EnqueuedCommands.erase(pid);
+        }
     }
 }
 
@@ -311,24 +321,22 @@ bool Layermanager::executeCommand(ICommand* commandToBeExecuted)
     return (status == ExecutionSuccess || status == ExecutionSuccessRedraw);
 }
 
-bool Layermanager::enqueueCommand(ICommand* commandToBeExecuted)
+bool Layermanager::enqueueCommand(ICommand* command)
 {
-    unsigned int sizeBefore;
-    unsigned int sizeAfter;
+    bool result = false;
 
-    m_pScene->lockScene();
-    sizeBefore = m_pScene->m_toBeCommittedList.size();
-    m_pScene->m_toBeCommittedList.push_back(commandToBeExecuted);
-    sizeAfter = m_pScene->m_toBeCommittedList.size();
-    m_pScene->unlockScene();
+    if (command)
+    {
+        const unsigned int commandPid = command->getSenderPid();
+        m_EnqueuedCommands[commandPid].push_back(command);
+        result = true;
 
-    unsigned int commandPid = commandToBeExecuted->getSenderPid();
-    LOG_DEBUG("LayerManagerService", "enqueued " << commandToBeExecuted->getString()
-            << " from " << getSenderName(commandPid) << "(" << commandPid << ")"
-                                     << ((sizeAfter == sizeBefore + 1) ? "+" : "-"));
+        LOG_DEBUG("LayerManagerService", "enqueued " << command->getString()
+                    << " from " << getSenderName(commandPid) << "(" << commandPid << ")"
+                    << (result ? "+" : "-"));
+    }
 
-    // if queue size increased by 1, enqueue command was successful
-    return (sizeAfter == sizeBefore + 1);
+    return result;
 }
 
 bool Layermanager::execute(ICommand* commandToBeExecuted)
@@ -537,3 +545,4 @@ HealthCondition Layermanager::getHealth()
 
     return returnValue;
 }
+