From 3635394247441009a918d6f61bfac177999e26dc Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 2 Nov 2021 20:12:02 -0400 Subject: [PATCH] Revert "Pull up LayerLwIP::ScheduleLambda to SystemLayer (#11187)" (#11341) This reverts commit 16cd474e9068e3184865603e8812849b1cc0644c. --- src/include/platform/CHIPDeviceEvent.h | 7 +- src/include/platform/PlatformManager.h | 5 +- .../internal/GenericPlatformManagerImpl.cpp | 2 +- src/lib/support/LambdaBridge.h | 53 --------------- src/platform/BUILD.gn | 2 +- ...mEventSupport.cpp => LwIPEventSupport.cpp} | 4 +- src/system/BUILD.gn | 3 +- ...tformEventSupport.h => LwIPEventSupport.h} | 2 +- src/system/SystemLayer.cpp | 35 ---------- src/system/SystemLayer.h | 64 +++++++++++-------- src/system/SystemLayerImplLwIP.cpp | 14 +++- src/system/SystemLayerImplLwIP.h | 1 + 12 files changed, 65 insertions(+), 127 deletions(-) delete mode 100644 src/lib/support/LambdaBridge.h rename src/platform/{PlatformEventSupport.cpp => LwIPEventSupport.cpp} (96%) rename src/system/{PlatformEventSupport.h => LwIPEventSupport.h} (97%) delete mode 100644 src/system/SystemLayer.cpp diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index 0d3da3b44db27d..4583f6cc887c7b 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -307,7 +307,10 @@ typedef void (*AsyncWorkFunct)(intptr_t arg); #include #include -#include +#include +#include +#include +#include namespace chip { namespace DeviceLayer { @@ -322,7 +325,7 @@ struct ChipDeviceEvent final union { ChipDevicePlatformEvent Platform; - LambdaBridge LambdaEvent; + System::LambdaBridge LambdaEvent; struct { ::chip::System::EventType Type; diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h index 5bbb68c9adf2cc..38cf83fa41c04f 100644 --- a/src/include/platform/PlatformManager.h +++ b/src/include/platform/PlatformManager.h @@ -25,9 +25,12 @@ #include #include -#include #include +#if CHIP_SYSTEM_CONFIG_USE_LWIP +#include +#endif // CHIP_SYSTEM_CONFIG_USE_LWIP + namespace chip { namespace Dnssd { diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index a54e36baa6be1b..28f1eb8d9ad730 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -226,7 +226,7 @@ void GenericPlatformManagerImpl::_DispatchEvent(const ChipDeviceEvent break; case DeviceEventType::kChipLambdaEvent: - event->LambdaEvent(); + event->LambdaEvent.LambdaProxy(static_cast(event->LambdaEvent.LambdaBody)); break; case DeviceEventType::kCallWorkFunct: diff --git a/src/lib/support/LambdaBridge.h b/src/lib/support/LambdaBridge.h deleted file mode 100644 index 32b0a17075fc80..00000000000000 --- a/src/lib/support/LambdaBridge.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -#pragma once - -#include - -#include - -namespace chip { - -class LambdaBridge -{ -public: - // Use initialize instead of constructor because this class has to be trivial - template - void Initialize(const Lambda & lambda) - { - // memcpy is used to move the lambda into the event queue, so it must be trivially copyable - static_assert(std::is_trivially_copyable::value, "lambda must be trivially copyable"); - static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE, "lambda too large"); - static_assert(CHIP_CONFIG_LAMBDA_EVENT_ALIGN % alignof(Lambda) == 0, "lambda align too large"); - - // Implicit cast a capture-less lambda into a raw function pointer. - mLambdaProxy = [](const std::aligned_storage & body) { - (*reinterpret_cast(&body))(); - }; - memcpy(&mLambdaBody, &lambda, sizeof(Lambda)); - } - - void operator()() const { mLambdaProxy(mLambdaBody); } - -private: - void (*mLambdaProxy)(const std::aligned_storage & body); - std::aligned_storage mLambdaBody; -}; - -static_assert(std::is_trivial::value, "LambdaBridge is not trivial"); - -} // namespace chip diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 7870c9127e3b8c..c18a3da9d193cb 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -285,8 +285,8 @@ if (chip_device_platform != "none") { "GeneralUtils.cpp", "Globals.cpp", "LockTracker.cpp", + "LwIPEventSupport.cpp", "PersistedStorage.cpp", - "PlatformEventSupport.cpp", "TestIdentity.cpp", ] diff --git a/src/platform/PlatformEventSupport.cpp b/src/platform/LwIPEventSupport.cpp similarity index 96% rename from src/platform/PlatformEventSupport.cpp rename to src/platform/LwIPEventSupport.cpp index f7ed770bdf8f6f..0a4cead359ab50 100644 --- a/src/platform/PlatformEventSupport.cpp +++ b/src/platform/LwIPEventSupport.cpp @@ -34,11 +34,11 @@ namespace System { using namespace ::chip::DeviceLayer; -CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge) +CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, const LambdaBridge & bridge) { ChipDeviceEvent event; event.Type = DeviceEventType::kChipLambdaEvent; - event.LambdaEvent = std::move(bridge); + event.LambdaEvent = bridge; return PlatformMgr().PostEvent(&event); } diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index e4538f9a930142..83989935b6f7ef 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -131,7 +131,6 @@ static_library("system") { "SystemError.h", "SystemEvent.h", "SystemFaultInjection.h", - "SystemLayer.cpp", "SystemLayer.h", "SystemLayerImpl${chip_system_config_event_loop}.cpp", "SystemLayerImpl${chip_system_config_event_loop}.h", @@ -171,7 +170,7 @@ static_library("system") { } if (chip_system_config_use_lwip) { - sources += [ "PlatformEventSupport.h" ] + sources += [ "LwIPEventSupport.h" ] } if (chip_with_nlfaultinjection) { diff --git a/src/system/PlatformEventSupport.h b/src/system/LwIPEventSupport.h similarity index 97% rename from src/system/PlatformEventSupport.h rename to src/system/LwIPEventSupport.h index ee17332a04df4a..3679bec5a68a38 100644 --- a/src/system/PlatformEventSupport.h +++ b/src/system/LwIPEventSupport.h @@ -29,7 +29,7 @@ class Object; class PlatformEventing { public: - static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge); + static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, const 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.cpp b/src/system/SystemLayer.cpp deleted file mode 100644 index cb4330e194c5ec..00000000000000 --- a/src/system/SystemLayer.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * - * 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. - */ - -#include -#include -#include - -namespace chip { -namespace System { - -CHIP_ERROR Layer::ScheduleLambdaBridge(LambdaBridge && bridge) -{ - CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, std::move(bridge)); - if (lReturn != CHIP_NO_ERROR) - { - ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn)); - } - return lReturn; -} - -} // namespace System -} // namespace chip diff --git a/src/system/SystemLayer.h b/src/system/SystemLayer.h index b61acf22c6fe70..b731ec31fa5feb 100644 --- a/src/system/SystemLayer.h +++ b/src/system/SystemLayer.h @@ -25,8 +25,6 @@ #pragma once -#include - // Include configuration headers #include @@ -34,7 +32,6 @@ #include #include -#include #include #include #include @@ -53,6 +50,12 @@ namespace chip { namespace System { +struct LambdaBridge +{ + void (*LambdaProxy)(const void * context); + alignas(CHIP_CONFIG_LAMBDA_EVENT_ALIGN) char LambdaBody[CHIP_CONFIG_LAMBDA_EVENT_SIZE]; +}; + class Layer; using TimerCompleteCallback = void (*)(Layer * aLayer, void * appState); @@ -145,31 +148,6 @@ class DLL_EXPORT Layer */ virtual CHIP_ERROR ScheduleWork(TimerCompleteCallback aComplete, void * aAppState) = 0; - /** - * @brief - * Schedules a lambda even to be run as soon as possible in the CHIP context. This function is not thread-safe, - * it must be called with in the CHIP context - * - * @param[in] event A object encapsulate the context of a lambda - * - * @retval CHIP_NO_ERROR On success. - * @retval other Platform-specific errors generated indicating the reason for failure. - */ - CHIP_ERROR ScheduleLambdaBridge(LambdaBridge && event); - - /** - * @brief - * Schedules a lambda object to be run as soon as possible in the CHIP context. This function is not thread-safe, - * it must be called with in the CHIP context - */ - template - CHIP_ERROR ScheduleLambda(const Lambda & lambda) - { - LambdaBridge bridge; - bridge.Initialize(lambda); - return ScheduleLambdaBridge(std::move(bridge)); - } - private: // Copy and assignment NOT DEFINED Layer(const Layer &) = delete; @@ -224,6 +202,36 @@ class LayerLwIP : public Layer */ virtual CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) = 0; + /** + * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event + * queue. + * + * @param[in] event A object encapsulate the context of a lambda + * + * @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 ScheduleLambdaBridge(const LambdaBridge & event) = 0; + + template + CHIP_ERROR ScheduleLambda(const Lambda & lambda) + { + LambdaBridge event; + + // memcpy is used to move the lambda into the event queue, so it must be trivially copyable + static_assert(std::is_trivially_copyable::value); + static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE); + static_assert(alignof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_ALIGN); + + // Implicit cast a capture-less lambda into a raw function pointer. + event.LambdaProxy = [](const void * body) { (*static_cast(body))(); }; + memcpy(event.LambdaBody, &lambda, sizeof(Lambda)); + + return ScheduleLambdaBridge(event); + } + protected: // Provide access to private members of EventHandlerDelegate. struct LwIPEventHandlerDelegate : public EventHandlerDelegate diff --git a/src/system/SystemLayerImplLwIP.cpp b/src/system/SystemLayerImplLwIP.cpp index 5117407cb6ca84..67b8c77313458d 100644 --- a/src/system/SystemLayerImplLwIP.cpp +++ b/src/system/SystemLayerImplLwIP.cpp @@ -22,7 +22,7 @@ */ #include -#include +#include #include #include #include @@ -122,6 +122,18 @@ CHIP_ERROR LayerImplLwIP::AddEventHandlerDelegate(EventHandlerDelegate & aDelega return CHIP_NO_ERROR; } +CHIP_ERROR LayerImplLwIP::ScheduleLambdaBridge(const LambdaBridge & bridge) +{ + VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE); + + CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, bridge); + if (lReturn != CHIP_NO_ERROR) + { + ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn)); + } + return lReturn; +} + CHIP_ERROR LayerImplLwIP::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) { VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE); diff --git a/src/system/SystemLayerImplLwIP.h b/src/system/SystemLayerImplLwIP.h index 867f198c0119e9..4ff2686d4e597e 100644 --- a/src/system/SystemLayerImplLwIP.h +++ b/src/system/SystemLayerImplLwIP.h @@ -44,6 +44,7 @@ class LayerImplLwIP : public LayerLwIP // LayerLwIP overrides. CHIP_ERROR AddEventHandlerDelegate(EventHandlerDelegate & aDelegate); + CHIP_ERROR ScheduleLambdaBridge(const LambdaBridge & bridge) override; CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument); public: