| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 
 | /*
 *  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;
};
}
 |