Inet/(TCP/UDP)Endpoints: Migrate from SystemPool to BitMapObjectPool (#11428)
* Migrate inet/endpoints to BitMapPool
* Remove atomic
diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp
index 7f07735..ee25bf3 100644
--- a/src/app/tests/integration/chip_im_initiator.cpp
+++ b/src/app/tests/integration/chip_im_initiator.cpp
@@ -709,6 +709,7 @@
chip::DeviceLayer::PlatformMgr().RunEventLoop();
chip::app::InteractionModelEngine::GetInstance()->Shutdown();
+ gTransportManager.Close();
ShutdownChip();
exit:
if (err != CHIP_NO_ERROR || (gCommandRespCount != kMaxCommandMessageCount + kTotalFailureCommandMessageCount))
diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp
index 9be9a07..05fb9b6 100644
--- a/src/app/tests/integration/chip_im_responder.cpp
+++ b/src/app/tests/integration/chip_im_responder.cpp
@@ -248,7 +248,7 @@
}
chip::app::InteractionModelEngine::GetInstance()->Shutdown();
-
+ gTransportManager.Close();
ShutdownChip();
return EXIT_SUCCESS;
diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h
index 15d3ac7..0b28974 100644
--- a/src/include/platform/CHIPDeviceEvent.h
+++ b/src/include/platform/CHIPDeviceEvent.h
@@ -315,6 +315,9 @@
#include <ble/BleConfig.h>
#include <inet/InetLayer.h>
#include <lib/support/LambdaBridge.h>
+#include <system/SystemEvent.h>
+#include <system/SystemLayer.h>
+#include <system/SystemPacketBuffer.h>
namespace chip {
namespace DeviceLayer {
@@ -332,12 +335,6 @@
LambdaBridge LambdaEvent;
struct
{
- ::chip::System::EventType Type;
- ::chip::System::Object * Target;
- uintptr_t Argument;
- } ChipSystemLayerEvent;
- struct
- {
AsyncWorkFunct WorkFunct;
intptr_t Arg;
} CallWorkFunct;
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp
index 041999f..158780f 100644
--- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp
+++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp
@@ -221,11 +221,6 @@
// Do nothing for no-op events.
break;
- case DeviceEventType::kChipSystemLayerEvent:
- // If the event is a CHIP System or Inet Layer event, deliver it to the System::Layer event handler.
- Impl()->DispatchEventToSystemLayer(event);
- break;
-
case DeviceEventType::kChipLambdaEvent:
event->LambdaEvent();
break;
@@ -260,24 +255,6 @@
}
template <class ImplClass>
-void GenericPlatformManagerImpl<ImplClass>::DispatchEventToSystemLayer(const ChipDeviceEvent * event)
-{
- // TODO(#788): remove ifdef LWIP once System::Layer event APIs are generally available
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
- CHIP_ERROR err = CHIP_NO_ERROR;
-
- // Invoke the System Layer's event handler function.
- err = static_cast<System::LayerImplLwIP &>(SystemLayer())
- .HandleEvent(*event->ChipSystemLayerEvent.Target, event->ChipSystemLayerEvent.Type,
- event->ChipSystemLayerEvent.Argument);
- if (err != CHIP_NO_ERROR)
- {
- ChipLogError(DeviceLayer, "Error handling CHIP System Layer event (type %d): %s", event->Type, ErrorStr(err));
- }
-#endif
-}
-
-template <class ImplClass>
void GenericPlatformManagerImpl<ImplClass>::DispatchEventToDeviceLayer(const ChipDeviceEvent * event)
{
// Dispatch the event to all the components in the Device Layer.
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.h b/src/include/platform/internal/GenericPlatformManagerImpl.h
index cb5fc22..cd9be3e 100644
--- a/src/include/platform/internal/GenericPlatformManagerImpl.h
+++ b/src/include/platform/internal/GenericPlatformManagerImpl.h
@@ -69,7 +69,6 @@
// ===== Support methods that can be overridden by the implementation subclass.
- void DispatchEventToSystemLayer(const ChipDeviceEvent * event);
void DispatchEventToDeviceLayer(const ChipDeviceEvent * event);
void DispatchEventToApplication(const ChipDeviceEvent * event);
static void HandleMessageLayerActivityChanged(bool messageLayerIsActive);
diff --git a/src/inet/BUILD.gn b/src/inet/BUILD.gn
index 77eb03a..3c2cace 100644
--- a/src/inet/BUILD.gn
+++ b/src/inet/BUILD.gn
@@ -84,7 +84,6 @@
"InetInterface.h",
"InetLayer.cpp",
"InetLayer.h",
- "InetLayerEvents.h",
"arpa-inet-compatibility.h",
]
diff --git a/src/inet/EndPointBasis.cpp b/src/inet/EndPointBasis.cpp
index 0dc43cf..a4a457b 100644
--- a/src/inet/EndPointBasis.cpp
+++ b/src/inet/EndPointBasis.cpp
@@ -39,18 +39,6 @@
mLwIPEndPointType = LwIPEndPointType::Unknown;
}
-void EndPointBasis::DeferredFree(System::Object::ReleaseDeferralErrorTactic aTactic)
-{
- if (!CHIP_SYSTEM_CONFIG_USE_SOCKETS || (mVoid != nullptr))
- {
- DeferredRelease(static_cast<System::LayerLwIP *>(Layer().SystemLayer()), aTactic);
- }
- else
- {
- Release();
- }
-}
-
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
@@ -62,11 +50,6 @@
mSocket = kInvalidSocketFd;
}
-void EndPointBasis::DeferredFree(System::Object::ReleaseDeferralErrorTactic aTactic)
-{
- Release();
-}
-
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
@@ -77,11 +60,6 @@
mInetLayer = &aInetLayer;
}
-void EndPointBasis::DeferredFree(System::Object::ReleaseDeferralErrorTactic aTactic)
-{
- Release();
-}
-
#endif // CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
} // namespace Inet
diff --git a/src/inet/EndPointBasis.h b/src/inet/EndPointBasis.h
index a6decde..0a68bf5 100644
--- a/src/inet/EndPointBasis.h
+++ b/src/inet/EndPointBasis.h
@@ -28,7 +28,6 @@
#include <inet/IPAddress.h>
#include <lib/support/DLLUtil.h>
-#include <system/SystemObject.h>
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#include <system/SocketEvents.h>
@@ -51,7 +50,7 @@
/**
* Basis of internet transport endpoint classes.
*/
-class DLL_EXPORT EndPointBasis : public System::Object
+class DLL_EXPORT EndPointBasis
{
public:
/**
@@ -68,12 +67,13 @@
*/
bool IsCreatedByInetLayer(const InetLayer & aInetLayer) const { return mInetLayer == &aInetLayer; }
+ void * AppState;
+
private:
InetLayer * mInetLayer; /**< Pointer to the InetLayer object that owns this object. */
protected:
void InitEndPointBasis(InetLayer & aInetLayer, void * aAppState = nullptr);
- void DeferredFree(System::Object::ReleaseDeferralErrorTactic aTactic);
#if CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
nw_parameters_t mParameters;
@@ -91,7 +91,6 @@
/** Encapsulated LwIP protocol control block */
union
{
- const void * mVoid; /**< An untyped protocol control buffer reference */
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
udp_pcb * mUDP; /**< User datagram protocol (UDP) control */
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
diff --git a/src/inet/Inet.h b/src/inet/Inet.h
index 3c94b48..cb6a764 100644
--- a/src/inet/Inet.h
+++ b/src/inet/Inet.h
@@ -32,7 +32,6 @@
#include <inet/InetError.h>
#include <inet/InetInterface.h>
#include <inet/InetLayer.h>
-#include <inet/InetLayerEvents.h>
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
#include <inet/TCPEndPoint.h>
diff --git a/src/inet/InetInterface.cpp b/src/inet/InetInterface.cpp
index f2bc434..8deff39 100644
--- a/src/inet/InetInterface.cpp
+++ b/src/inet/InetInterface.cpp
@@ -30,7 +30,6 @@
#include "InetInterface.h"
#include "InetLayer.h"
-#include "InetLayerEvents.h"
#include <lib/support/CHIPMemString.h>
#include <lib/support/CodeUtils.h>
diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp
index 6f8f279..f5e282d 100644
--- a/src/inet/InetLayer.cpp
+++ b/src/inet/InetLayer.cpp
@@ -79,18 +79,6 @@
namespace chip {
namespace Inet {
-void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot)
-{
-#if INET_CONFIG_ENABLE_TCP_ENDPOINT
- TCPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumTCPEps],
- aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumTCPEps]);
-#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
-#if INET_CONFIG_ENABLE_UDP_ENDPOINT
- UDPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumUDPEps],
- aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumUDPEps]);
-#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
-}
-
/**
* This is the InetLayer default constructor.
*
@@ -99,17 +87,7 @@
* method must be called successfully prior to using the object.
*
*/
-InetLayer::InetLayer()
-{
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
- if (!sInetEventHandlerDelegate.IsInitialized())
- sInetEventHandlerDelegate.Init(HandleInetLayerEvent);
-#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
-}
-
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
-chip::System::LayerLwIP::EventHandlerDelegate InetLayer::sInetEventHandlerDelegate;
-#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
+InetLayer::InetLayer() {}
#if INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP
@@ -248,8 +226,6 @@
#if CHIP_SYSTEM_CONFIG_USE_LWIP
ReturnErrorOnFailure(InitQueueLimiter());
-
- static_cast<System::LayerLwIP *>(mSystemLayer)->AddEventHandlerDelegate(sInetEventHandlerDelegate);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
mLayerState.SetInitialized();
@@ -453,7 +429,7 @@
VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
- *retEndPoint = TCPEndPoint::sPool.TryCreate();
+ *retEndPoint = TCPEndPoint::sPool.CreateObject();
if (*retEndPoint == nullptr)
{
ChipLogError(Inet, "%s endpoint pool FULL", "TCP");
@@ -493,7 +469,7 @@
VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
- *retEndPoint = UDPEndPoint::sPool.TryCreate();
+ *retEndPoint = UDPEndPoint::sPool.CreateObject();
if (*retEndPoint == nullptr)
{
ChipLogError(Inet, "%s endpoint pool FULL", "UDP");
@@ -609,64 +585,6 @@
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
-CHIP_ERROR InetLayer::HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType, uintptr_t aArgument)
-{
- assertChipStackLockedByCurrentThread();
-
- VerifyOrReturnError(INET_IsInetEvent(aEventType), CHIP_ERROR_UNEXPECTED_EVENT);
-
- // Dispatch the event according to its type.
- switch (aEventType)
- {
-#if INET_CONFIG_ENABLE_TCP_ENDPOINT
- case kInetEvent_TCPConnectComplete:
- static_cast<TCPEndPoint &>(aTarget).HandleConnectComplete(static_cast<CHIP_ERROR>(aArgument));
- break;
-
- case kInetEvent_TCPConnectionReceived:
- static_cast<TCPEndPoint &>(aTarget).HandleIncomingConnection(reinterpret_cast<TCPEndPoint *>(aArgument));
- break;
-
- case kInetEvent_TCPDataReceived:
- static_cast<TCPEndPoint &>(aTarget).HandleDataReceived(
- System::PacketBufferHandle::Adopt(reinterpret_cast<chip::System::PacketBuffer *>(aArgument)));
- break;
-
- case kInetEvent_TCPDataSent:
- static_cast<TCPEndPoint &>(aTarget).HandleDataSent(static_cast<uint16_t>(aArgument));
- break;
-
- case kInetEvent_TCPError:
- static_cast<TCPEndPoint &>(aTarget).HandleError(static_cast<CHIP_ERROR>(aArgument));
- break;
-#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
-
-#if INET_CONFIG_ENABLE_UDP_ENDPOINT
- case kInetEvent_UDPDataReceived:
- static_cast<UDPEndPoint &>(aTarget).HandleDataReceived(
- System::PacketBufferHandle::Adopt(reinterpret_cast<chip::System::PacketBuffer *>(aArgument)));
- break;
-#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
-
- default:
- return CHIP_ERROR_UNEXPECTED_EVENT;
- }
-
- // If the event was droppable, record the fact that it has been dequeued.
- if (IsDroppableEvent(aEventType))
- {
- EndPointBasis & lBasis = static_cast<EndPointBasis &>(aTarget);
- InetLayer & lInetLayer = lBasis.Layer();
-
- lInetLayer.DroppableEventDequeued();
- }
-
- return CHIP_NO_ERROR;
-}
-
-#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
-
/**
* Reset the members of the IPPacketInfo object.
*
diff --git a/src/inet/InetLayer.h b/src/inet/InetLayer.h
index 5f040b9..57163ee 100644
--- a/src/inet/InetLayer.h
+++ b/src/inet/InetLayer.h
@@ -55,7 +55,6 @@
#include <inet/IPPrefix.h>
#include <inet/InetError.h>
#include <inet/InetInterface.h>
-#include <inet/InetLayerEvents.h>
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
#include <inet/TCPEndPoint.h>
@@ -151,16 +150,10 @@
CHIP_ERROR GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr);
bool MatchLocalIPv6Subnet(const IPAddress & addr);
- static void UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot);
-
void * GetPlatformData();
void SetPlatformData(void * aPlatformData);
#if CHIP_SYSTEM_CONFIG_USE_LWIP
- static CHIP_ERROR HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType, uintptr_t aArgument);
-
- static chip::System::LayerLwIP::EventHandlerDelegate sInetEventHandlerDelegate;
-
// In some implementations, there may be a shared event / message
// queue for the InetLayer used by other system events / messages.
//
diff --git a/src/inet/InetLayerEvents.h b/src/inet/InetLayerEvents.h
deleted file mode 100644
index 9cb155d..0000000
--- a/src/inet/InetLayerEvents.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * Copyright (c) 2020 Project CHIP Authors
- * Copyright (c) 2013-2017 Nest Labs, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file
- * This file enumerates and defines the different types of events
- * generated at the Inet layer.
- *
- */
-
-#pragma once
-
-#include <inet/InetConfig.h>
-
-#include <system/SystemEvent.h>
-
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
-
-namespace chip {
-namespace Inet {
-
-/**
- * The Inet layer event type definitions.
- *
- */
-enum
-{
- kInetEvent_TCPConnectComplete = _INET_CONFIG_EVENT(0), /**< The event for TCP connection completion */
- kInetEvent_TCPConnectionReceived = _INET_CONFIG_EVENT(1), /**< The event for TCP connection reception */
- kInetEvent_TCPDataReceived = _INET_CONFIG_EVENT(2), /**< The event for data reception over a TCP connection */
- kInetEvent_TCPDataSent = _INET_CONFIG_EVENT(3), /**< The event for data transmission over a TCP connection */
- kInetEvent_TCPError = _INET_CONFIG_EVENT(4), /**< The event for an error on a TCP connection */
- kInetEvent_UDPDataReceived = _INET_CONFIG_EVENT(5), /**< The event for data reception over UDP */
- kInetEvent_DNSResolveComplete = _INET_CONFIG_EVENT(6), /**< The event for DNS name resolution completion */
- kInetEvent_RawDataReceived = _INET_CONFIG_EVENT(7) /**< The event for data reception over an InetLayer raw endpoint */
-};
-
-/**
- * Check to verify if a System::EventType is a valid Inet layer event type.
- *
- * @param[in] aType A chip System Layer event type.
- *
- * @return true if it falls within the enumerated range; otherwise, false.
- *
- */
-static inline bool INET_IsInetEvent(chip::System::EventType aType)
-{
- return (aType >= kInetEvent_TCPConnectComplete && aType <= kInetEvent_RawDataReceived);
-}
-
-} // namespace Inet
-} // namespace chip
-
-#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
diff --git a/src/inet/TCPEndPoint.cpp b/src/inet/TCPEndPoint.cpp
index 7c31e74..f0b5fb2 100644
--- a/src/inet/TCPEndPoint.cpp
+++ b/src/inet/TCPEndPoint.cpp
@@ -87,7 +87,7 @@
namespace chip {
namespace Inet {
-chip::System::ObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> TCPEndPoint::sPool;
+BitMapObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> TCPEndPoint::sPool;
#if CHIP_SYSTEM_CONFIG_USE_LWIP
namespace {
@@ -964,9 +964,8 @@
if (arg != NULL)
{
- CHIP_ERROR conErr;
- TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
- System::LayerLwIP * lSystemLayer = static_cast<System::LayerLwIP *>(ep->Layer().SystemLayer());
+ TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
+ System::Layer * lSystemLayer = ep->Layer().SystemLayer();
if (lwipErr == ERR_OK)
{
@@ -976,10 +975,16 @@
}
// Post callback to HandleConnectComplete.
- conErr = chip::System::MapErrorLwIP(lwipErr);
- if (lSystemLayer->PostEvent(*ep, kInetEvent_TCPConnectComplete, static_cast<uintptr_t>(conErr.AsInteger())) !=
- CHIP_NO_ERROR)
+ ep->Retain();
+ CHIP_ERROR err = lSystemLayer->ScheduleLambda([ep, conErr = System::MapErrorLwIP(lwipErr)] {
+ ep->HandleConnectComplete(conErr);
+ ep->Release();
+ });
+ if (err != CHIP_NO_ERROR)
+ {
+ ep->Release();
res = ERR_ABRT;
+ }
}
else
res = ERR_ABRT;
@@ -996,9 +1001,9 @@
if (arg != NULL)
{
- TCPEndPoint * listenEP = static_cast<TCPEndPoint *>(arg);
- TCPEndPoint * conEP = NULL;
- System::LayerLwIP * lSystemLayer = static_cast<System::LayerLwIP *>(listenEP->Layer().SystemLayer());
+ TCPEndPoint * listenEP = static_cast<TCPEndPoint *>(arg);
+ TCPEndPoint * conEP = NULL;
+ System::Layer * lSystemLayer = listenEP->Layer().SystemLayer();
// Tell LwIP we've accepted the connection so it can decrement the listen PCB's pending_accepts counter.
tcp_accepted(listenEP->mTCP);
@@ -1043,8 +1048,17 @@
tcp_err(tpcb, LwIPHandleError);
// Post a callback to the HandleConnectionReceived() function, passing it the new end point.
- if (lSystemLayer->PostEvent(*listenEP, kInetEvent_TCPConnectionReceived, (uintptr_t) conEP) != CHIP_NO_ERROR)
+ listenEP->Retain();
+ conEP->Retain();
+ err = lSystemLayer->ScheduleLambda([listenEP, conEP] {
+ listenEP->HandleIncomingConnection(conEP);
+ conEP->Release();
+ listenEP->Release();
+ });
+ if (err != CHIP_NO_ERROR)
{
+ conEP->Release(); // for the Ref in ScheduleLambda
+ listenEP->Release();
err = CHIP_ERROR_CONNECTION_ABORTED;
conEP->Release(); // for the Retain() above
conEP->Release(); // for the Retain() in NewTCPEndPoint()
@@ -1053,7 +1067,17 @@
// Otherwise, there was an error accepting the connection, so post a callback to the HandleError function.
else
- lSystemLayer->PostEvent(*listenEP, kInetEvent_TCPError, static_cast<uintptr_t>(err.AsInteger()));
+ {
+ listenEP->Retain();
+ err = lSystemLayer->ScheduleLambda([listenEP, err] {
+ listenEP->HandleError(err);
+ listenEP->Release();
+ });
+ if (err != CHIP_NO_ERROR)
+ {
+ listenEP->Release();
+ }
+ }
}
else
err = CHIP_ERROR_CONNECTION_ABORTED;
@@ -1069,18 +1093,26 @@
}
}
-err_t TCPEndPoint::LwIPHandleDataReceived(void * arg, struct tcp_pcb * tpcb, struct pbuf * p, err_t err)
+err_t TCPEndPoint::LwIPHandleDataReceived(void * arg, struct tcp_pcb * tpcb, struct pbuf * p, err_t _err)
{
err_t res = ERR_OK;
if (arg != NULL)
{
- TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
- System::LayerLwIP * lSystemLayer = static_cast<System::LayerLwIP *>(ep->Layer().SystemLayer());
+ TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
+ System::Layer * lSystemLayer = ep->Layer().SystemLayer();
// Post callback to HandleDataReceived.
- if (lSystemLayer->PostEvent(*ep, kInetEvent_TCPDataReceived, (uintptr_t) p) != CHIP_NO_ERROR)
+ ep->Retain();
+ CHIP_ERROR err = lSystemLayer->ScheduleLambda([ep, p] {
+ ep->HandleDataReceived(System::PacketBufferHandle::Adopt(p));
+ ep->Release();
+ });
+ if (err != CHIP_NO_ERROR)
+ {
+ ep->Release();
res = ERR_ABRT;
+ }
}
else
res = ERR_ABRT;
@@ -1103,12 +1135,20 @@
if (arg != NULL)
{
- TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
- System::LayerLwIP * lSystemLayer = static_cast<System::LayerLwIP *>(ep->Layer().SystemLayer());
+ TCPEndPoint * ep = static_cast<TCPEndPoint *>(arg);
+ System::Layer * lSystemLayer = ep->Layer().SystemLayer();
// Post callback to HandleDataReceived.
- if (lSystemLayer->PostEvent(*ep, kInetEvent_TCPDataSent, (uintptr_t) len) != CHIP_NO_ERROR)
+ ep->Retain();
+ CHIP_ERROR err = lSystemLayer->ScheduleLambda([ep, len] {
+ ep->HandleDataSent(len);
+ ep->Release();
+ });
+ if (err != CHIP_NO_ERROR)
+ {
+ ep->Release();
res = ERR_ABRT;
+ }
}
else
res = ERR_ABRT;
@@ -1135,8 +1175,13 @@
ep->mLwIPEndPointType = LwIPEndPointType::Unknown;
// Post callback to HandleError.
- CHIP_ERROR err = chip::System::MapErrorLwIP(lwipErr);
- lSystemLayer->PostEvent(*ep, kInetEvent_TCPError, static_cast<uintptr_t>(err.AsInteger()));
+ ep->Retain();
+ CHIP_ERROR err = lSystemLayer->ScheduleLambda([ep, conErr = System::MapErrorLwIP(lwipErr)] {
+ ep->HandleError(conErr);
+ ep->Release();
+ });
+ if (err != CHIP_NO_ERROR)
+ ep->Release();
}
}
@@ -1362,8 +1407,7 @@
ReturnErrorOnFailure(static_cast<System::LayerSockets *>(Layer().SystemLayer())
->SetCallback(mWatch, HandlePendingIO, reinterpret_cast<intptr_t>(this)));
- // Once Connecting or Connected, bump the reference count. The corresponding Release()
- // [or on LwIP, DeferredRelease()] will happen in DoClose().
+ // Once Connecting or Connected, bump the reference count. The corresponding Release() will happen in DoClose().
Retain();
if (conRes == 0)
@@ -2339,8 +2383,7 @@
if (res == CHIP_NO_ERROR)
{
- // Once Listening, bump the reference count. The corresponding call to Release()
- // [or on LwIP, DeferredRelease()] will happen in DoClose().
+ // Once Listening, bump the reference count. The corresponding call to Release() will happen in DoClose().
Retain();
mState = State::kListening;
}
@@ -2477,9 +2520,7 @@
Abort();
}
- // Release the Retain() that happened when the end point was allocated
- // [on LwIP, the object may still be alive if DoClose() used the
- // EndPointBasis::DeferredFree() method.]
+ // Release the Retain() that happened when the end point was allocated.
Release();
}
@@ -2713,16 +2754,9 @@
}
// Decrement the ref count that was added when the connection started (in Connect()) or listening started (in Listen()).
- //
- // When using LwIP, post a callback to Release() rather than calling it directly. Since up-calls
- // from LwIP are delivered as events (via the LwIP* methods), we must ensure that all events have been
- // cleared from the queue before the end point gets freed, otherwise we'll end up accessing freed memory.
- // We achieve this by first preventing further up-calls from LwIP (via the call to tcp_abort() above)
- // and then queuing the Release() call to happen after all existing events have been processed.
- //
if (oldState != State::kReady && oldState != State::kBound)
{
- DeferredFree(kReleaseDeferralErrorTactic_Ignore);
+ Release();
}
}
diff --git a/src/inet/TCPEndPoint.h b/src/inet/TCPEndPoint.h
index 77eab74..a6f0574 100644
--- a/src/inet/TCPEndPoint.h
+++ b/src/inet/TCPEndPoint.h
@@ -30,7 +30,9 @@
#include <inet/EndPointBasis.h>
#include <inet/IPAddress.h>
#include <inet/InetInterface.h>
-
+#include <lib/core/ReferenceCounted.h>
+#include <lib/support/Pool.h>
+#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>
#include <utility>
@@ -50,6 +52,13 @@
class InetLayer;
class TCPTest;
+class TCPEndPoint;
+class TCPEndPointDeletor
+{
+public:
+ static void Release(TCPEndPoint * obj);
+};
+
/**
* @brief Objects of this class represent TCP transport endpoints.
*
@@ -58,7 +67,7 @@
* endpoints (SOCK_STREAM sockets on Linux and BSD-derived systems) or LwIP
* TCP protocol control blocks, as the system is configured accordingly.
*/
-class DLL_EXPORT TCPEndPoint : public EndPointBasis
+class DLL_EXPORT TCPEndPoint : public EndPointBasis, public ReferenceCounted<TCPEndPoint, TCPEndPointDeletor>
{
friend class InetLayer;
friend class ::chip::Transport::TCPTest;
@@ -571,7 +580,8 @@
constexpr static size_t kMaxReceiveMessageSize = System::PacketBuffer::kMaxSizeWithoutReserve;
private:
- static chip::System::ObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> sPool;
+ friend class TCPEndPointDeletor;
+ static BitMapObjectPool<TCPEndPoint, INET_CONFIG_NUM_TCP_ENDPOINTS> sPool;
/**
* Basic dynamic state of the underlying endpoint.
@@ -728,5 +738,10 @@
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
};
+inline void TCPEndPointDeletor::Release(TCPEndPoint * obj)
+{
+ TCPEndPoint::sPool.ReleaseObject(obj);
+}
+
} // namespace Inet
} // namespace chip
diff --git a/src/inet/UDPEndPoint.cpp b/src/inet/UDPEndPoint.cpp
index 317266d..a804c37 100644
--- a/src/inet/UDPEndPoint.cpp
+++ b/src/inet/UDPEndPoint.cpp
@@ -130,7 +130,7 @@
namespace chip {
namespace Inet {
-chip::System::ObjectPool<UDPEndPoint, INET_CONFIG_NUM_UDP_ENDPOINTS> UDPEndPoint::sPool;
+BitMapObjectPool<UDPEndPoint, INET_CONFIG_NUM_UDP_ENDPOINTS> UDPEndPoint::sPool;
#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_SOCKETS
@@ -428,7 +428,7 @@
void UDPEndPoint::Free()
{
Close();
- DeferredFree(kReleaseDeferralErrorTactic_Die);
+ Release();
}
void UDPEndPoint::HandleDataReceived(System::PacketBufferHandle && msg)
@@ -536,10 +536,10 @@
void UDPEndPoint::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb, struct pbuf * p, ip_addr_t * addr, u16_t port)
#endif // LWIP_VERSION_MAJOR > 1 || LWIP_VERSION_MINOR >= 5
{
- UDPEndPoint * ep = static_cast<UDPEndPoint *>(arg);
- System::LayerLwIP * lSystemLayer = static_cast<System::LayerLwIP *>(ep->Layer().SystemLayer());
- IPPacketInfo * pktInfo = nullptr;
- System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p);
+ UDPEndPoint * ep = static_cast<UDPEndPoint *>(arg);
+ System::Layer * lSystemLayer = ep->Layer().SystemLayer();
+ IPPacketInfo * pktInfo = nullptr;
+ System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p);
if (buf->HasChainedBuffer())
{
// Try the simple expedient of flattening in-place.
@@ -585,13 +585,22 @@
pktInfo->DestPort = pcb->local_port;
}
- const CHIP_ERROR error =
- lSystemLayer->PostEvent(*ep, kInetEvent_UDPDataReceived, (uintptr_t) System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(buf));
- if (error == CHIP_NO_ERROR)
+ ep->Retain();
+ CHIP_ERROR err = lSystemLayer->ScheduleLambda([ep, p = System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(buf)] {
+ ep->HandleDataReceived(System::PacketBufferHandle::Adopt(p));
+ InetLayer & lInetLayer = ep->Layer();
+ lInetLayer.DroppableEventDequeued();
+ ep->Release();
+ });
+ if (err == CHIP_NO_ERROR)
{
- // If PostEvent() succeeded, it has ownership of the buffer, so we need to release it (without freeing it).
+ // If ScheduleLambda() succeeded, it has ownership of the buffer, so we need to release it (without freeing it).
static_cast<void>(std::move(buf).UnsafeRelease());
}
+ else
+ {
+ ep->Release();
+ }
}
CHIP_ERROR UDPEndPoint::SetMulticastLoopback(IPVersion aIPVersion, bool aLoopback)
diff --git a/src/inet/UDPEndPoint.h b/src/inet/UDPEndPoint.h
index eadb2d9..ae2ad58 100644
--- a/src/inet/UDPEndPoint.h
+++ b/src/inet/UDPEndPoint.h
@@ -31,7 +31,8 @@
#include <inet/EndPointBasis.h>
#include <inet/IPAddress.h>
#include <inet/InetInterface.h>
-
+#include <lib/core/ReferenceCounted.h>
+#include <lib/support/Pool.h>
#include <system/SystemPacketBuffer.h>
#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
@@ -44,6 +45,13 @@
class InetLayer;
class IPPacketInfo;
+class UDPEndPoint;
+class UDPEndPointDeletor
+{
+public:
+ static void Release(UDPEndPoint * obj);
+};
+
/**
* @brief Objects of this class represent UDP transport endpoints.
*
@@ -52,7 +60,7 @@
* endpoints (SOCK_DGRAM sockets on Linux and BSD-derived systems) or LwIP
* UDP protocol control blocks, as the system is configured accordingly.
*/
-class DLL_EXPORT UDPEndPoint : public EndPointBasis
+class DLL_EXPORT UDPEndPoint : public EndPointBasis, public ReferenceCounted<UDPEndPoint, UDPEndPointDeletor>
{
public:
UDPEndPoint() = default;
@@ -280,7 +288,8 @@
CHIP_ERROR IPv4JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join);
CHIP_ERROR IPv6JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join);
- static chip::System::ObjectPool<UDPEndPoint, INET_CONFIG_NUM_UDP_ENDPOINTS> sPool;
+ friend class UDPEndPointDeletor;
+ static BitMapObjectPool<UDPEndPoint, INET_CONFIG_NUM_UDP_ENDPOINTS> sPool;
CHIP_ERROR BindImpl(IPAddressType addressType, const IPAddress & address, uint16_t port, InterfaceId interfaceId);
CHIP_ERROR BindInterfaceImpl(IPAddressType addressType, InterfaceId interfaceId);
@@ -371,5 +380,10 @@
#endif // CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
};
+inline void UDPEndPointDeletor::Release(UDPEndPoint * obj)
+{
+ UDPEndPoint::sPool.ReleaseObject(obj);
+}
+
} // namespace Inet
} // namespace chip
diff --git a/src/inet/tests/TestInetLayerCommon.hpp b/src/inet/tests/TestInetLayerCommon.hpp
index 0d649ed..d34a762 100644
--- a/src/inet/tests/TestInetLayerCommon.hpp
+++ b/src/inet/tests/TestInetLayerCommon.hpp
@@ -34,7 +34,7 @@
#include <inet/InetError.h>
#include <inet/InetInterface.h>
#include <inet/UDPEndPoint.h>
-
+#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>
// Preprocessor Macros
diff --git a/src/lib/core/ReferenceCounted.h b/src/lib/core/ReferenceCounted.h
index bdbbb58..52ebc56 100644
--- a/src/lib/core/ReferenceCounted.h
+++ b/src/lib/core/ReferenceCounted.h
@@ -23,6 +23,7 @@
#pragma once
+#include <atomic>
#include <limits>
#include <stdlib.h>
@@ -45,7 +46,7 @@
class ReferenceCounted
{
public:
- typedef uint32_t count_type;
+ using count_type = uint32_t;
/** Adds one to the usage count of this class */
Subclass * Retain()
diff --git a/src/messaging/tests/echo/echo_requester.cpp b/src/messaging/tests/echo/echo_requester.cpp
index b6e960b..d1936a1 100644
--- a/src/messaging/tests/echo/echo_requester.cpp
+++ b/src/messaging/tests/echo/echo_requester.cpp
@@ -268,6 +268,8 @@
chip::DeviceLayer::PlatformMgr().RunEventLoop();
+ gUDPManager.Close();
+
Shutdown();
exit:
diff --git a/src/messaging/tests/echo/echo_responder.cpp b/src/messaging/tests/echo/echo_responder.cpp
index ec3634c..9dc973f 100644
--- a/src/messaging/tests/echo/echo_responder.cpp
+++ b/src/messaging/tests/echo/echo_responder.cpp
@@ -143,6 +143,8 @@
gEchoServer.Shutdown();
}
+ gUDPManager.Close();
+
ShutdownChip();
return EXIT_SUCCESS;
diff --git a/src/platform/PlatformEventSupport.cpp b/src/platform/PlatformEventSupport.cpp
index 7863aee..1572a3d 100644
--- a/src/platform/PlatformEventSupport.cpp
+++ b/src/platform/PlatformEventSupport.cpp
@@ -41,18 +41,6 @@
return PlatformMgr().PostEvent(&event);
}
-CHIP_ERROR PlatformEventing::PostEvent(System::Layer & aLayer, System::Object & aTarget, System::EventType aType,
- uintptr_t aArgument)
-{
- ChipDeviceEvent event;
- event.Type = DeviceEventType::kChipSystemLayerEvent;
- event.ChipSystemLayerEvent.Type = aType;
- event.ChipSystemLayerEvent.Target = &aTarget;
- event.ChipSystemLayerEvent.Argument = aArgument;
-
- return PlatformMgr().PostEvent(&event);
-}
-
CHIP_ERROR PlatformEventing::StartTimer(System::Layer & aLayer, System::Clock::Timeout delay)
{
return PlatformMgr().StartChipTimer(delay);
diff --git a/src/system/PlatformEventSupport.h b/src/system/PlatformEventSupport.h
index ee17332..9c0e85a 100644
--- a/src/system/PlatformEventSupport.h
+++ b/src/system/PlatformEventSupport.h
@@ -30,7 +30,6 @@
{
public:
static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge);
- static CHIP_ERROR PostEvent(System::Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument);
static CHIP_ERROR StartTimer(System::Layer & aLayer, System::Clock::Timeout aTimeout);
};
diff --git a/src/system/SystemLayer.h b/src/system/SystemLayer.h
index d69c2dd..2377af2 100644
--- a/src/system/SystemLayer.h
+++ b/src/system/SystemLayer.h
@@ -178,60 +178,6 @@
class LayerLwIP : public Layer
{
-protected:
- struct LwIPEventHandlerDelegate;
-
-public:
- class EventHandlerDelegate
- {
- public:
- typedef CHIP_ERROR (*EventHandlerFunction)(Object & aTarget, EventType aEventType, uintptr_t aArgument);
-
- bool IsInitialized(void) const;
- void Init(EventHandlerFunction aFunction);
- void Prepend(const EventHandlerDelegate *& aDelegateList);
-
- private:
- friend class LayerLwIP::LwIPEventHandlerDelegate;
- EventHandlerFunction mFunction;
- const EventHandlerDelegate * mNextDelegate;
- };
-
- /**
- * This adds an event handler delegate to the system layer to extend its ability to handle LwIP events.
- *
- * @param[in] aDelegate An uninitialied LwIP event handler delegate structure
- *
- * @retval CHIP_NO_ERROR On success.
- * @retval CHIP_ERROR_INVALID_ARGUMENT If the function pointer contained in aDelegate is NULL
- */
- virtual CHIP_ERROR AddEventHandlerDelegate(LayerLwIP::EventHandlerDelegate & aDelegate) = 0;
-
- /**
- * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event
- * queue.
- *
- * @param[in,out] aTarget A pointer to the CHIP System Layer object making the post request.
- * @param[in] aEventType The type of event to post.
- * @param[in,out] aArgument The argument associated with the event to post.
- *
- * @retval CHIP_NO_ERROR On success.
- * @retval CHIP_ERROR_INCORRECT_STATE If the state of the Layer object is incorrect.
- * @retval CHIP_ERROR_NO_MEMORY If the event queue is already full.
- * @retval other Platform-specific errors generated indicating the reason for failure.
- */
- virtual CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) = 0;
-
-protected:
- // Provide access to private members of EventHandlerDelegate.
- struct LwIPEventHandlerDelegate : public EventHandlerDelegate
- {
- const EventHandlerFunction & GetFunction() const { return mFunction; }
- const LwIPEventHandlerDelegate * GetNextDelegate() const
- {
- return static_cast<const LwIPEventHandlerDelegate *>(mNextDelegate);
- }
- };
};
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
diff --git a/src/system/SystemLayerImplLwIP.cpp b/src/system/SystemLayerImplLwIP.cpp
index 5117407..c1171f6 100644
--- a/src/system/SystemLayerImplLwIP.cpp
+++ b/src/system/SystemLayerImplLwIP.cpp
@@ -30,7 +30,7 @@
namespace chip {
namespace System {
-LayerImplLwIP::LayerImplLwIP() : mHandlingTimerComplete(false), mEventDelegateList(nullptr) {}
+LayerImplLwIP::LayerImplLwIP() : mHandlingTimerComplete(false) {}
CHIP_ERROR LayerImplLwIP::Init()
{
@@ -97,84 +97,6 @@
return ScheduleLambda([timer] { timer->HandleComplete(); });
}
-bool LayerLwIP::EventHandlerDelegate::IsInitialized() const
-{
- return mFunction != nullptr;
-}
-
-void LayerLwIP::EventHandlerDelegate::Init(EventHandlerFunction aFunction)
-{
- mFunction = aFunction;
- mNextDelegate = nullptr;
-}
-
-void LayerLwIP::EventHandlerDelegate::Prepend(const LayerLwIP::EventHandlerDelegate *& aDelegateList)
-{
- mNextDelegate = aDelegateList;
- aDelegateList = this;
-}
-
-CHIP_ERROR LayerImplLwIP::AddEventHandlerDelegate(EventHandlerDelegate & aDelegate)
-{
- LwIPEventHandlerDelegate & lDelegate = static_cast<LwIPEventHandlerDelegate &>(aDelegate);
- VerifyOrReturnError(lDelegate.GetFunction() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
- lDelegate.Prepend(mEventDelegateList);
- return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR LayerImplLwIP::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
-{
- VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
-
- CHIP_ERROR lReturn = PlatformEventing::PostEvent(*this, aTarget, aEventType, aArgument);
- if (lReturn != CHIP_NO_ERROR)
- {
- ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer event (type %d): %s", aEventType, ErrorStr(lReturn));
- }
- return lReturn;
-}
-
-/**
- * This implements the actual dispatch and handling of a CHIP System Layer event.
- *
- * @param[in,out] aTarget A reference to the layer object to which the event is targeted.
- * @param[in] aEventType The event / message type to handle.
- * @param[in] aArgument The argument associated with the event / message.
- *
- * @retval CHIP_NO_ERROR On success.
- * @retval CHIP_ERROR_INCORRECT_STATE If the state of the InetLayer object is incorrect.
- * @retval CHIP_ERROR_UNEXPECTED_EVENT If the event type is unrecognized.
- */
-CHIP_ERROR LayerImplLwIP::HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
-{
- VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
-
- // Prevent the target object from being freed while dispatching the event.
- aTarget.Retain();
-
- CHIP_ERROR lReturn = CHIP_ERROR_UNEXPECTED_EVENT;
- const LwIPEventHandlerDelegate * lEventDelegate = static_cast<const LwIPEventHandlerDelegate *>(mEventDelegateList);
-
- while (lReturn == CHIP_ERROR_UNEXPECTED_EVENT && lEventDelegate != nullptr)
- {
- lReturn = lEventDelegate->GetFunction()(aTarget, aEventType, aArgument);
- lEventDelegate = lEventDelegate->GetNextDelegate();
- }
-
- if (lReturn == CHIP_ERROR_UNEXPECTED_EVENT)
- {
- ChipLogError(chipSystemLayer, "Unexpected event type %d", aEventType);
- }
-
- /*
- Release the reference to the target object. When the object's lifetime finally comes to an end, in most cases this will be
- the release call that decrements the ref count to zero.
- */
- aTarget.Release();
-
- return lReturn;
-}
-
/**
* Start the platform timer with specified millsecond duration.
*
diff --git a/src/system/SystemLayerImplLwIP.h b/src/system/SystemLayerImplLwIP.h
index 867f198..f2099b3 100644
--- a/src/system/SystemLayerImplLwIP.h
+++ b/src/system/SystemLayerImplLwIP.h
@@ -42,13 +42,8 @@
void CancelTimer(TimerCompleteCallback onComplete, void * appState) override;
CHIP_ERROR ScheduleWork(TimerCompleteCallback onComplete, void * appState) override;
- // LayerLwIP overrides.
- CHIP_ERROR AddEventHandlerDelegate(EventHandlerDelegate & aDelegate);
- CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
-
public:
// Platform implementation.
- CHIP_ERROR HandleEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
CHIP_ERROR HandlePlatformTimer(void);
private:
@@ -58,7 +53,6 @@
Timer::MutexedList mTimerList;
bool mHandlingTimerComplete; // true while handling any timer completion
- const EventHandlerDelegate * mEventDelegateList;
ObjectLifeCycle mLayerState;
};