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
…IPReceiveUDPMessage
  • Loading branch information
yufengwangca committed Aug 24, 2022
1 parent 0f9615d commit 28485d5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/inet/UDPEndPointImplLwIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,22 @@ 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 (mDelayRelease == true)
{
ChipLogError(Inet, "Unable scedule lambda: %" CHIP_ERROR_FORMAT, err.Format());
// There is nothing we can do here, accept the chance of racing
Release();
mDelayRelease = false;

Retain();
CHIP_ERROR err = GetSystemLayer().ScheduleLambda([this] { Release(); });
if (err != CHIP_NO_ERROR)
{
ChipLogError(Inet, "Unable scedule lambda: %" CHIP_ERROR_FORMAT, err.Format());
// There is nothing we can do here, accept the chance of racing
Release();
}
}
}

Expand All @@ -278,6 +283,9 @@ void UDPEndPointImplLwIP::Free()

void UDPEndPointImplLwIP::HandleDataReceived(System::PacketBufferHandle && msg, IPPacketInfo * pktInfo)
{
// Clear mDelayRelease flag so that we don't need to delay release of current UDPEndPoint.
mDelayRelease = false;

if ((mState == State::kListening) && (OnMessageReceived != nullptr))
{
if (pktInfo != nullptr)
Expand Down Expand Up @@ -391,6 +399,10 @@ void UDPEndPointImplLwIP::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb
pktInfo->SrcPort = port;
pktInfo->DestPort = pcb->local_port;

// Set mDelayRelease flag to delay release of this UDP EndPoint until HandleDataReceived is
// called on this UDP EndPoint.
ep->mDelayRelease = true;

CHIP_ERROR err = ep->GetSystemLayer().ScheduleLambda([ep, p = System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(buf), pktInfo] {
ep->HandleDataReceived(System::PacketBufferHandle::Adopt(p), pktInfo);
});
Expand All @@ -402,6 +414,8 @@ void UDPEndPointImplLwIP::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb
}
else
{
ep->mDelayRelease = false;

// If ScheduleLambda() succeeded, `pktInfo` will be deleted in `HandleDataReceived`.
// Otherwise we delete it here.
Platform::Delete(pktInfo);
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.
bool mDelayRelease = false;
};

using UDPEndPointImpl = UDPEndPointImplLwIP;
Expand Down

0 comments on commit 28485d5

Please sign in to comment.