diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp index 7f07735ab9caec..ee25bf366de91f 100644 --- a/src/app/tests/integration/chip_im_initiator.cpp +++ b/src/app/tests/integration/chip_im_initiator.cpp @@ -709,6 +709,7 @@ int main(int argc, char * argv[]) 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 9be9a077614cd0..05fb9b68613234 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -248,7 +248,7 @@ int main(int argc, char * argv[]) } 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 15d3ac7817b114..0b28974210b72b 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -315,6 +315,9 @@ typedef void (*AsyncWorkFunct)(intptr_t arg); #include #include #include +#include +#include +#include namespace chip { namespace DeviceLayer { @@ -331,12 +334,6 @@ struct ChipDeviceEvent final ChipDevicePlatformEvent Platform; LambdaBridge LambdaEvent; struct - { - ::chip::System::EventType Type; - ::chip::System::Object * Target; - uintptr_t Argument; - } ChipSystemLayerEvent; - struct { AsyncWorkFunct WorkFunct; intptr_t Arg; diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index 041999fa4eb45e..158780f37c0c19 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -221,11 +221,6 @@ void GenericPlatformManagerImpl::_DispatchEvent(const ChipDeviceEvent // 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; @@ -259,24 +254,6 @@ void GenericPlatformManagerImpl::_DispatchEvent(const ChipDeviceEvent #endif // CHIP_PROGRESS_LOGGING } -template -void GenericPlatformManagerImpl::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(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 void GenericPlatformManagerImpl::DispatchEventToDeviceLayer(const ChipDeviceEvent * event) { diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.h b/src/include/platform/internal/GenericPlatformManagerImpl.h index cb5fc22e5d189a..cd9be3ec4dc668 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.h +++ b/src/include/platform/internal/GenericPlatformManagerImpl.h @@ -69,7 +69,6 @@ class GenericPlatformManagerImpl // ===== 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 77eb03ad819fe2..3c2caced20f164 100644 --- a/src/inet/BUILD.gn +++ b/src/inet/BUILD.gn @@ -84,7 +84,6 @@ static_library("inet") { "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 0dc43cf79e5ff2..a4a457bad41b9a 100644 --- a/src/inet/EndPointBasis.cpp +++ b/src/inet/EndPointBasis.cpp @@ -39,18 +39,6 @@ void EndPointBasis::InitEndPointBasis(InetLayer & aInetLayer, void * aAppState) mLwIPEndPointType = LwIPEndPointType::Unknown; } -void EndPointBasis::DeferredFree(System::Object::ReleaseDeferralErrorTactic aTactic) -{ - if (!CHIP_SYSTEM_CONFIG_USE_SOCKETS || (mVoid != nullptr)) - { - DeferredRelease(static_cast(Layer().SystemLayer()), aTactic); - } - else - { - Release(); - } -} - #endif // CHIP_SYSTEM_CONFIG_USE_LWIP #if CHIP_SYSTEM_CONFIG_USE_SOCKETS @@ -62,11 +50,6 @@ void EndPointBasis::InitEndPointBasis(InetLayer & aInetLayer, void * aAppState) 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 @@ void EndPointBasis::InitEndPointBasis(InetLayer & aInetLayer, void * aAppState) 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 a6decde4ae2353..0a68bf5c29924a 100644 --- a/src/inet/EndPointBasis.h +++ b/src/inet/EndPointBasis.h @@ -28,7 +28,6 @@ #include #include -#include #if CHIP_SYSTEM_CONFIG_USE_SOCKETS #include @@ -51,7 +50,7 @@ class InetLayer; /** * Basis of internet transport endpoint classes. */ -class DLL_EXPORT EndPointBasis : public System::Object +class DLL_EXPORT EndPointBasis { public: /** @@ -68,12 +67,13 @@ class DLL_EXPORT EndPointBasis : public System::Object */ 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 @@ class DLL_EXPORT EndPointBasis : public System::Object /** 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 3c94b4813016c2..cb6a764567bcd7 100644 --- a/src/inet/Inet.h +++ b/src/inet/Inet.h @@ -32,7 +32,6 @@ #include #include #include -#include #if INET_CONFIG_ENABLE_TCP_ENDPOINT #include diff --git a/src/inet/InetInterface.cpp b/src/inet/InetInterface.cpp index f2bc434be8a524..8deff392f258fd 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 #include diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp index 6f8f279b53e878..f5e282d37a62e8 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 @@ void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot) * 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 @@ CHIP_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) #if CHIP_SYSTEM_CONFIG_USE_LWIP ReturnErrorOnFailure(InitQueueLimiter()); - - static_cast(mSystemLayer)->AddEventHandlerDelegate(sInetEventHandlerDelegate); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP mLayerState.SetInitialized(); @@ -453,7 +429,7 @@ CHIP_ERROR InetLayer::NewTCPEndPoint(TCPEndPoint ** retEndPoint) 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 @@ CHIP_ERROR InetLayer::NewUDPEndPoint(UDPEndPoint ** retEndPoint) 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 @@ void InetLayer::HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, voi } #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(aTarget).HandleConnectComplete(static_cast(aArgument)); - break; - - case kInetEvent_TCPConnectionReceived: - static_cast(aTarget).HandleIncomingConnection(reinterpret_cast(aArgument)); - break; - - case kInetEvent_TCPDataReceived: - static_cast(aTarget).HandleDataReceived( - System::PacketBufferHandle::Adopt(reinterpret_cast(aArgument))); - break; - - case kInetEvent_TCPDataSent: - static_cast(aTarget).HandleDataSent(static_cast(aArgument)); - break; - - case kInetEvent_TCPError: - static_cast(aTarget).HandleError(static_cast(aArgument)); - break; -#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT - -#if INET_CONFIG_ENABLE_UDP_ENDPOINT - case kInetEvent_UDPDataReceived: - static_cast(aTarget).HandleDataReceived( - System::PacketBufferHandle::Adopt(reinterpret_cast(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(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 5f040b9f22c066..57163ee7195c3d 100644 --- a/src/inet/InetLayer.h +++ b/src/inet/InetLayer.h @@ -55,7 +55,6 @@ #include #include #include -#include #if INET_CONFIG_ENABLE_TCP_ENDPOINT #include @@ -151,16 +150,10 @@ class DLL_EXPORT InetLayer 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 9cb155ddb589c5..00000000000000 --- 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 - -#include - -#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 7c31e74e8e8e99..f0b5fb207fad71 100644 --- a/src/inet/TCPEndPoint.cpp +++ b/src/inet/TCPEndPoint.cpp @@ -87,7 +87,7 @@ namespace chip { namespace Inet { -chip::System::ObjectPool TCPEndPoint::sPool; +BitMapObjectPool TCPEndPoint::sPool; #if CHIP_SYSTEM_CONFIG_USE_LWIP namespace { @@ -964,9 +964,8 @@ err_t TCPEndPoint::LwIPHandleConnectComplete(void * arg, struct tcp_pcb * tpcb, if (arg != NULL) { - CHIP_ERROR conErr; - TCPEndPoint * ep = static_cast(arg); - System::LayerLwIP * lSystemLayer = static_cast(ep->Layer().SystemLayer()); + TCPEndPoint * ep = static_cast(arg); + System::Layer * lSystemLayer = ep->Layer().SystemLayer(); if (lwipErr == ERR_OK) { @@ -976,10 +975,16 @@ err_t TCPEndPoint::LwIPHandleConnectComplete(void * arg, struct tcp_pcb * tpcb, } // Post callback to HandleConnectComplete. - conErr = chip::System::MapErrorLwIP(lwipErr); - if (lSystemLayer->PostEvent(*ep, kInetEvent_TCPConnectComplete, static_cast(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 @@ err_t TCPEndPoint::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc if (arg != NULL) { - TCPEndPoint * listenEP = static_cast(arg); - TCPEndPoint * conEP = NULL; - System::LayerLwIP * lSystemLayer = static_cast(listenEP->Layer().SystemLayer()); + TCPEndPoint * listenEP = static_cast(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 @@ err_t TCPEndPoint::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc 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 @@ err_t TCPEndPoint::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc // Otherwise, there was an error accepting the connection, so post a callback to the HandleError function. else - lSystemLayer->PostEvent(*listenEP, kInetEvent_TCPError, static_cast(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::LwIPHandleIncomingConnection(void * arg, struct tcp_pcb * tpc } } -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(arg); - System::LayerLwIP * lSystemLayer = static_cast(ep->Layer().SystemLayer()); + TCPEndPoint * ep = static_cast(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 @@ err_t TCPEndPoint::LwIPHandleDataSent(void * arg, struct tcp_pcb * tpcb, u16_t l if (arg != NULL) { - TCPEndPoint * ep = static_cast(arg); - System::LayerLwIP * lSystemLayer = static_cast(ep->Layer().SystemLayer()); + TCPEndPoint * ep = static_cast(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 @@ void TCPEndPoint::LwIPHandleError(void * arg, err_t lwipErr) ep->mLwIPEndPointType = LwIPEndPointType::Unknown; // Post callback to HandleError. - CHIP_ERROR err = chip::System::MapErrorLwIP(lwipErr); - lSystemLayer->PostEvent(*ep, kInetEvent_TCPError, static_cast(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 @@ CHIP_ERROR TCPEndPoint::ConnectImpl(const IPAddress & addr, uint16_t port, Inter ReturnErrorOnFailure(static_cast(Layer().SystemLayer()) ->SetCallback(mWatch, HandlePendingIO, reinterpret_cast(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 @@ CHIP_ERROR TCPEndPoint::Listen(uint16_t backlog) 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 @@ void TCPEndPoint::Free() 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 @@ CHIP_ERROR TCPEndPoint::DoClose(CHIP_ERROR err, bool suppressCallback) } // 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 77eab7408f9b85..a6f05744df2685 100644 --- a/src/inet/TCPEndPoint.h +++ b/src/inet/TCPEndPoint.h @@ -30,7 +30,9 @@ #include #include #include - +#include +#include +#include #include #include @@ -50,6 +52,13 @@ namespace Inet { 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 @@ class TCPTest; * 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 { friend class InetLayer; friend class ::chip::Transport::TCPTest; @@ -571,7 +580,8 @@ class DLL_EXPORT TCPEndPoint : public EndPointBasis constexpr static size_t kMaxReceiveMessageSize = System::PacketBuffer::kMaxSizeWithoutReserve; private: - static chip::System::ObjectPool sPool; + friend class TCPEndPointDeletor; + static BitMapObjectPool sPool; /** * Basic dynamic state of the underlying endpoint. @@ -728,5 +738,10 @@ class DLL_EXPORT TCPEndPoint : public EndPointBasis #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 317266d38236fd..a804c37af77efb 100644 --- a/src/inet/UDPEndPoint.cpp +++ b/src/inet/UDPEndPoint.cpp @@ -130,7 +130,7 @@ namespace chip { namespace Inet { -chip::System::ObjectPool UDPEndPoint::sPool; +BitMapObjectPool UDPEndPoint::sPool; #if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_SOCKETS @@ -428,7 +428,7 @@ void UDPEndPoint::CloseImpl() 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 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(arg); - System::LayerLwIP * lSystemLayer = static_cast(ep->Layer().SystemLayer()); - IPPacketInfo * pktInfo = nullptr; - System::PacketBufferHandle buf = System::PacketBufferHandle::Adopt(p); + UDPEndPoint * ep = static_cast(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 @@ void UDPEndPoint::LwIPReceiveUDPMessage(void * arg, struct udp_pcb * pcb, struct 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(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 eadb2d935e3858..ae2ad58c357b7d 100644 --- a/src/inet/UDPEndPoint.h +++ b/src/inet/UDPEndPoint.h @@ -31,7 +31,8 @@ #include #include #include - +#include +#include #include #if CHIP_SYSTEM_CONFIG_USE_DISPATCH @@ -44,6 +45,13 @@ namespace Inet { 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 @@ class IPPacketInfo; * 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 { public: UDPEndPoint() = default; @@ -280,7 +288,8 @@ class DLL_EXPORT UDPEndPoint : public EndPointBasis CHIP_ERROR IPv4JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join); CHIP_ERROR IPv6JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join); - static chip::System::ObjectPool sPool; + friend class UDPEndPointDeletor; + static BitMapObjectPool 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 @@ class DLL_EXPORT UDPEndPoint : public EndPointBasis #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 0d649ed4904832..d34a7628ea3a3c 100644 --- a/src/inet/tests/TestInetLayerCommon.hpp +++ b/src/inet/tests/TestInetLayerCommon.hpp @@ -34,7 +34,7 @@ #include #include #include - +#include #include // Preprocessor Macros diff --git a/src/lib/core/ReferenceCounted.h b/src/lib/core/ReferenceCounted.h index bdbbb5830ccd16..52ebc56d13a7e3 100644 --- a/src/lib/core/ReferenceCounted.h +++ b/src/lib/core/ReferenceCounted.h @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -45,7 +46,7 @@ template , int kInitRefC 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 b6e960bea54d79..d1936a12b673b5 100644 --- a/src/messaging/tests/echo/echo_requester.cpp +++ b/src/messaging/tests/echo/echo_requester.cpp @@ -268,6 +268,8 @@ int main(int argc, char * argv[]) 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 ec3634c2b2b861..9dc973f890fe18 100644 --- a/src/messaging/tests/echo/echo_responder.cpp +++ b/src/messaging/tests/echo/echo_responder.cpp @@ -143,6 +143,8 @@ int main(int argc, char * argv[]) gEchoServer.Shutdown(); } + gUDPManager.Close(); + ShutdownChip(); return EXIT_SUCCESS; diff --git a/src/platform/PlatformEventSupport.cpp b/src/platform/PlatformEventSupport.cpp index 7863aeea817bf2..1572a3da865457 100644 --- a/src/platform/PlatformEventSupport.cpp +++ b/src/platform/PlatformEventSupport.cpp @@ -41,18 +41,6 @@ CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, Lambda 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 ee17332a04df4a..9c0e85a545cd44 100644 --- a/src/system/PlatformEventSupport.h +++ b/src/system/PlatformEventSupport.h @@ -30,7 +30,6 @@ class PlatformEventing { 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 d69c2ddb773a44..2377af2333b91c 100644 --- a/src/system/SystemLayer.h +++ b/src/system/SystemLayer.h @@ -178,60 +178,6 @@ class DLL_EXPORT Layer 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(mNextDelegate); - } - }; }; #endif // CHIP_SYSTEM_CONFIG_USE_LWIP diff --git a/src/system/SystemLayerImplLwIP.cpp b/src/system/SystemLayerImplLwIP.cpp index 5117407cb6ca84..c1171f66f9026c 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 @@ CHIP_ERROR LayerImplLwIP::ScheduleWork(TimerCompleteCallback onComplete, void * 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(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(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 867f198c0119e9..f2099b3aab7ed2 100644 --- a/src/system/SystemLayerImplLwIP.h +++ b/src/system/SystemLayerImplLwIP.h @@ -42,13 +42,8 @@ class LayerImplLwIP : public LayerLwIP 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 @@ class LayerImplLwIP : public LayerLwIP Timer::MutexedList mTimerList; bool mHandlingTimerComplete; // true while handling any timer completion - const EventHandlerDelegate * mEventDelegateList; ObjectLifeCycle mLayerState; };