From 610315eebeaa1f838eb13c460aa20bac5f67d9a4 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 8 Aug 2022 15:27:44 -0400 Subject: [PATCH] Add somewhat better documentation around CommandHandler::Handle. (#21642) * Add somewhat better documentation around CommandHandler::Handle. Fixes https://github.com/project-chip/connectedhomeip/issues/21548 * Address review comments --- src/app/CommandHandler.cpp | 4 ++++ src/app/CommandHandler.h | 31 ++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/app/CommandHandler.cpp b/src/app/CommandHandler.cpp index 9ad0b4eca7cbab..462ebfa900371a 100644 --- a/src/app/CommandHandler.cpp +++ b/src/app/CommandHandler.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include namespace chip { @@ -580,6 +581,9 @@ FabricIndex CommandHandler::GetAccessingFabricIndex() const CommandHandler * CommandHandler::Handle::Get() { + // Not safe to work with CommandHandler in parallel with other Matter work. + assertChipStackLockedByCurrentThread(); + return (mMagic == InteractionModelEngine::GetInstance()->GetMagicNumber()) ? mpHandler : nullptr; } diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index da198cad0af6ef..af89f2a3e32588 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -18,7 +18,13 @@ /** * @file - * This file defines object for a CHIP IM Invoke Command Handler + * A handler for incoming Invoke interactions. + * + * Allows adding responses to be sent in an InvokeResponse: see the various + * "Add*" methods. + * + * Allows adding the responses asynchronously. See the documentation + * for the CommandHandler::Handle class below. * */ @@ -77,6 +83,29 @@ class CommandHandler : public Messaging::ExchangeDelegate virtual Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) = 0; }; + /** + * Class that allows asynchronous command processing before sending a + * response. When such processing is desired: + * + * 1) Create a Handle initialized with the CommandHandler that delivered the + * incoming command. + * 2) Ensure the Handle, or some Handle it's moved into via the move + * constructor or move assignment operator, remains alive during the + * course of the asynchronous processing. + * 3) Ensure that the ConcreteCommandPath involved will be known when + * sending the response. + * 4) When ready to send the response: + * * Ensure that no other Matter tasks are running in parallel (e.g. by + * running on the Matter event loop or holding the Matter stack lock). + * * Call Get() to get the CommandHandler. + * * Check that Get() did not return null. + * * Add the response to the CommandHandler via one of the Add* methods. + * * Let the Handle get destroyed, or manually call Handle::Release() if + * destruction of the Handle is not desirable for some reason. + * + * The Invoke Response will not be sent until all outstanding Handles have + * been destroyed or have had Release called. + */ class Handle { public: