Skip to content

Commit

Permalink
RAII changes
Browse files Browse the repository at this point in the history
  • Loading branch information
wqx6 committed Dec 15, 2023
1 parent d03d9f3 commit 4192753
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 27 deletions.
26 changes: 20 additions & 6 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@
namespace chip {
namespace app {

class AutoReleaseSubscriptionInfoIterator
{
public:
AutoReleaseSubscriptionInfoIterator(SubscriptionResumptionStorage::SubscriptionInfoIterator *iterator) : mIterator(iterator) {};
~AutoReleaseSubscriptionInfoIterator()
{
mIterator->Release();
}

SubscriptionResumptionStorage::SubscriptionInfoIterator *operator->() const
{
return mIterator;
}
private:
SubscriptionResumptionStorage::SubscriptionInfoIterator *mIterator;
};

using Protocols::InteractionModel::Status;

Global<InteractionModelEngine> sInteractionModelEngine;
Expand Down Expand Up @@ -1835,7 +1852,7 @@ void InteractionModelEngine::ResumeSubscriptionsTimerCallback(System::Layer * ap
bool resumedSubscriptions = false;
#endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
SubscriptionResumptionStorage::SubscriptionInfo subscriptionInfo;
auto * iterator = imEngine->mpSubscriptionResumptionStorage->IterateSubscriptions();
AutoReleaseSubscriptionInfoIterator iterator(imEngine->mpSubscriptionResumptionStorage->IterateSubscriptions());
while (iterator->Next(subscriptionInfo))
{
// If subscription happens between reboot and this timer callback, it's already live and should skip resumption
Expand All @@ -1853,27 +1870,24 @@ void InteractionModelEngine::ResumeSubscriptionsTimerCallback(System::Layer * ap
continue;
}

auto subscriptionResumptionSessionEstablisher = Platform::New<SubscriptionResumptionSessionEstablisher>();
auto subscriptionResumptionSessionEstablisher = Platform::MakeUnique<SubscriptionResumptionSessionEstablisher>();
if (subscriptionResumptionSessionEstablisher == nullptr)
{
ChipLogProgress(InteractionModel, "Failed to create SubscriptionResumptionSessionEstablisher");
iterator->Release();
return;
}

if (subscriptionResumptionSessionEstablisher->ResumeSubscription(*imEngine->mpCASESessionMgr, subscriptionInfo) !=
CHIP_NO_ERROR)
{
ChipLogProgress(InteractionModel, "Failed to ResumeSubscription 0x%" PRIx32, subscriptionInfo.mSubscriptionId);
iterator->Release();
Platform::Delete(subscriptionResumptionSessionEstablisher);
return;
}
subscriptionResumptionSessionEstablisher.release();
#if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
resumedSubscriptions = true;
#endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
}
iterator->Release();

#if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
// If no persisted subscriptions needed resumption then all resumption retries are done
Expand Down
18 changes: 9 additions & 9 deletions src/app/ReadHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,28 @@ ReadHandler::ReadHandler(ManagementCallback & apCallback, Observer * observer) :
mObserver = observer;
}

void ReadHandler::OnSubscriptionResumed(const SessionHandle & sessionHandle, SubscriptionResumptionSessionEstablisher & helper)
void ReadHandler::OnSubscriptionResumed(const SessionHandle & sessionHandle, SubscriptionResumptionSessionEstablisher & resumptionSessionEstablisher)
{
mSubscriptionId = helper.mSubscriptionInfo.mSubscriptionId;
mMinIntervalFloorSeconds = helper.mSubscriptionInfo.mMinInterval;
mMaxInterval = helper.mSubscriptionInfo.mMaxInterval;
SetStateFlag(ReadHandlerFlags::FabricFiltered, helper.mSubscriptionInfo.mFabricFiltered);
mSubscriptionId = resumptionSessionEstablisher.mSubscriptionInfo.mSubscriptionId;
mMinIntervalFloorSeconds = resumptionSessionEstablisher.mSubscriptionInfo.mMinInterval;
mMaxInterval = resumptionSessionEstablisher.mSubscriptionInfo.mMaxInterval;
SetStateFlag(ReadHandlerFlags::FabricFiltered, resumptionSessionEstablisher.mSubscriptionInfo.mFabricFiltered);

// Move dynamically allocated attributes and events from the SubscriptionInfo struct into
// the object pool managed by the IM engine
for (size_t i = 0; i < helper.mSubscriptionInfo.mAttributePaths.AllocatedSize(); i++)
for (size_t i = 0; i < resumptionSessionEstablisher.mSubscriptionInfo.mAttributePaths.AllocatedSize(); i++)
{
AttributePathParams params = helper.mSubscriptionInfo.mAttributePaths[i].GetParams();
AttributePathParams params = resumptionSessionEstablisher.mSubscriptionInfo.mAttributePaths[i].GetParams();
CHIP_ERROR err = InteractionModelEngine::GetInstance()->PushFrontAttributePathList(mpAttributePathList, params);
if (err != CHIP_NO_ERROR)
{
Close();
return;
}
}
for (size_t i = 0; i < helper.mSubscriptionInfo.mEventPaths.AllocatedSize(); i++)
for (size_t i = 0; i < resumptionSessionEstablisher.mSubscriptionInfo.mEventPaths.AllocatedSize(); i++)
{
EventPathParams params = helper.mSubscriptionInfo.mEventPaths[i].GetParams();
EventPathParams params = resumptionSessionEstablisher.mSubscriptionInfo.mEventPaths[i].GetParams();
CHIP_ERROR err = InteractionModelEngine::GetInstance()->PushFrontEventPathParamsList(mpEventPathList, params);
if (err != CHIP_NO_ERROR)
{
Expand Down
38 changes: 29 additions & 9 deletions src/app/SubscriptionResumptionSessionEstablisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@

namespace chip {
namespace app {

class AutoDeleteEstablisher
{
public:
AutoDeleteEstablisher(SubscriptionResumptionSessionEstablisher * sessionEstablisher) : mSessionEstablisher(sessionEstablisher) {}
~AutoDeleteEstablisher()
{
chip::Platform::Delete(mSessionEstablisher);
}

SubscriptionResumptionSessionEstablisher * operator->() const
{
return mSessionEstablisher;
}

SubscriptionResumptionSessionEstablisher & operator*() const
{
return *mSessionEstablisher;
}

private:
SubscriptionResumptionSessionEstablisher * mSessionEstablisher;
};

SubscriptionResumptionSessionEstablisher::SubscriptionResumptionSessionEstablisher() :
mOnConnectedCallback(HandleDeviceConnected, this), mOnConnectionFailureCallback(HandleDeviceConnectionFailure, this)
{}
Expand Down Expand Up @@ -68,32 +92,29 @@ SubscriptionResumptionSessionEstablisher::ResumeSubscription(
void SubscriptionResumptionSessionEstablisher::HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr,
const SessionHandle & sessionHandle)
{
SubscriptionResumptionSessionEstablisher * _this = static_cast<SubscriptionResumptionSessionEstablisher *>(context);
SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = _this->mSubscriptionInfo;
AutoDeleteEstablisher establisher(static_cast<SubscriptionResumptionSessionEstablisher *>(context));
SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = establisher->mSubscriptionInfo;
InteractionModelEngine * imEngine = InteractionModelEngine::GetInstance();
if (!imEngine->EnsureResourceForSubscription(subscriptionInfo.mFabricIndex, subscriptionInfo.mAttributePaths.AllocatedSize(),
subscriptionInfo.mEventPaths.AllocatedSize()))
{
ChipLogProgress(InteractionModel, "no resource for subscription resumption");
delete _this;
return;
}
ReadHandler * readHandler = imEngine->mReadHandlers.CreateObject(*imEngine, imEngine->GetReportScheduler());
if (readHandler == nullptr)
{
ChipLogProgress(InteractionModel, "no resource for ReadHandler creation");
delete _this;
return;
}
readHandler->OnSubscriptionResumed(sessionHandle, *_this);
delete _this;
readHandler->OnSubscriptionResumed(sessionHandle, *establisher);
}

void SubscriptionResumptionSessionEstablisher::HandleDeviceConnectionFailure(void * context, const ScopedNodeId & peerId,
CHIP_ERROR error)
{
SubscriptionResumptionSessionEstablisher * _this = static_cast<SubscriptionResumptionSessionEstablisher *>(context);
SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = _this->mSubscriptionInfo;
AutoDeleteEstablisher establisher(static_cast<SubscriptionResumptionSessionEstablisher *>(context));
SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = establisher->mSubscriptionInfo;
ChipLogError(DataManagement, "Failed to establish CASE for subscription-resumption with error '%" CHIP_ERROR_FORMAT "'",
error.Format());
// If the device fails to establish the session, the subscriber might be offline and its subscription read client will
Expand All @@ -105,7 +126,6 @@ void SubscriptionResumptionSessionEstablisher::HandleDeviceConnectionFailure(voi
subscriptionResumptionStorage->Delete(subscriptionInfo.mNodeId, subscriptionInfo.mFabricIndex,
subscriptionInfo.mSubscriptionId);
}
delete _this;
}

} // namespace app
Expand Down
4 changes: 1 addition & 3 deletions src/app/SubscriptionResumptionSessionEstablisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace chip {
namespace app {

/**
* Session Esatblisher to resume persistent subscription. A CASE session will be established upon invoking
* Session Establisher to resume persistent subscription. A CASE session will be established upon invoking
* ResumeSubscription(), followed by the creation and intialization of a ReadHandler. This class helps prevent
* a scenario where all ReadHandlers in the pool grab the invalid session handle. In such scenario, if the device
* receives a new subscription request, it will crash as there is no evictable ReadHandler.
Expand All @@ -36,8 +36,6 @@ class SubscriptionResumptionSessionEstablisher
public:
SubscriptionResumptionSessionEstablisher();

~SubscriptionResumptionSessionEstablisher() {}

CHIP_ERROR ResumeSubscription(CASESessionManager & caseSessionManager,
const SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo);

Expand Down

0 comments on commit 4192753

Please sign in to comment.