From 716b95770c0a700285344d857f7d6b93c66feb4e Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 30 Aug 2022 17:59:45 -0700 Subject: [PATCH] =?UTF-8?q?Don't=20delay=20the=20release=20of=20Lwip=20UDP?= =?UTF-8?q?EndPoint=20if=20there=20is=20no=20pending=20Lw=E2=80=A6=20(#221?= =?UTF-8?q?22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don't delay the release of Lwip UDPEndPoint if there is no pending LwIPReceiveUDPMessage * Use std::atomic_int instead of bool * Update src/inet/UDPEndPointImplLwIP.cpp Co-authored-by: Zang MingJie * Update src/inet/UDPEndPointImplLwIP.cpp Co-authored-by: Boris Zbarsky Co-authored-by: Zang MingJie Co-authored-by: Boris Zbarsky --- src/inet/UDPEndPointImplLwIP.cpp | 26 +++++++++++++++++++------- src/inet/UDPEndPointImplLwIP.h | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/inet/UDPEndPointImplLwIP.cpp b/src/inet/UDPEndPointImplLwIP.cpp index 2d54324e606fd7..7b9cc6f46415ee 100644 --- a/src/inet/UDPEndPointImplLwIP.cpp +++ b/src/inet/UDPEndPointImplLwIP.cpp @@ -252,17 +252,20 @@ void UDPEndPointImplLwIP::CloseImpl() mUDP = nullptr; mLwIPEndPointType = LwIPEndPointType::Unknown; - // In case that there is a UDPEndPointImplLwIP::LwIPReceiveUDPMessage + // If there is a UDPEndPointImplLwIP::LwIPReceiveUDPMessage // event pending in the event queue (SystemLayer::ScheduleLambda), we // schedule a release call to the end of the queue, to ensure that the // queued pointer to UDPEndPointImplLwIP is not dangling. - Retain(); - CHIP_ERROR err = GetSystemLayer().ScheduleLambda([this] { Release(); }); - if (err != CHIP_NO_ERROR) + if (mDelayReleaseCount != 0) { - ChipLogError(Inet, "Unable scedule lambda: %" CHIP_ERROR_FORMAT, err.Format()); - // There is nothing we can do here, accept the chance of racing - Release(); + Retain(); + CHIP_ERROR err = GetSystemLayer().ScheduleLambda([this] { Release(); }); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Inet, "Unable to schedule lambda: %" CHIP_ERROR_FORMAT, err.Format()); + // There is nothing we can do here, accept the chance of racing + Release(); + } } } @@ -390,8 +393,13 @@ void UDPEndPointImplLwIP::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb pktInfo->SrcPort = port; pktInfo->DestPort = pcb->local_port; + // Increase mDelayReleaseCount to delay release of this UDP EndPoint while the HandleDataReceived call is + // pending on it. + ep->mDelayReleaseCount++; + CHIP_ERROR err = ep->GetSystemLayer().ScheduleLambda( [ep, p = System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(buf), pktInfo = pktInfo.get()] { + ep->mDelayReleaseCount--; ep->HandleDataReceived(System::PacketBufferHandle::Adopt(p), pktInfo); }); @@ -402,6 +410,10 @@ void UDPEndPointImplLwIP::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb // Similarly, ScheduleLambda now has ownership of pktInfo. pktInfo.release(); } + else + { + ep->mDelayReleaseCount--; + } } CHIP_ERROR UDPEndPointImplLwIP::SetMulticastLoopback(IPVersion aIPVersion, bool aLoopback) diff --git a/src/inet/UDPEndPointImplLwIP.h b/src/inet/UDPEndPointImplLwIP.h index 7bc523c913ff3a..3d8aebe1021f52 100644 --- a/src/inet/UDPEndPointImplLwIP.h +++ b/src/inet/UDPEndPointImplLwIP.h @@ -61,6 +61,7 @@ class UDPEndPointImplLwIP : public UDPEndPoint, public EndPointStateLwIP static void LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb, struct pbuf * p, const ip_addr_t * addr, u16_t port); udp_pcb * mUDP; // LwIP User datagram protocol (UDP) control block. + std::atomic_int mDelayReleaseCount{ 0 }; }; using UDPEndPointImpl = UDPEndPointImplLwIP;