summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/ActorProtocol.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/ActorProtocol.h')
-rw-r--r--xbmc/utils/ActorProtocol.h117
1 files changed, 117 insertions, 0 deletions
diff --git a/xbmc/utils/ActorProtocol.h b/xbmc/utils/ActorProtocol.h
new file mode 100644
index 0000000..77f19b9
--- /dev/null
+++ b/xbmc/utils/ActorProtocol.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "threads/CriticalSection.h"
+
+#include <cstddef>
+#include <memory>
+#include <queue>
+#include <string>
+#include <utility>
+
+class CEvent;
+
+namespace Actor
+{
+
+class CPayloadWrapBase
+{
+public:
+ virtual ~CPayloadWrapBase() = default;
+};
+
+template<typename Payload>
+class CPayloadWrap : public CPayloadWrapBase
+{
+public:
+ ~CPayloadWrap() override = default;
+ CPayloadWrap(Payload* data) { m_pPayload.reset(data); }
+ CPayloadWrap(Payload& data) { m_pPayload.reset(new Payload(data)); }
+ Payload* GetPlayload() { return m_pPayload.get(); }
+
+protected:
+ std::unique_ptr<Payload> m_pPayload;
+};
+
+class Protocol;
+
+class Message
+{
+ friend class Protocol;
+
+ static constexpr size_t MSG_INTERNAL_BUFFER_SIZE = 32;
+
+public:
+ int signal;
+ bool isSync = false;
+ bool isSyncFini;
+ bool isOut;
+ bool isSyncTimeout;
+ size_t payloadSize;
+ uint8_t buffer[MSG_INTERNAL_BUFFER_SIZE];
+ uint8_t *data = nullptr;
+ std::unique_ptr<CPayloadWrapBase> payloadObj;
+ Message *replyMessage = nullptr;
+ Protocol &origin;
+ CEvent *event = nullptr;
+
+ void Release();
+ bool Reply(int sig, void *data = nullptr, size_t size = 0);
+
+private:
+ explicit Message(Protocol &_origin) noexcept
+ :origin(_origin) {}
+};
+
+class Protocol
+{
+public:
+ Protocol(std::string name, CEvent* inEvent, CEvent* outEvent)
+ : portName(std::move(name)), containerInEvent(inEvent), containerOutEvent(outEvent)
+ {
+ }
+ Protocol(std::string name) : Protocol(std::move(name), nullptr, nullptr) {}
+ ~Protocol();
+ Message *GetMessage();
+ void ReturnMessage(Message *msg);
+ bool SendOutMessage(int signal,
+ const void* data = nullptr,
+ size_t size = 0,
+ Message* outMsg = nullptr);
+ bool SendOutMessage(int signal, CPayloadWrapBase *payload, Message *outMsg = nullptr);
+ bool SendInMessage(int signal,
+ const void* data = nullptr,
+ size_t size = 0,
+ Message* outMsg = nullptr);
+ bool SendInMessage(int signal, CPayloadWrapBase *payload, Message *outMsg = nullptr);
+ bool SendOutMessageSync(
+ int signal, Message** retMsg, int timeout, const void* data = nullptr, size_t size = 0);
+ bool SendOutMessageSync(int signal, Message **retMsg, int timeout, CPayloadWrapBase *payload);
+ bool ReceiveOutMessage(Message **msg);
+ bool ReceiveInMessage(Message **msg);
+ void Purge();
+ void PurgeIn(int signal);
+ void PurgeOut(int signal);
+ void DeferIn(bool value) { inDefered = value; }
+ void DeferOut(bool value) { outDefered = value; }
+ void Lock() { criticalSection.lock(); }
+ void Unlock() { criticalSection.unlock(); }
+ std::string portName;
+
+protected:
+ CEvent *containerInEvent, *containerOutEvent;
+ CCriticalSection criticalSection;
+ std::queue<Message*> outMessages;
+ std::queue<Message*> inMessages;
+ std::queue<Message*> freeMessageQueue;
+ bool inDefered = false, outDefered = false;
+};
+
+}