Simplify implementation of ServiceThread 60/37060/4
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 18 Mar 2015 14:53:57 +0000 (15:53 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 26 Mar 2015 06:45:42 +0000 (23:45 -0700)
Change-Id: I56ced6bb12e2a6140ab26ab82f9dd68cb2b92b76

src/CMakeLists.txt
src/manager/main/service-thread.h
src/manager/main/thread-service.cpp [new file with mode: 0644]
src/manager/main/thread-service.h [new file with mode: 0644]
src/manager/service/ckm-service.cpp
src/manager/service/ckm-service.h
src/manager/service/ocsp-service.cpp
src/manager/service/ocsp-service.h

index a7774cf..658b0c4 100644 (file)
@@ -18,6 +18,7 @@ SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/main/socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/key-manager-main.cpp
     ${KEY_MANAGER_PATH}/main/smack-check.cpp
+    ${KEY_MANAGER_PATH}/main/thread-service.cpp
     ${KEY_MANAGER_PATH}/service/certificate-store.cpp
     ${KEY_MANAGER_PATH}/service/certificate-config.cpp
     ${KEY_MANAGER_PATH}/service/digest.cpp
index 3e538b5..e480458 100644 (file)
@@ -31,6 +31,7 @@
 #include <mutex>
 #include <thread>
 #include <memory>
+#include <functional>
 #include <condition_variable>
 
 #include <cstdio>
 
 #include "generic-event.h"
 
-#define DEFINE_THREAD_EVENT(eventType)                                \
-    void Event(const eventType &event) {                              \
-        CKM::ServiceThread<ParentClassName>::              \
-            Event(event,                                              \
-                  this,                                               \
-                  &ParentClassName::EventInternal##eventType);        \
-    }                                                                 \
-    void EventInternal##eventType(const eventType &event)
-
-#define DECLARE_THREAD_EVENT(eventType, methodName)                   \
-    void Event(const eventType &event) {                              \
-        CKM::ServiceThread<ParentClassName>::              \
-            Event(event,                                              \
-                  this,                                               \
-                  &ParentClassName::methodName);                      \
-    }
-
 namespace CKM {
 
-template <class Service>
 class ServiceThread {
 public:
-    typedef Service ParentClassName;
+    typedef std::function<void(void)> EventDescription;
     enum class State {
         NoThread,
         Work,
@@ -93,24 +76,17 @@ public:
     {
         if (m_state != State::NoThread)
             Join();
-        while (!m_eventQueue.empty()){
-            auto front = m_eventQueue.front();
-            delete front.eventPtr;
-            m_eventQueue.pop();
-        }
     }
 
-    template <class T>
-    void Event(const T &event,
-               Service *servicePtr,
-               void (Service::*serviceFunction)(const T &))
+protected:
+    /*
+     * This function is always called from ThreadService::ThreadEvent where fun
+     * is created as a temporary object and therefore will not be copied.
+     */
+    void CreateEvent(std::function<void(void)> fun)
     {
         EventDescription description;
-        description.serviceFunctionPtr =
-            reinterpret_cast<void (Service::*)(void*)>(serviceFunction);
-        description.servicePtr = servicePtr;
-        description.eventFunctionPtr = &ServiceThread::EventCall<T>;
-        description.eventPtr = new T(event);
+        description = std::move(fun);
         {
             std::lock_guard<std::mutex> lock(m_eventQueueMutex);
             m_eventQueue.push(description);
@@ -118,29 +94,13 @@ public:
         m_waitCondition.notify_one();
     }
 
-protected:
-
-    struct EventDescription {
-        void (Service::*serviceFunctionPtr)(void *);
-        Service *servicePtr;
-        void (ServiceThread::*eventFunctionPtr)(const EventDescription &event);
-        GenericEvent* eventPtr;
-    };
-
-    template <class T>
-    void EventCall(const EventDescription &desc) {
-        auto fun = reinterpret_cast<void (Service::*)(const T&)>(desc.serviceFunctionPtr);
-        const T& eventLocale = *(static_cast<T*>(desc.eventPtr));
-        (desc.servicePtr->*fun)(eventLocale);
-    }
-
     static void ThreadLoopStatic(ServiceThread *ptr) {
         ptr->ThreadLoop();
     }
 
     void ThreadLoop(){
         for (;;) {
-            EventDescription description = {NULL, NULL, NULL, NULL};
+            EventDescription description;
             {
                 std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
                 if (m_quit)
@@ -153,11 +113,10 @@ protected:
                 }
             }
 
-            if (description.eventPtr != NULL) {
+            if (description) {
                 UNHANDLED_EXCEPTION_HANDLER_BEGIN
                 {
-                    (this->*description.eventFunctionPtr)(description);
-                    delete description.eventPtr;
+                    description();
                 }
                 UNHANDLED_EXCEPTION_HANDLER_END
             }
diff --git a/src/manager/main/thread-service.cpp b/src/manager/main/thread-service.cpp
new file mode 100644 (file)
index 0000000..6d84999
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       thread-service.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <thread-service.h>
+#include <dpl/log/log.h>
+
+namespace CKM {
+
+ThreadService::ThreadService()
+{
+}
+
+ThreadService::~ThreadService()
+{
+}
+
+void ThreadService::Handle(const AcceptEvent &event) {
+    LogDebug("Accept event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.interfaceID = event.interfaceID;
+    info.credentials = event.credentials;
+}
+
+void ThreadService::Handle(const WriteEvent &event) {
+    LogDebug("Write event (" << event.size << " bytes )");
+}
+
+void ThreadService::Handle(const ReadEvent &event) {
+    LogDebug("Read event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+    while(ProcessOne(event.connectionID, info));
+}
+
+void ThreadService::Handle(const CloseEvent &event) {
+    LogDebug("Close event");
+    m_connectionInfoMap.erase(event.connectionID.counter);
+}
+
+} /* namespace CKM */
diff --git a/src/manager/main/thread-service.h b/src/manager/main/thread-service.h
new file mode 100644 (file)
index 0000000..2a4cadb
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       thread-service.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <generic-socket-manager.h>
+#include <service-thread.h>
+#include <connection-info.h>
+#include <noncopyable.h>
+
+namespace CKM {
+
+class ThreadService: public CKM::GenericSocketService, public CKM::ServiceThread
+{
+public:
+    ThreadService();
+    virtual ~ThreadService();
+    NONCOPYABLE(ThreadService);
+
+    void Event(const AcceptEvent& event) { ThreadEvent(event); }
+    void Event(const WriteEvent& event) { ThreadEvent(event); }
+    void Event(const ReadEvent& event) { ThreadEvent(event); }
+    void Event(const CloseEvent& event) { ThreadEvent(event); }
+
+protected:
+    virtual bool ProcessOne(const ConnectionID &conn,
+                            ConnectionInfo &info) = 0;
+private:
+    template <typename E>
+    void ThreadEvent(const E& event) {
+        CreateEvent([this, event]() { this->Handle(event); });
+    }
+
+    void Handle(const AcceptEvent &event);
+    void Handle(const WriteEvent &event);
+    void Handle(const ReadEvent &event);
+    void Handle(const CloseEvent &event);
+
+    ConnectionInfoMap m_connectionInfoMap;
+};
+
+} /* namespace CKM */
index 79c08d7..d281dc4 100644 (file)
  * @version     1.0
  * @brief       CKM service implementation.
  */
-#include <service-thread.h>
-#include <generic-socket-manager.h>
-#include <connection-info.h>
-#include <message-buffer.h>
+
 #include <protocols.h>
 
 #include <dpl/serialization.h>
@@ -54,25 +51,7 @@ GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription
     };
 }
 
-void CKMService::accept(const AcceptEvent &event) {
-    LogDebug("Accept event");
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
-    info.interfaceID = event.interfaceID;
-    info.credentials = event.credentials;
-}
-
-void CKMService::write(const WriteEvent &event) {
-    LogDebug("Write event (" << event.size << " bytes)");
-}
-
-void CKMService::process(const ReadEvent &event) {
-    LogDebug("Read event");
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
-    info.buffer.Push(event.rawBuffer);
-    while(processOne(event.connectionID, info));
-}
-
-bool CKMService::processOne(
+bool CKMService::ProcessOne(
     const ConnectionID &conn,
     ConnectionInfo &info)
 {
@@ -84,9 +63,9 @@ bool CKMService::processOne(
             return false;
 
         if (info.interfaceID == SOCKET_ID_CONTROL)
-            response = processControl(info.buffer);
+            response = ProcessControl(info.buffer);
         else
-            response = processStorage(info.credentials, info.buffer);
+            response = ProcessStorage(info.credentials, info.buffer);
 
         m_serviceManager->Write(conn, response);
 
@@ -109,7 +88,7 @@ bool CKMService::processOne(
     return false;
 }
 
-RawBuffer CKMService::processControl(MessageBuffer &buffer) {
+RawBuffer CKMService::ProcessControl(MessageBuffer &buffer) {
     int command = 0;
     uid_t user = 0;
     ControlCommand cc;
@@ -166,7 +145,7 @@ RawBuffer CKMService::processControl(MessageBuffer &buffer) {
     }
 }
 
-RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
+RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
 {
     int command = 0;
     int msgID = 0;
@@ -383,11 +362,5 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
     }
 }
 
-
-void CKMService::close(const CloseEvent &event) {
-    LogDebug("Close event");
-    m_connectionInfoMap.erase(event.connectionID.counter);
-}
-
 } // namespace CKM
 
index 053749c..59fa010 100644 (file)
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#include <service-thread.h>
-#include <generic-socket-manager.h>
-#include <connection-info.h>
+#include <thread-service.h>
 #include <message-buffer.h>
 #include <dpl/exception.h>
 
@@ -31,9 +29,7 @@ namespace CKM {
 
 class CKMLogic;
 
-class CKMService
-  : public CKM::GenericSocketService
-  , public CKM::ServiceThread<CKMService>
+class CKMService : public CKM::ThreadService
 {
 public:
     CKMService();
@@ -45,15 +41,6 @@ public:
 
     ServiceDescriptionVector GetServiceDescription();
 
-    DECLARE_THREAD_EVENT(AcceptEvent, accept)
-    DECLARE_THREAD_EVENT(WriteEvent, write)
-    DECLARE_THREAD_EVENT(ReadEvent, process)
-    DECLARE_THREAD_EVENT(CloseEvent, close)
-
-    void accept(const AcceptEvent &event);
-    void write(const WriteEvent &event);
-    void process(const ReadEvent &event);
-    void close(const CloseEvent &event);
 private:
     class Exception {
     public:
@@ -61,18 +48,17 @@ private:
         DECLARE_EXCEPTION_TYPE(Base, BrokenProtocol)
     };
 
-    bool processOne(
+    bool ProcessOne(
         const ConnectionID &conn,
         ConnectionInfo &info);
 
-    RawBuffer processControl(
+    RawBuffer ProcessControl(
         MessageBuffer &buffer);
 
-    RawBuffer processStorage(
+    RawBuffer ProcessStorage(
         Credentials &cred,
         MessageBuffer &buffer);
 
-    ConnectionInfoMap m_connectionInfoMap;
     CKMLogic *m_logic;
 };
 
index 9e8c2f6..6bc28cf 100644 (file)
  * @version     1.0
  * @brief       OCSP service implementation.
  */
-#include <service-thread.h>
-#include <generic-socket-manager.h>
-#include <connection-info.h>
-#include <message-buffer.h>
+
 #include <protocols.h>
 
 #include <dpl/serialization.h>
@@ -52,25 +49,7 @@ GenericSocketService::ServiceDescriptionVector OCSPService::GetServiceDescriptio
     };
 }
 
-void OCSPService::accept(const AcceptEvent &event) {
-    LogDebug("Accept event");
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
-    info.interfaceID = event.interfaceID;
-    info.credentials = event.credentials;
-}
-
-void OCSPService::write(const WriteEvent &event) {
-    LogDebug("Write event (" << event.size << " bytes )");
-}
-
-void OCSPService::process(const ReadEvent &event) {
-    LogDebug("Read event");
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
-    info.buffer.Push(event.rawBuffer);
-    while(processOne(event.connectionID, info));
-}
-
-bool OCSPService::processOne(
+bool OCSPService::ProcessOne(
     const ConnectionID &conn,
     ConnectionInfo &info)
 {
@@ -102,10 +81,5 @@ bool OCSPService::processOne(
     return false;
 }
 
-void OCSPService::close(const CloseEvent &event) {
-    LogDebug("Close event");
-    m_connectionInfoMap.erase(event.connectionID.counter);
-}
-
 } // namespace CKM
 
index c288d14..85e6072 100644 (file)
  */
 #pragma once
 
-#include <service-thread.h>
-#include <generic-socket-manager.h>
-#include <connection-info.h>
+#include <thread-service.h>
 #include <message-buffer.h>
 
 namespace CKM {
 
 class OCSPLogic;
 
-class OCSPService
-  : public CKM::GenericSocketService
-  , public CKM::ServiceThread<OCSPService>
+class OCSPService : public CKM::ThreadService
 {
 public:
     OCSPService();
@@ -44,21 +40,11 @@ public:
 
     ServiceDescriptionVector GetServiceDescription();
 
-    DECLARE_THREAD_EVENT(AcceptEvent, accept)
-    DECLARE_THREAD_EVENT(WriteEvent, write)
-    DECLARE_THREAD_EVENT(ReadEvent, process)
-    DECLARE_THREAD_EVENT(CloseEvent, close)
-
-    void accept(const AcceptEvent &event);
-    void write(const WriteEvent &event);
-    void process(const ReadEvent &event);
-    void close(const CloseEvent &event);
 private:
-    bool processOne(
+    bool ProcessOne(
         const ConnectionID &conn,
         ConnectionInfo &info);
 
-    ConnectionInfoMap m_connectionInfoMap;
     OCSPLogic *m_logic;
 };