From ec79e495a168fdc562056bdf48a7d0c0d3040cea Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 17 Jun 2015 14:17:57 +0200 Subject: [PATCH] Add MessageService [Feature] Inter-service communication development [Solution] Add MessageService and ThreadMessageService classes to support/simplify transferring inter service messages between services/threads. [Verification] Verify together with next commit Change-Id: Id205e299ffc186a5e6eae6563d9804ce61fdec21 --- src/manager/main/message-service.h | 161 +++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/manager/main/message-service.h diff --git a/src/manager/main/message-service.h b/src/manager/main/message-service.h new file mode 100644 index 0000000..65512c0 --- /dev/null +++ b/src/manager/main/message-service.h @@ -0,0 +1,161 @@ +/* + * 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 message-service.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace CKM { + +/* + * MessageService framework is a wrapper for inter service communication with use of + * CommunicationManager. It allows registering a service as a listener in CommunicationManager and + * provides thread safe message handling. The message received from communication manager in + * SENDER THREAD is passed to RECEIVER THREAD. The RECEIVER THREAD is notified with + * ServiceThread::CreateEvent which in turn calls provided callback in this thread. + */ + +template +class MessageService; + + +// aggregating template +template +class MessageService : public MessageService, public MessageService +{ +protected: + // RECEIVER THREAD + template + void Register(Mgr& mgr) { + MessageService::Register(mgr); + MessageService::Register(mgr); + } + // RECEIVER THREAD + void CheckMessages() { + MessageService::CheckMessages(); + MessageService::CheckMessages(); + } +}; + + +// single Message type (Msg) handler +template +class MessageService +{ +public: + MessageService() {} + virtual ~MessageService() {} + NONCOPYABLE(MessageService); + +protected: + // RECEIVER THREAD: register as a listener of Msg + template + void Register(Mgr& mgr); + + // SENDER THREAD: notify about new message + virtual void Notify() = 0; + + // RECEIVER THREAD: check if there are new messages and process each of them + void CheckMessages(); + + // RECEIVER THREAD: process single message + virtual void ProcessMessage(Msg msg) = 0; + +private: + // SENDER THREAD: add message to the list + void AddMessage(const Msg& msg); + + std::mutex m_messagesMutex; + std::list m_messages; +}; + +template +template +void MessageService::Register(Mgr& mgr) +{ + mgr.Register([this](const Msg& msg) { this->AddMessage(msg); }); +} + +template +void MessageService::AddMessage(const Msg& msg) +{ + m_messagesMutex.lock(); + m_messages.push_back(msg); + m_messagesMutex.unlock(); + Notify(); // notify about added message +} + +template +void MessageService::CheckMessages() +{ + while(true) { + m_messagesMutex.lock(); + if (m_messages.empty()) { + m_messagesMutex.unlock(); + break; + } + // move out the first message + Msg message = std::move(m_messages.front()); + m_messages.pop_front(); + m_messagesMutex.unlock(); + + try { + ProcessMessage(std::move(message)); + } catch(...) { + LogError("Uncaught exception in ProcessMessage"); + } + } +} + + +// thread based service with messages support +template +class ThreadMessageService : public ThreadService, public MessageService +{ +public: + ThreadMessageService() {} + virtual ~ThreadMessageService() {} + NONCOPYABLE(ThreadMessageService); + + // RECEIVER THREAD: register as a listener of all supported messages + template + void Register(Mgr& mgr) { + MessageService::Register(mgr); + } + +private: + // SENDER THREAD: adds callback to RECEIVER THREAD event queue and wakes it + virtual void Notify() { + CreateEvent([this]() { this->CheckMessages(); }); + } + + // RECEIVER THREAD + void CheckMessages() { + MessageService::CheckMessages(); + } +}; + +} /* namespace CKM */ -- 2.7.4