Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency of InteractionModelEngine in CommandHandler #31830

Merged
merged 20 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 47 additions & 16 deletions src/app/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <lib/core/CHIPConfig.h>
#include <lib/core/TLVData.h>
#include <lib/core/TLVUtilities.h>
#include <lib/support/IntrusiveList.h>
#include <lib/support/TypeTraits.h>
#include <platform/LockTracker.h>
#include <protocols/secure_channel/Constants.h>
Expand All @@ -58,6 +59,11 @@ CommandHandler::CommandHandler(TestOnlyOverrides & aTestOverride, Callback * apC
}
}

CommandHandler::~CommandHandler()
{
InvalidateHandles();
}

CHIP_ERROR CommandHandler::AllocateBuffer()
{
// We should only allocate a buffer if we will be sending out a response.
Expand Down Expand Up @@ -266,23 +272,48 @@ void CommandHandler::Close()
// reference is the stack shutting down, in which case Close() is not called. So the below check should always pass.
VerifyOrDieWithMsg(mPendingWork == 0, DataManagement, "CommandHandler::Close() called with %u unfinished async work items",
static_cast<unsigned int>(mPendingWork));
InvalidateHandles();

if (mpCallback)
{
mpCallback->OnDone(*this);
}
}

void CommandHandler::IncrementHoldOff()
void CommandHandler::AddToHandleList(Handle * apHandle)
{
mpHandleList.PushBack(apHandle);
}

void CommandHandler::RemoveFromHandleList(Handle * apHandle)
{
VerifyOrDie(mpHandleList.Contains(apHandle));
mpHandleList.Remove(apHandle);
}

void CommandHandler::InvalidateHandles()
{
for (auto handle = mpHandleList.begin(); handle != mpHandleList.end(); ++handle)
{
handle->Invalidate();
}
}

void CommandHandler::IncrementHoldOff(Handle * apHandle)
{
mPendingWork++;
AddToHandleList(apHandle);
}

void CommandHandler::DecrementHoldOff()
void CommandHandler::DecrementHoldOff(Handle * apHandle)
{

mPendingWork--;
ChipLogDetail(DataManagement, "Decreasing reference count for CommandHandler, remaining %u",
static_cast<unsigned int>(mPendingWork));

RemoveFromHandleList(apHandle);

if (mPendingWork != 0)
{
return;
Expand Down Expand Up @@ -771,35 +802,35 @@ FabricIndex CommandHandler::GetAccessingFabricIndex() const
return mpResponder->GetAccessingFabricIndex();
}

void CommandHandler::Handle::Init(CommandHandler * handler)
{
if (handler != nullptr)
{
handler->IncrementHoldOff(this);
mpHandler = handler;
}
}

CommandHandler * CommandHandler::Handle::Get()
{
// Not safe to work with CommandHandler in parallel with other Matter work.
assertChipStackLockedByCurrentThread();

return (mMagic == InteractionModelEngine::GetInstance()->GetMagicNumber()) ? mpHandler : nullptr;
return mpHandler;
}

void CommandHandler::Handle::Release()
{
if (mpHandler != nullptr)
{
if (mMagic == InteractionModelEngine::GetInstance()->GetMagicNumber())
{
mpHandler->DecrementHoldOff();
}
mpHandler = nullptr;
mMagic = 0;
mpHandler->DecrementHoldOff(this);
Invalidate();
}
}

CommandHandler::Handle::Handle(CommandHandler * handle)
CommandHandler::Handle::Handle(CommandHandler * handler)
{
if (handle != nullptr)
{
handle->IncrementHoldOff();
mpHandler = handle;
mMagic = InteractionModelEngine::GetInstance()->GetMagicNumber();
}
Init(handler);
}

CHIP_ERROR CommandHandler::FinalizeInvokeResponseMessageAndPrepareNext()
Expand Down
45 changes: 31 additions & 14 deletions src/app/CommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <lib/support/BitFlags.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/IntrusiveList.h>
#include <lib/support/Scoped.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeHolder.h>
Expand Down Expand Up @@ -110,29 +111,26 @@ class CommandHandler
* The Invoke Response will not be sent until all outstanding Handles have
* been destroyed or have had Release called.
*/
class Handle
class Handle : public IntrusiveListNodeBase<>
{
public:
Handle() {}
Handle(const Handle & handle) = delete;
Handle(Handle && handle)
{
mpHandler = handle.mpHandler;
mMagic = handle.mMagic;
handle.mpHandler = nullptr;
handle.mMagic = 0;
Init(handle.mpHandler);
handle.Release();
}
Handle(decltype(nullptr)) {}
Handle(CommandHandler * handle);
Handle(CommandHandler * handler);
~Handle() { Release(); }

Handle & operator=(Handle && handle)
{
Release();
mpHandler = handle.mpHandler;
mMagic = handle.mMagic;
handle.mpHandler = nullptr;
handle.mMagic = 0;
Init(handle.mpHandler);

handle.Release();
return *this;
}

Expand All @@ -143,16 +141,19 @@ class CommandHandler
}

/**
* Get the CommandHandler object it holds. Get() may return a nullptr if the CommandHandler object is holds is no longer
* Get the CommandHandler object it holds. Get() may return a nullptr if the CommandHandler object it holds is no longer
* valid.
*/
CommandHandler * Get();

void Release();

void Invalidate() { mpHandler = nullptr; }

private:
void Init(CommandHandler * handler);

CommandHandler * mpHandler = nullptr;
uint32_t mMagic = 0;
};

