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;