525 lines
18 KiB
Diff
525 lines
18 KiB
Diff
From 9fb0aa74fece1deea72ef7c8eef5e45da2113b21 Mon Sep 17 00:00:00 2001
|
|
From: fly_1997 <flylove7@outlook.com>
|
|
Date: Tue, 26 Nov 2024 15:59:15 +0800
|
|
Subject: [PATCH 2/5] add data free and fix unsubscribe error
|
|
|
|
---
|
|
src/common/CMakeLists.txt | 7 +
|
|
src/common/data_register.cpp | 247 +++++++++++++++----
|
|
src/common/data_register.h | 20 +-
|
|
src/plugin/collect/include/command_data.h | 2 +-
|
|
src/plugin_mgr/event/unsubscribe_handler.cpp | 7 +-
|
|
src/plugin_mgr/instance_run_handler.cpp | 2 +-
|
|
src/sdk/oe_client.cpp | 1 +
|
|
7 files changed, 227 insertions(+), 59 deletions(-)
|
|
|
|
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
|
|
index 2d49b3e..46084e5 100644
|
|
--- a/src/common/CMakeLists.txt
|
|
+++ b/src/common/CMakeLists.txt
|
|
@@ -22,6 +22,13 @@ target_link_libraries(${PROJECT_NAME} log4cplus)
|
|
target_link_libraries(${PROJECT_NAME} yaml-cpp)
|
|
target_link_libraries(${PROJECT_NAME} curl boundscheck)
|
|
|
|
+if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
|
|
+target_link_directories(${PROJECT_NAME} PUBLIC
|
|
+ ${LIB_KPERF_LIBPATH}
|
|
+)
|
|
+target_link_libraries(${PROJECT_NAME} kperf)
|
|
+endif()
|
|
+
|
|
file(COPY
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/data_list.h"
|
|
DESTINATION "${CMAKE_BINARY_DIR}/output/include")
|
|
diff --git a/src/common/data_register.cpp b/src/common/data_register.cpp
|
|
index 89e660e..cdf6d97 100644
|
|
--- a/src/common/data_register.cpp
|
|
+++ b/src/common/data_register.cpp
|
|
@@ -16,68 +16,107 @@
|
|
|
|
namespace oeaware {
|
|
|
|
-int TopicSerialize(const void *topic, OutStream &out)
|
|
+void TopicFree(CTopic *topic)
|
|
{
|
|
- auto tmpTopic = static_cast<const CTopic*>(topic);
|
|
- std::string instanceName(tmpTopic->instanceName);
|
|
- std::string topicName(tmpTopic->topicName);
|
|
- std::string params(tmpTopic->params);
|
|
+ if (topic == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ if (topic->instanceName != nullptr) {
|
|
+ delete[] topic->instanceName;
|
|
+ topic->instanceName = nullptr;
|
|
+ }
|
|
+ if (topic->topicName != nullptr) {
|
|
+ delete[] topic->topicName;
|
|
+ topic->topicName = nullptr;
|
|
+ }
|
|
+ if (topic->params != nullptr) {
|
|
+ delete[] topic->params;
|
|
+ topic->params = nullptr;
|
|
+ }
|
|
+}
|
|
+
|
|
+int TopicSerialize(const CTopic *topic, OutStream &out)
|
|
+{
|
|
+ std::string instanceName(topic->instanceName);
|
|
+ std::string topicName(topic->topicName);
|
|
+ std::string params(topic->params);
|
|
out << instanceName << topicName << params;
|
|
return 0;
|
|
}
|
|
|
|
-int TopicDeserialize(void *topic, InStream &in)
|
|
+int TopicDeserialize(CTopic *topic, InStream &in)
|
|
{
|
|
std::string instanceName;
|
|
std::string topicName;
|
|
std::string params;
|
|
in >> instanceName >> topicName >> params;
|
|
- ((CTopic*)topic)->instanceName = new char[instanceName.size() + 1];
|
|
- ((CTopic*)topic)->topicName = new char[topicName.size() + 1];
|
|
- ((CTopic*)topic)->params = new char[params.size() + 1];
|
|
+ topic->instanceName = new char[instanceName.size() + 1];
|
|
+ topic->topicName = new char[topicName.size() + 1];
|
|
+ topic->params = new char[params.size() + 1];
|
|
|
|
- auto ret = strcpy_s(((CTopic*)topic)->instanceName, instanceName.size() + 1, instanceName.data());
|
|
+ auto ret = strcpy_s(topic->instanceName, instanceName.size() + 1, instanceName.data());
|
|
if (ret != EOK) return ret;
|
|
- ret = strcpy_s(((CTopic*)topic)->topicName, topicName.size() + 1, topicName.data());
|
|
+ ret = strcpy_s(topic->topicName, topicName.size() + 1, topicName.data());
|
|
if (ret != EOK) return ret;
|
|
- ret = strcpy_s(((CTopic*)topic)->params, params.size() + 1, params.data());
|
|
+ ret = strcpy_s(topic->params, params.size() + 1, params.data());
|
|
if (ret != EOK) return ret;
|
|
return 0;
|
|
}
|
|
|
|
-int DataListSerialize(const void *dataList, OutStream &out)
|
|
+void DataListFree(DataList *dataList)
|
|
+{
|
|
+ if (dataList == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ auto ® = Register::GetInstance();
|
|
+ DataFreeFunc free = reg.GetDataFreeFunc(Concat({dataList->topic.instanceName, dataList->topic.topicName}, "::"));
|
|
+ if (free == nullptr) {
|
|
+ free = reg.GetDataFreeFunc(dataList->topic.instanceName);
|
|
+ }
|
|
+ if (free != nullptr) {
|
|
+ for (uint64_t i = 0; i < dataList->len; ++i) {
|
|
+ free(dataList->data[i]);
|
|
+ }
|
|
+ }
|
|
+ TopicFree(&dataList->topic);
|
|
+ if (dataList->data != nullptr) {
|
|
+ delete[] dataList->data;
|
|
+ dataList->data = nullptr;
|
|
+ }
|
|
+}
|
|
+
|
|
+int DataListSerialize(const DataList *dataList, OutStream &out)
|
|
{
|
|
- auto tmpList = static_cast<const DataList*>(dataList);
|
|
- TopicSerialize(&tmpList->topic, out);
|
|
- out << tmpList->len;
|
|
+ TopicSerialize(&dataList->topic, out);
|
|
+ out << dataList->len;
|
|
auto ® = Register::GetInstance();
|
|
- auto func = reg.GetDataSerialize(Concat({tmpList->topic.instanceName, tmpList->topic.topicName}, "::"));
|
|
+ auto func = reg.GetDataSerialize(Concat({dataList->topic.instanceName, dataList->topic.topicName}, "::"));
|
|
if (func == nullptr) {
|
|
- func = reg.GetDataSerialize(tmpList->topic.instanceName);
|
|
+ func = reg.GetDataSerialize(dataList->topic.instanceName);
|
|
}
|
|
- for (uint64_t i = 0; i < tmpList->len; ++i) {
|
|
- func(tmpList->data[i], out);
|
|
+ for (uint64_t i = 0; i < dataList->len; ++i) {
|
|
+ func(dataList->data[i], out);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
-int DataListDeserialize(void *dataList, InStream &in)
|
|
+int DataListDeserialize(DataList *dataList, InStream &in)
|
|
{
|
|
CTopic topic;
|
|
TopicDeserialize(&topic, in);
|
|
uint64_t size;
|
|
in >> size;
|
|
- ((DataList*)dataList)->topic = topic;
|
|
- ((DataList*)dataList)->len = size;
|
|
- ((DataList*)dataList)->data = new void* [size];
|
|
+ dataList->topic = topic;
|
|
+ dataList->len = size;
|
|
+ dataList->data = new void* [size];
|
|
auto ® = Register::GetInstance();
|
|
auto func = reg.GetDataDeserialize(Concat({topic.instanceName, topic.topicName}, "::"));
|
|
if (func == nullptr) {
|
|
func = reg.GetDataDeserialize(topic.instanceName);
|
|
}
|
|
for (uint64_t i = 0; i < size; ++i) {
|
|
- ((DataList*)dataList)->data[i] = nullptr;
|
|
- auto ret = func(&(((DataList*)dataList)->data[i]), in);
|
|
+ dataList->data[i] = nullptr;
|
|
+ auto ret = func(&(dataList->data[i]), in);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
@@ -85,6 +124,16 @@ int DataListDeserialize(void *dataList, InStream &in)
|
|
return 0;
|
|
}
|
|
|
|
+void ResultFree(Result *result)
|
|
+{
|
|
+ if (result == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ if (result->payload != nullptr) {
|
|
+ delete[] result->payload;
|
|
+ result->payload = nullptr;
|
|
+ }
|
|
+}
|
|
|
|
int ResultDeserialize(void *data, InStream &in)
|
|
{
|
|
@@ -96,6 +145,17 @@ int ResultDeserialize(void *data, InStream &in)
|
|
return ret;
|
|
}
|
|
#if defined(__arm__) || defined(__aarch64__)
|
|
+void PmuBaseDataFree(void *data)
|
|
+{
|
|
+ auto tmpData = static_cast<PmuCountingData*>(data);
|
|
+ if (tmpData == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ PmuDataFree(tmpData->pmuData);
|
|
+ tmpData->pmuData = nullptr;
|
|
+ tmpData->len = 0;
|
|
+}
|
|
+
|
|
int PmuCountingDataSerialize(const void *data, OutStream &out)
|
|
{
|
|
auto tmpData = static_cast<const PmuCountingData*>(data);
|
|
@@ -456,6 +516,19 @@ int PmuUncoreDataDeserialize(void **data, InStream &in)
|
|
}
|
|
#endif
|
|
|
|
+void ThreadInfoFree(void *data)
|
|
+{
|
|
+ auto threadInfo = static_cast<ThreadInfo*>(data);
|
|
+ if (threadInfo == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ if (threadInfo->name != nullptr) {
|
|
+ delete[] threadInfo->name;
|
|
+ threadInfo->name = nullptr;
|
|
+ }
|
|
+ delete threadInfo;
|
|
+}
|
|
+
|
|
int ThreadInfoSerialize(const void *data, OutStream &out)
|
|
{
|
|
auto threadInfo = static_cast<const ThreadInfo*>(data);
|
|
@@ -476,6 +549,32 @@ int ThreadInfoDeserialize(void **data, InStream &in)
|
|
return 0;
|
|
}
|
|
|
|
+void KernelDataFree(void *data)
|
|
+{
|
|
+ auto tmpData = static_cast<const KernelData*>(data);
|
|
+ if (tmpData == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ KernelDataNode *node = tmpData->kernelData;
|
|
+ for (int i = 0; i < tmpData->len; ++i) {
|
|
+ auto tmp = node->next;
|
|
+ if (node == nullptr) {
|
|
+ break;
|
|
+ }
|
|
+ if (node->key != nullptr) {
|
|
+ delete[] node->key;
|
|
+ node->key = nullptr;
|
|
+ }
|
|
+ if (node->value != nullptr) {
|
|
+ delete[] node->value;
|
|
+ node->value = nullptr;
|
|
+ }
|
|
+ delete node;
|
|
+ node = tmp;
|
|
+ }
|
|
+ delete tmpData;
|
|
+}
|
|
+
|
|
int KernelDataSerialize(const void *data, OutStream &out)
|
|
{
|
|
auto tmpData = static_cast<const KernelData*>(data);
|
|
@@ -523,17 +622,47 @@ int KernelDataDeserialize(void **data, InStream &in)
|
|
return 0;
|
|
}
|
|
|
|
+void CommandDataFree(void *data)
|
|
+{
|
|
+ CommandData *commandData = (CommandData*)data;
|
|
+ if (commandData == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ for (int i = 0; i < commandData->attrLen; ++i) {
|
|
+ if (commandData->itemAttr[i] != nullptr) {
|
|
+ delete[] commandData->itemAttr[i];
|
|
+ commandData->itemAttr[i] = nullptr;
|
|
+ }
|
|
+ }
|
|
+ if (commandData->items == nullptr) {
|
|
+ delete commandData;
|
|
+ return;
|
|
+ }
|
|
+ for (int i = 0; i < commandData->itemLen; ++i) {
|
|
+ for (int j = 0; j < commandData->attrLen; ++j) {
|
|
+ if (commandData->items[i].value[j] != nullptr) {
|
|
+ delete[] commandData->items[i].value[j];
|
|
+ commandData->items[i].value[j] = nullptr;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ delete[] commandData->items;
|
|
+ commandData->items = nullptr;
|
|
+
|
|
+ delete commandData;
|
|
+}
|
|
+
|
|
int CommandDataSerialize(const void *data, OutStream &out)
|
|
{
|
|
- auto sarData = (SarData*)data;
|
|
- out << sarData->attrLen << sarData->itemLen;
|
|
- for (int i = 0; i < sarData->attrLen; ++i) {
|
|
- std::string attr(sarData->itemAttr[i]);
|
|
+ auto commandData = (CommandData*)data;
|
|
+ out << commandData->attrLen << commandData->itemLen;
|
|
+ for (int i = 0; i < commandData->attrLen; ++i) {
|
|
+ std::string attr(commandData->itemAttr[i]);
|
|
out << attr;
|
|
}
|
|
- for (int i = 0; i < sarData->itemLen; ++i) {
|
|
- for (int j = 0; j < sarData->attrLen; ++j) {
|
|
- std::string item(sarData->items[i].value[j]);
|
|
+ for (int i = 0; i < commandData->itemLen; ++i) {
|
|
+ for (int j = 0; j < commandData->attrLen; ++j) {
|
|
+ std::string item(commandData->items[i].value[j]);
|
|
out << item;
|
|
}
|
|
}
|
|
@@ -542,8 +671,8 @@ int CommandDataSerialize(const void *data, OutStream &out)
|
|
|
|
int CommandDataDeserialize(void **data, InStream &in)
|
|
{
|
|
- *data = new SarData();
|
|
- auto sarData = static_cast<SarData*>(*data);
|
|
+ *data = new CommandData();
|
|
+ auto sarData = static_cast<CommandData*>(*data);
|
|
in >> sarData->attrLen >> sarData->itemLen;
|
|
int ret;
|
|
for (int i = 0; i < sarData->attrLen; ++i) {
|
|
@@ -570,6 +699,15 @@ int CommandDataDeserialize(void **data, InStream &in)
|
|
return 0;
|
|
}
|
|
|
|
+void AnalysisDataFree(void *data)
|
|
+{
|
|
+ auto analysisData = static_cast<AdaptData*>(data);
|
|
+ if (analysisData == nullptr) {
|
|
+ return;
|
|
+ }
|
|
+ delete analysisData;
|
|
+}
|
|
+
|
|
int AnalysisDataSerialize(const void *data, OutStream &out)
|
|
{
|
|
auto analysisData = static_cast<const AdaptData*>(data);
|
|
@@ -600,44 +738,55 @@ int AnalysisDataDeserialize(void **data, InStream &in)
|
|
|
|
void Register::RegisterData(const std::string &name, const RegisterEntry &entry)
|
|
{
|
|
- deserializeFuncs[name] = entry;
|
|
+ registerEntry[name] = entry;
|
|
}
|
|
|
|
void Register::InitRegisterData()
|
|
{
|
|
#if defined(__arm__) || defined(__aarch64__)
|
|
- RegisterData("pmu_counting_collector", RegisterEntry(PmuCountingDataSerialize, PmuCountingDataDeserialize));
|
|
+ RegisterData("pmu_counting_collector", RegisterEntry(PmuCountingDataSerialize, PmuCountingDataDeserialize,
|
|
+ PmuBaseDataFree));
|
|
|
|
- RegisterData("pmu_sampling_collector", RegisterEntry(PmuSamplingDataSerialize, PmuSamplingDataDeserialize));
|
|
+ RegisterData("pmu_sampling_collector", RegisterEntry(PmuSamplingDataSerialize, PmuSamplingDataDeserialize,
|
|
+ PmuBaseDataFree));
|
|
|
|
- RegisterData("pmu_spe_collector", RegisterEntry(PmuSpeDataSerialize, PmuSpeDataDeserialize));
|
|
+ RegisterData("pmu_spe_collector", RegisterEntry(PmuSpeDataSerialize, PmuSpeDataDeserialize, PmuBaseDataFree));
|
|
|
|
- RegisterData("pmu_uncore_collector", RegisterEntry(PmuUncoreDataSerialize, PmuUncoreDataDeserialize));
|
|
+ RegisterData("pmu_uncore_collector", RegisterEntry(PmuUncoreDataSerialize, PmuUncoreDataDeserialize,
|
|
+ PmuBaseDataFree));
|
|
#endif
|
|
- RegisterData("thread_collector", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize));
|
|
+ RegisterData("thread_collector", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize, ThreadInfoFree));
|
|
+
|
|
+ RegisterData("kernel_config", RegisterEntry(KernelDataSerialize, KernelDataDeserialize, KernelDataFree));
|
|
|
|
- RegisterData("kernel_config", RegisterEntry(KernelDataSerialize, KernelDataDeserialize));
|
|
+ RegisterData("thread_scenario", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize, ThreadInfoFree));
|
|
|
|
- RegisterData("thread_scenario", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize));
|
|
+ RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize, CommandDataFree));
|
|
|
|
- RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize));
|
|
- RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize));
|
|
RegisterData("analysis_aware", RegisterEntry(AnalysisDataSerialize, AnalysisDataDeserialize));
|
|
}
|
|
|
|
SerializeFunc Register::GetDataSerialize(const std::string &name)
|
|
{
|
|
- if (!deserializeFuncs.count(name)) {
|
|
+ if (!registerEntry.count(name)) {
|
|
return nullptr;
|
|
}
|
|
- return deserializeFuncs[name].se;
|
|
+ return registerEntry[name].se;
|
|
}
|
|
|
|
DeserializeFunc Register::GetDataDeserialize(const std::string &name)
|
|
{
|
|
- if (!deserializeFuncs.count(name)) {
|
|
+ if (!registerEntry.count(name)) {
|
|
+ return nullptr;
|
|
+ }
|
|
+ return registerEntry[name].de;
|
|
+}
|
|
+
|
|
+DataFreeFunc Register::GetDataFreeFunc(const std::string &name)
|
|
+{
|
|
+ if (!registerEntry.count(name)) {
|
|
return nullptr;
|
|
}
|
|
- return deserializeFuncs[name].de;
|
|
+ return registerEntry[name].free;
|
|
}
|
|
}
|
|
diff --git a/src/common/data_register.h b/src/common/data_register.h
|
|
index 5e1ae4a..b72cd97 100644
|
|
--- a/src/common/data_register.h
|
|
+++ b/src/common/data_register.h
|
|
@@ -13,18 +13,21 @@
|
|
#define COMMON_DATA_REGISTER_H
|
|
#include <unordered_map>
|
|
#include "serialize.h"
|
|
+#include "data_list.h"
|
|
|
|
namespace oeaware {
|
|
using DeserializeFunc = int(*)(void**, InStream &in);
|
|
using SerializeFunc = int(*)(const void*, OutStream &out);
|
|
-using FreeData = void(*)(void *);
|
|
+using DataFreeFunc = void(*)(void *);
|
|
|
|
struct RegisterEntry {
|
|
RegisterEntry() { }
|
|
RegisterEntry(const SerializeFunc &se, const DeserializeFunc &de) : se(se), de(de) { }
|
|
+ RegisterEntry(const SerializeFunc &se, const DeserializeFunc &de, const DataFreeFunc &free) : se(se),
|
|
+ de(de), free(free) { }
|
|
SerializeFunc se;
|
|
DeserializeFunc de;
|
|
- FreeData free;
|
|
+ DataFreeFunc free;
|
|
};
|
|
|
|
class Register {
|
|
@@ -40,17 +43,20 @@ public:
|
|
void InitRegisterData();
|
|
DeserializeFunc GetDataDeserialize(const std::string &name);
|
|
SerializeFunc GetDataSerialize(const std::string &name);
|
|
+ DataFreeFunc GetDataFreeFunc(const std::string &name);
|
|
void RegisterData(const std::string &name, const RegisterEntry &func);
|
|
private:
|
|
Register() { };
|
|
|
|
- std::unordered_map<std::string, RegisterEntry> deserializeFuncs;
|
|
+ std::unordered_map<std::string, RegisterEntry> registerEntry;
|
|
};
|
|
-
|
|
-int DataListSerialize(const void *data, OutStream &out);
|
|
-int DataListDeserialize(void *data, InStream &in);
|
|
+void DataListFree(DataList *dataList);
|
|
+int DataListSerialize(const DataList *dataList, OutStream &out);
|
|
+int DataListDeserialize(DataList *dataList, InStream &in);
|
|
int ResultDeserialize(void *data, InStream &in);
|
|
-int TopicSerialize(const void *topic, OutStream &out);
|
|
+int TopicSerialize(const CTopic *topic, OutStream &out);
|
|
+int TopicDeserialize(CTopic *topic, InStream &in);
|
|
+void TopicFree(CTopic *topic);
|
|
}
|
|
|
|
#endif
|
|
diff --git a/src/plugin/collect/include/command_data.h b/src/plugin/collect/include/command_data.h
|
|
index f466bd3..e7a8540 100644
|
|
--- a/src/plugin/collect/include/command_data.h
|
|
+++ b/src/plugin/collect/include/command_data.h
|
|
@@ -26,7 +26,7 @@ typedef struct {
|
|
int attrLen;
|
|
char *itemAttr[ATTR_MAX_LENGTH];
|
|
CommandIter *items;
|
|
-} SarData, CommandData;
|
|
+} CommandData;
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
diff --git a/src/plugin_mgr/event/unsubscribe_handler.cpp b/src/plugin_mgr/event/unsubscribe_handler.cpp
|
|
index 72b53bf..749a683 100644
|
|
--- a/src/plugin_mgr/event/unsubscribe_handler.cpp
|
|
+++ b/src/plugin_mgr/event/unsubscribe_handler.cpp
|
|
@@ -23,7 +23,12 @@ EventResult UnsubscribeHandler::Handle(const Event &event)
|
|
INFO(logger, "sdk " << event.payload[0] << " disconnected and has been unsubscribed related topics.");
|
|
return eventResult;
|
|
}
|
|
- auto msg = std::make_shared<InstanceRunMessage>(RunType::UNSUBSCRIBE, event.payload);
|
|
+ CTopic cTopic;
|
|
+ InStream in(event.payload[0]);
|
|
+ TopicDeserialize(&cTopic, in);
|
|
+ Topic topic{cTopic.instanceName, cTopic.topicName, cTopic.params};
|
|
+ auto msg = std::make_shared<InstanceRunMessage>(RunType::UNSUBSCRIBE,
|
|
+ std::vector<std::string>{topic.GetType(), event.payload[1]});
|
|
instanceRunHandler->RecvQueuePush(msg);
|
|
msg->Wait();
|
|
result = msg->result;
|
|
diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp
|
|
index 2e11d0d..30dc886 100644
|
|
--- a/src/plugin_mgr/instance_run_handler.cpp
|
|
+++ b/src/plugin_mgr/instance_run_handler.cpp
|
|
@@ -181,7 +181,7 @@ void InstanceRunHandler::PublishData(std::shared_ptr<InstanceRunMessage> &msg)
|
|
auto instance = memoryStore->GetInstance(subscriber);
|
|
instance->interface->UpdateData(msg->dataList);
|
|
}
|
|
- // free dataList
|
|
+ DataListFree(&msg->dataList);
|
|
}
|
|
|
|
bool InstanceRunHandler::HandleMessage()
|
|
diff --git a/src/sdk/oe_client.cpp b/src/sdk/oe_client.cpp
|
|
index 4eb04ae..9452a37 100644
|
|
--- a/src/sdk/oe_client.cpp
|
|
+++ b/src/sdk/oe_client.cpp
|
|
@@ -70,6 +70,7 @@ void Impl::HandleRecv()
|
|
for (auto handle : topicHandle[key]) {
|
|
handle(&dataList);
|
|
}
|
|
+ DataListFree(&dataList);
|
|
break;
|
|
}
|
|
default:
|
|
--
|
|
2.33.0
|
|
|