Auto-release group iterators (#36127)
* Fix up group iterator releasing
* Add missing bracket
* Renames and comments
* Restyled by clang-format
* Update src/app/WriteHandler.cpp
Co-authored-by: Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com>
---------
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com>
diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp
index d2fde33..011fd2e 100644
--- a/src/app/WriteHandler.cpp
+++ b/src/app/WriteHandler.cpp
@@ -42,6 +42,31 @@
namespace chip {
namespace app {
+namespace {
+
+/// Wraps a EndpointIterator and ensures that `::Release()` is called
+/// for the iterator (assuming it is non-null)
+class AutoReleaseGroupEndpointIterator
+{
+public:
+ explicit AutoReleaseGroupEndpointIterator(Credentials::GroupDataProvider::EndpointIterator * iterator) : mIterator(iterator) {}
+ ~AutoReleaseGroupEndpointIterator()
+ {
+ if (mIterator != nullptr)
+ {
+ mIterator->Release();
+ }
+ }
+
+ bool IsNull() const { return mIterator == nullptr; }
+ bool Next(Credentials::GroupDataProvider::GroupEndpoint & item) { return mIterator->Next(item); }
+
+private:
+ Credentials::GroupDataProvider::EndpointIterator * mIterator;
+};
+
+} // namespace
+
using namespace Protocols::InteractionModel;
using Status = Protocols::InteractionModel::Status;
@@ -436,10 +461,6 @@
ConcreteDataAttributePath dataAttributePath;
TLV::TLVReader reader = aAttributeDataIBsReader;
- Credentials::GroupDataProvider::GroupEndpoint mapping;
- Credentials::GroupDataProvider * groupDataProvider = Credentials::GetGroupDataProvider();
- Credentials::GroupDataProvider::EndpointIterator * iterator;
-
err = element.Init(reader);
SuccessOrExit(err);
@@ -461,8 +482,8 @@
"Received group attribute write for Group=%u Cluster=" ChipLogFormatMEI " attribute=" ChipLogFormatMEI,
groupId, ChipLogValueMEI(dataAttributePath.mClusterId), ChipLogValueMEI(dataAttributePath.mAttributeId));
- iterator = groupDataProvider->IterateEndpoints(fabric);
- VerifyOrExit(iterator != nullptr, err = CHIP_ERROR_NO_MEMORY);
+ AutoReleaseGroupEndpointIterator iterator(Credentials::GetGroupDataProvider()->IterateEndpoints(fabric));
+ VerifyOrExit(!iterator.IsNull(), err = CHIP_ERROR_NO_MEMORY);
bool shouldReportListWriteEnd = ShouldReportListWriteEnd(
mProcessingAttributePath, mStateFlags.Has(StateBits::kProcessingAttributeIsList), dataAttributePath);
@@ -470,7 +491,8 @@
std::optional<bool> isListAttribute = std::nullopt;
- while (iterator->Next(mapping))
+ Credentials::GroupDataProvider::GroupEndpoint mapping;
+ while (iterator.Next(mapping))
{
if (groupId != mapping.group_id)
{
@@ -552,7 +574,6 @@
dataAttributePath.mEndpointId = kInvalidEndpointId;
mStateFlags.Set(StateBits::kProcessingAttributeIsList, dataAttributePath.IsListOperation());
mProcessingAttributePath.SetValue(dataAttributePath);
- iterator->Release();
}
if (CHIP_END_OF_TLV == err)