Skip to content

Commit

Permalink
Don't delay the release of Lwip UDPEndPoint if there is no pending Lw… (
Browse files Browse the repository at this point in the history
project-chip#22122)

* 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 <zealot0630@gmail.com>

* Update src/inet/UDPEndPointImplLwIP.cpp

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

Co-authored-by: Zang MingJie <zealot0630@gmail.com>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
  • Loading branch information
3 people authored Aug 31, 2022
1 parent 13e6825 commit 716b957
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/inet/UDPEndPointImplLwIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}

Expand Down Expand Up @@ -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);
});

Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/inet/UDPEndPointImplLwIP.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 716b957

Please sign in to comment.