1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SHARE_MEMORY_BLOCK_H
17 #define SHARE_MEMORY_BLOCK_H
18 
19 #ifndef NO_PROTOBUF
20 #include "google/protobuf/message.h"
21 #endif
22 #include <cstdint>
23 #include <functional>
24 #include <securec.h>
25 #include <string>
26 #include "plugin_module_api.h"
27 
28 #define EXPORT_API __attribute__((visibility("default")))
29 
30 class EXPORT_API ShareMemoryBlock {
31 public:
32     ShareMemoryBlock(const std::string& name, uint32_t size);
33     ShareMemoryBlock(const std::string& name, uint32_t size, int fd);
34     ~ShareMemoryBlock();
35 
36     bool PutRaw(const int8_t* data, uint32_t size);
37     bool PutRawTimeout(const int8_t* data, uint32_t size);
38     bool PutWithPayloadTimeout(const int8_t* header, uint32_t headerSize, const int8_t* payload, uint32_t payloadSize);
39     bool PutWithPayloadSync(const int8_t* header, uint32_t headerSize, const int8_t* payload, uint32_t payloadSize,
40                             const std::function<bool()>& callback);
41 #ifndef NO_PROTOBUF
42     EXPORT_API bool PutMessage(const google::protobuf::Message& pmsg, const std::string& pluginName);
43 #endif
44     using DataHandler = std::function<bool(const int8_t*, uint32_t)>;
45     EXPORT_API bool TakeData(const DataHandler& func, bool isProtobufSerialize = true);
46     bool TakeDataOptimize(const DataHandler& func);
47 
48     std::string GetName();
49     uint32_t GetSize();
50     EXPORT_API int GetfileDescriptor();
51 
52     bool Valid() const;
53 
54     enum ReusePolicy {
55         DROP_NONE, // buffer满时,不丢弃老数据,不放入新数据
56         DROP_OLD,  // buffer满时,丢弃最老的数据
57     };
SetReusePolicy(enum ReusePolicy dt)58     void SetReusePolicy(enum ReusePolicy dt)
59     {
60         reusePloicy_ = dt;
61     }
62 
63     void ResetPos();
64     void UseMemory(int32_t size);
65     bool GetMemory(uint32_t size, uint8_t** memory, uint32_t* offset);
66     bool Seek(uint32_t pos);
67 
68     struct ShareMemoryBlockCtx {
69         RandomWriteCtx ctx;
70         ShareMemoryBlock* block = nullptr;
71     };
GetCtx()72     ShareMemoryBlockCtx* GetCtx()
73     {
74         return &smbCtx_;
75     }
76 
77 private:
78     int8_t* GetFreeMemory(uint32_t size);
79     bool UseFreeMemory(int8_t* pmem, uint32_t size);
80 
81     uint32_t GetDataSize();
82     const int8_t* GetDataPoint();
83     bool Next();
84 
85     struct BlockHeader {
sizeofShareMemoryBlock::BlockHeader86         struct alignas(sizeof(uintptr_t)) {
87             std::atomic<uint32_t> writeOffset_;
88             std::atomic<uint32_t> readOffset_;
89             uint32_t memorySize_;
90             pthread_mutex_t mutex_;
91             std::atomic<uint32_t> bytesCount_;
92             std::atomic<uint32_t> chunkCount_;
93         } info;
94         int8_t data[0];
95     };
96 
97     ShareMemoryBlock();
98     int8_t* GetCurrentFreeMemory(uint32_t size);
99 
100     bool CreateBlock(std::string name, uint32_t size);
101     bool CreateBlockWithFd(std::string name, uint32_t size, int fd);
102     bool ReleaseBlock();
103 
104     int fileDescriptor_;
105     void* memoryPoint_;
106     uint32_t memorySize_;
107     std::string memoryName_;
108     uint32_t messageWriteOffset_ = 0;
109     ShareMemoryBlockCtx smbCtx_ = {
110         .ctx = {nullptr, nullptr},
111         .block = nullptr,
112     };
113 
114     BlockHeader* header_;
115     ReusePolicy reusePloicy_;
116 };
117 
118 #endif
119