Skip to content

Commit

Permalink
Modify using uniqur_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
joonhaengHeo committed Apr 17, 2023
1 parent c97da79 commit 40eca60
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 36 deletions.
85 changes: 49 additions & 36 deletions src/darwin/Framework/CHIP/MTRBaseDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,15 @@
NSString * const MTRArrayValueType = @"Array";

class MTRDataValueDictionaryCallbackBridge;
template <typename DecodableValueType> class BufferedReadClientCallback;
class MTRDataValueDictionaryDecodableType;

@interface MTRReadClientContainer : NSObject
@property (nonatomic, readwrite) app::ReadClient * readClientPtr;
@property (nonatomic, readwrite) app::AttributePathParams * pathParams;
@property (nonatomic, readwrite) app::EventPathParams * eventPathParams;
@property (nonatomic, readwrite) uint64_t deviceID;
@property (nonatomic, readwrite) BufferedReadClientCallback<MTRDataValueDictionaryDecodableType> * callbackPtr;
- (void)onDone;
@end

Expand Down Expand Up @@ -158,6 +161,10 @@ static void PurgeReadClientContainers(
Platform::MemoryFree(container.eventPathParams);
container.eventPathParams = nullptr;
}
if (container.callbackPtr != nullptr) {
Platform::Delete(container.callbackPtr);
container.callbackPtr = nullptr;
}
}
[listToDelete removeAllObjects];
if (completion) {
Expand Down Expand Up @@ -240,6 +247,10 @@ - (void)onDone
Platform::MemoryFree(_eventPathParams);
_eventPathParams = nullptr;
}
if (_callbackPtr) {
Platform::Delete(_callbackPtr);
_callbackPtr = nullptr;
}
PurgeCompletedReadClientContainers(_deviceID);
}

Expand All @@ -259,6 +270,10 @@ - (void)dealloc
Platform::MemoryFree(_eventPathParams);
_eventPathParams = nullptr;
}
if (_callbackPtr) {
Platform::Delete(_callbackPtr);
_callbackPtr = nullptr;
}
}
@end

Expand Down Expand Up @@ -748,7 +763,7 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
static void OnSuccessFn(void * context, id value) { DispatchSuccess(context, value); }
};