// Previously we kept adding arguments with default values individually as parameters. This is because there
Expand Down Expand Up @@ -191,6 +192,14 @@ class CommandHandler
*/
CommandHandler(Callback * apCallback);

/*
* Destructor.
*
* The call will also invalidate all Handles created for this CommandHandler.
*
*/
~CommandHandler();

/*
* Constructor to override the number of supported paths per invoke and command responder.
*
Expand Down Expand Up @@ -525,13 +534,13 @@ class CommandHandler
* Users should use CommandHandler::Handle for management the lifespan of the CommandHandler.
* DefRef should be released in reasonable time, and Close() should only be called when the refcount reached 0.
*/
void IncrementHoldOff();
void IncrementHoldOff(Handle * apHandle);

/**
* DecrementHoldOff is used by CommandHandler::Handle for decreasing the refcount of the CommandHandler.
* When refcount reached 0, CommandHandler will send the response to the peer and shutdown.
*/
void DecrementHoldOff();
void DecrementHoldOff(Handle * apHandle);

/*
* Allocates a packet buffer used for encoding an invoke response payload.
Expand Down Expand Up @@ -672,12 +681,20 @@ class CommandHandler

size_t MaxPathsPerInvoke() const { return mMaxPathsPerInvoke; }

void AddToHandleList(Handle * handle);

void RemoveFromHandleList(Handle * handle);

void InvalidateHandles();

bool TestOnlyIsInIdleState() const { return mState == State::Idle; }

Callback * mpCallback = nullptr;
InvokeResponseMessage::Builder mInvokeResponseBuilder;
TLV::TLVType mDataElementContainerType = TLV::kTLVType_NotSpecified;
size_t mPendingWork = 0;
/* List to store all currently-outstanding Handles for this Command Handler.*/
IntrusiveList<Handle> mpHandleList;

chip::System::PacketBufferTLVWriter mCommandMessageWriter;
TLV::TLVWriter mBackupWriter;
Expand Down
4 changes: 0 additions & 4 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ CHIP_ERROR InteractionModelEngine::Init(Messaging::ExchangeManager * apExchangeM
ReturnErrorOnFailure(mpExchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::InteractionModel::Id, this));

mReportingEngine.Init();
mMagic++;

StatusIB::RegisterErrorFormatter();

Expand All @@ -111,9 +110,6 @@ void InteractionModelEngine::Shutdown()

mCommandHandlerList = nullptr;

// Increase magic number to invalidate all Handle-s.
mMagic++;

mCommandResponderObjs.ReleaseAll();

mTimedHandlers.ForEachActiveObject([this](TimedHandler * obj) -> Loop {
Expand Down
9 changes: 0 additions & 9 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,6 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
*/
WriteHandler * ActiveWriteHandlerAt(unsigned int aIndex);

/**
* The Magic number of this InteractionModelEngine, the magic number is set during Init()
*/
uint32_t GetMagicNumber() const { return mMagic; }

reporting::Engine & GetReportingEngine() { return mReportingEngine; }

reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; }
Expand Down Expand Up @@ -706,10 +701,6 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
CASESessionManager * mpCASESessionMgr = nullptr;

SubscriptionResumptionStorage * mpSubscriptionResumptionStorage = nullptr;

// A magic number for tracking values between stack Shutdown()-s and Init()-s.
// An ObjectHandle is valid iff. its magic equals to this one.
uint32_t mMagic = 0;
};

} // namespace app
Expand Down
Loading