1
2
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
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;
};
}
|