From f234a793f330184725371340bf5d7cda4caa22a2 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 6 Mar 2025 13:03:25 -0500 Subject: [PATCH] Coalesce operational instance adds in MTROperationalBrowser. This way we will only notify once if we get Add notifications all together on multiple interfaces. --- .../Framework/CHIP/MTROperationalBrowser.h | 8 +++-- .../Framework/CHIP/MTROperationalBrowser.mm | 34 +++++++++++++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTROperationalBrowser.h b/src/darwin/Framework/CHIP/MTROperationalBrowser.h index 4115f0e887d150..b249280cbe62c1 100644 --- a/src/darwin/Framework/CHIP/MTROperationalBrowser.h +++ b/src/darwin/Framework/CHIP/MTROperationalBrowser.h @@ -20,8 +20,7 @@ #import #import -class MTROperationalBrowser -{ +class MTROperationalBrowser { public: // Should be created at a point when the dispatch queue is available. MTROperationalBrowser(MTRDeviceControllerFactory * aFactory, dispatch_queue_t aQueue); @@ -40,7 +39,7 @@ class MTROperationalBrowser private: static void OnBrowse(DNSServiceRef aServiceRef, DNSServiceFlags aFlags, uint32_t aInterfaceId, DNSServiceErrorType aError, - const char * aName, const char * aType, const char * aDomain, void * aContext); + const char * aName, const char * aType, const char * aDomain, void * aContext); void EnsureBrowse(); void StopBrowse(); @@ -58,4 +57,7 @@ class MTROperationalBrowser // Count of controllers that are currently active; we aim to have a browse // going while this is nonzero; size_t mActiveControllerCount = 0; + + // Queued-up instance names to notify about. + NSMutableSet * mAddedInstanceNames = nil; }; diff --git a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm index b8bc3fd3b4f155..96fd2a6daa13c6 100644 --- a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm +++ b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm @@ -85,6 +85,8 @@ return; } + mAddedInstanceNames = [[NSMutableSet alloc] init]; + mInitialized = true; for (auto domain : kBrowseDomains) { @@ -100,6 +102,7 @@ { ChipLogProgress(Controller, "%p stopping persistent operational browse", this); if (mInitialized) { + mAddedInstanceNames = nil; DNSServiceRefDeallocate(mBrowseRef); mInitialized = false; } @@ -126,22 +129,33 @@ return; } - chip::PeerId peerId; - CHIP_ERROR err = chip::Dnssd::ExtractIdFromInstanceName(aName, &peerId); - if (err != CHIP_NO_ERROR) { - ChipLogError(Controller, "Invalid instance name: '%s'\n", aName); + auto * newInstanceName = [NSString stringWithUTF8String:aName]; + if (!(aFlags & kDNSServiceFlagsAdd)) { + MTR_LOG("Matter operational instance advertisement removed: '%@'\n", newInstanceName); + // Make sure that we don't notify about things that appear and then disappear. + [self->mAddedInstanceNames removeObject:newInstanceName]; return; } - if (!(aFlags & kDNSServiceFlagsAdd)) { - // We mostly only care about new things appearing, but log it when things - // disappear. - MTR_LOG("Matter operational instance advertisement removed: '%s'\n", aName); + [self->mAddedInstanceNames addObject:newInstanceName]; + + if (aFlags & kDNSServiceFlagsMoreComing) { + // Just wait for those other notifications, so we coalesce everything. return; } - ChipLogProgress(Controller, "Notifying controller factory about new operational instance: '%s'", aName); - [self->mDeviceControllerFactory operationalInstanceAdded:peerId]; + for (NSString * instanceName in self->mAddedInstanceNames) { + chip::PeerId peerId; + CHIP_ERROR err = chip::Dnssd::ExtractIdFromInstanceName(instanceName.UTF8String, &peerId); + if (err != CHIP_NO_ERROR) { + ChipLogError(Controller, "Invalid instance name: '%@'\n", instanceName); + continue; + } + + ChipLogProgress(Controller, "Notifying controller factory about new operational instance: '%@'", instanceName); + [self->mDeviceControllerFactory operationalInstanceAdded:peerId]; + } + [self->mAddedInstanceNames removeAllObjects]; } MTROperationalBrowser::~MTROperationalBrowser()