template <typename DecodableValueType> class BufferedReadClientCallback final : public app::ReadClient::Callback {
template <typename DecodableValueType> class BufferedReadClientCallback : public app::ReadClient::Callback {
public:
using OnSuccessAttributeCallbackType
= std::function<void(const ConcreteAttributePath & aPath, const DecodableValueType & aData)>;
Expand All @@ -765,25 +780,34 @@ CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
OnErrorCallbackType aOnError, OnDoneCallbackType aOnDone,
OnSubscriptionEstablishedCallbackType aOnSubscriptionEstablished = nullptr,
OnDeviceResubscriptionScheduledCallbackType aOnDeviceResubscriptionScheduled = nullptr)
: mAttributePathParamsList(aAttributePathParamsList)
, mAttributePathParamsSize(aAttributePathParamsSize)
, mEventPathParamsList(aEventPathParamsList)
, mEventPathParamsSize(aEventPathParamsSize)
, mOnAttributeSuccess(aOnAttributeSuccess)
: mOnAttributeSuccess(aOnAttributeSuccess)
, mOnEventSuccess(aOnEventSuccess)
, mOnError(aOnError)
, mOnDone(aOnDone)
, mOnSubscriptionEstablished(aOnSubscriptionEstablished)
, mOnDeviceResubscriptionScheduled(aOnDeviceResubscriptionScheduled)
, mBufferedReadAdapter(*this)
{
if (aAttributePathParamsList != nullptr) {
mAttributePathParamsList = Platform::MakeMemoryUnique<app::AttributePathParams>(aAttributePathParamsSize, sizeof(AttributePathParams));
memcpy(mAttributePathParamsList.get(), aAttributePathParamsList, aAttributePathParamsSize * sizeof(AttributePathParams));
mAttributePathParamsSize = aAttributePathParamsSize;
}

if (aEventPathParamsList != nullptr) {
mEventPathParamsList = Platform::MakeMemoryUnique<app::EventPathParams>(aEventPathParamsSize, sizeof(EventPathParams));
memcpy(mEventPathParamsList.get(), aEventPathParamsList, aEventPathParamsSize * sizeof(EventPathParams));
mEventPathParamsSize = aEventPathParamsSize;
}
}

~BufferedReadClientCallback()
{
// Ensure we release the ReadClient before we tear down anything else,
// so it can call our OnDeallocatePaths properly.
mReadClient = nullptr;
mAttributePathParamsList = nullptr;
mEventPathParamsList = nullptr;
}

app::BufferedReadCallback & GetBufferedCallback() { return mBufferedReadAdapter; }
Expand All @@ -809,9 +833,9 @@ void OnAttributeData(

VerifyOrExit(aStatus.IsSuccess(), err = aStatus.ToChipError());
VerifyOrExit(
std::find_if(mAttributePathParamsList, mAttributePathParamsList + mAttributePathParamsSize,
std::find_if(mAttributePathParamsList.get(), mAttributePathParamsList.get() + mAttributePathParamsSize,
[aPath](app::AttributePathParams & pathParam) -> bool { return pathParam.IsAttributePathSupersetOf(aPath); })
!= mAttributePathParamsList + mAttributePathParamsSize,
!= mAttributePathParamsList.get() + mAttributePathParamsSize,
err = CHIP_ERROR_SCHEMA_MISMATCH);
VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);

Expand All @@ -834,11 +858,11 @@ void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, cons

VerifyOrExit(mEventPathParamsList != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);

VerifyOrExit(std::find_if(mEventPathParamsList, mEventPathParamsList + mEventPathParamsSize,
VerifyOrExit(std::find_if(mEventPathParamsList.get(), mEventPathParamsList.get() + mEventPathParamsSize,
[aEventHeader](app::EventPathParams & pathParam) -> bool {
return pathParam.IsEventPathSupersetOf(aEventHeader.mPath);
})
!= mEventPathParamsList + mEventPathParamsSize,
!= mEventPathParamsList.get() + mEventPathParamsSize,
err = CHIP_ERROR_SCHEMA_MISMATCH);
VerifyOrExit(apData != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);

Expand Down Expand Up @@ -887,8 +911,8 @@ void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) overr
OnDeviceResubscriptionScheduledCallbackType mOnDeviceResubscriptionScheduled;
app::BufferedReadCallback mBufferedReadAdapter;
Platform::UniquePtr<app::ReadClient> mReadClient;
app::AttributePathParams * mAttributePathParamsList;
app::EventPathParams * mEventPathParamsList;
Platform::MemoryUniquePtr<app::AttributePathParams> mAttributePathParamsList;
Platform::MemoryUniquePtr<app::EventPathParams> mEventPathParamsList;
size_t mAttributePathParamsSize;
size_t mEventPathParamsSize;
};
Expand Down Expand Up @@ -979,32 +1003,26 @@ - (void)readAttributePaths:(NSArray<MTRAttributeRequestPath *> * _Nullable)attri
}
};

AttributePathParams * attributePathParamsList = nullptr;
EventPathParams * eventPathParamsList = nullptr;
Platform::MemoryUniquePtr<AttributePathParams> attributePathParamsList = nullptr;
Platform::MemoryUniquePtr<EventPathParams> eventPathParamsList = nullptr;

if (attributes != nil) {
size_t count = 0;
attributePathParamsList
= static_cast<AttributePathParams *>(Platform::MemoryCalloc([attributes count], sizeof(AttributePathParams)));
= Platform::MakeMemoryUnique<AttributePathParams>([attributes count], sizeof(AttributePathParams));
VerifyOrReturnError(attributePathParamsList != nullptr, CHIP_ERROR_NO_MEMORY);
for (MTRAttributeRequestPath * attribute in attributes) {
[attribute convertToAttributePathParams:attributePathParamsList[count++]];
[attribute convertToAttributePathParams:attributePathParamsList.get()[count++]];
}
}

if (events != nil) {
size_t count = 0;
eventPathParamsList
= static_cast<EventPathParams *>(Platform::MemoryCalloc([events count], sizeof(EventPathParams)));
if (eventPathParamsList == nullptr) {
if (attributePathParamsList != nullptr) {
Platform::MemoryFree(attributePathParamsList);
attributePathParamsList = nullptr;
}
return CHIP_ERROR_NO_MEMORY;
}
= Platform::MakeMemoryUnique<EventPathParams>([events count], sizeof(EventPathParams));
VerifyOrReturnError(eventPathParamsList != nullptr, CHIP_ERROR_NO_MEMORY);
for (MTREventRequestPath * event in events) {
[event convertToEventPathParams:eventPathParamsList[count++]];
[event convertToEventPathParams:eventPathParamsList.get()[count++]];
}
}

Expand All @@ -1013,31 +1031,24 @@ - (void)readAttributePaths:(NSArray<MTRAttributeRequestPath *> * _Nullable)attri

chip::app::ReadPrepareParams readParams(session);
[params toReadPrepareParams:readParams];
readParams.mpAttributePathParamsList = attributePathParamsList;
readParams.mpAttributePathParamsList = attributePathParamsList.get();
readParams.mAttributePathParamsListSize = [attributePaths count];
readParams.mpEventPathParamsList = eventPathParamsList;
readParams.mpEventPathParamsList = eventPathParamsList.get();
readParams.mEventPathParamsListSize = [eventPaths count];

auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb, attributePathParamsList,
eventPathParamsList](BufferedReadClientCallback<MTRDataValueDictionaryDecodableType> * callback) {
auto onDone = [resultArray, interactionStatus, bridge, successCb, failureCb](BufferedReadClientCallback<MTRDataValueDictionaryDecodableType> * callback) {
if (*interactionStatus != CHIP_NO_ERROR) {
// Failure
failureCb(bridge, *interactionStatus);
} else {
// Success
successCb(bridge, resultArray);
}
if (attributePathParamsList != nullptr) {
Platform::MemoryFree(attributePathParamsList);
}
if (eventPathParamsList != nullptr) {
Platform::MemoryFree(eventPathParamsList);
}
chip::Platform::Delete(callback);
};

auto callback = chip::Platform::MakeUnique<BufferedReadClientCallback<MTRDataValueDictionaryDecodableType>>(
attributePathParamsList, readParams.mAttributePathParamsListSize, eventPathParamsList,
attributePathParamsList.get(), readParams.mAttributePathParamsListSize, eventPathParamsList.get(),
readParams.mEventPathParamsListSize, onAttributeSuccessCb, onEventSuccessCb, onFailureCb, onDone, nullptr);
VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY);

Expand Down Expand Up @@ -1437,6 +1448,7 @@ - (void)subscribeToAttributePaths:(NSArray<MTRAttributeRequestPath *> * _Nullabl
readParams.mEventPathParamsListSize = eventPathSize;

auto onDone = [container](BufferedReadClientCallback<MTRDataValueDictionaryDecodableType> * callback) {
container.callbackPtr = nullptr;
[container onDone];
// Make sure we delete callback last, because doing that actually destroys our
// lambda, so we can't access captured values after that.
Expand Down Expand Up @@ -1477,6 +1489,7 @@ - (void)subscribeToAttributePaths:(NSArray<MTRAttributeRequestPath *> * _Nullabl

// Read clients will be purged when deregistered.
container.readClientPtr = readClient;
container.callbackPtr = callback.get();
AddReadClientContainer(container.deviceID, container);
callback.release();
}];
Expand Down
15 changes: 15 additions & 0 deletions src/lib/support/CHIPMem.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,30 @@ struct Deleter
void operator()(T * p) { Delete(p); }
};

template <typename T>
struct MemoryFreer
{
void operator()(T * p) { MemoryFree(p); }
};

template <typename T>
using UniquePtr = std::unique_ptr<T, Deleter<T>>;

template <typename T>
using MemoryUniquePtr = std::unique_ptr<T, MemoryFreer<T>>;

template <typename T, typename... Args>
inline UniquePtr<T> MakeUnique(Args &&... args)
{
return UniquePtr<T>(New<T>(std::forward<Args>(args)...));
}

template <typename T>
inline MemoryUniquePtr<T> MakeMemoryUnique(size_t num, size_t size)
{
return MemoryUniquePtr<T>(static_cast<T *>(MemoryCalloc(num, size)));
}

template <typename T>
using SharedPtr = std::shared_ptr<T>;

Expand Down

0 comments on commit 40eca60

Please sign in to comment.