Skip to content

Commit 1188351

Browse files
kghostpull[bot]
authored andcommitted
Pull up LayerLwIP::ScheduleLambda to SystemLayer (#11187)
1 parent bd30c9e commit 1188351

12 files changed

+127
-65
lines changed

src/include/platform/CHIPDeviceEvent.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,7 @@ typedef void (*AsyncWorkFunct)(intptr_t arg);
307307

308308
#include <ble/BleConfig.h>
309309
#include <inet/InetLayer.h>
310-
#include <system/SystemEvent.h>
311-
#include <system/SystemLayer.h>
312-
#include <system/SystemObject.h>
313-
#include <system/SystemPacketBuffer.h>
310+
#include <lib/support/LambdaBridge.h>
314311

315312
namespace chip {
316313
namespace DeviceLayer {
@@ -325,7 +322,7 @@ struct ChipDeviceEvent final
325322
union
326323
{
327324
ChipDevicePlatformEvent Platform;
328-
System::LambdaBridge LambdaEvent;
325+
LambdaBridge LambdaEvent;
329326
struct
330327
{
331328
::chip::System::EventType Type;

src/include/platform/PlatformManager.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,9 @@
2525

2626
#include <platform/CHIPDeviceBuildConfig.h>
2727
#include <platform/CHIPDeviceEvent.h>
28+
#include <system/PlatformEventSupport.h>
2829
#include <system/SystemLayer.h>
2930

30-
#if CHIP_SYSTEM_CONFIG_USE_LWIP
31-
#include <system/LwIPEventSupport.h>
32-
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
33-
3431
namespace chip {
3532

3633
namespace Dnssd {

src/include/platform/internal/GenericPlatformManagerImpl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ void GenericPlatformManagerImpl<ImplClass>::_DispatchEvent(const ChipDeviceEvent
233233
break;
234234

235235
case DeviceEventType::kChipLambdaEvent:
236-
event->LambdaEvent.LambdaProxy(static_cast<const void *>(event->LambdaEvent.LambdaBody));
236+
event->LambdaEvent();
237237
break;
238238

239239
case DeviceEventType::kCallWorkFunct:

src/lib/support/LambdaBridge.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2021 Project CHIP Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <string.h>
20+
21+
#include <lib/core/CHIPConfig.h>
22+
23+
namespace chip {
24+
25+
class LambdaBridge
26+
{
27+
public:
28+
// Use initialize instead of constructor because this class has to be trivial
29+
template <typename Lambda>
30+
void Initialize(const Lambda & lambda)
31+
{
32+
// memcpy is used to move the lambda into the event queue, so it must be trivially copyable
33+
static_assert(std::is_trivially_copyable<Lambda>::value, "lambda must be trivially copyable");
34+
static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE, "lambda too large");
35+
static_assert(CHIP_CONFIG_LAMBDA_EVENT_ALIGN % alignof(Lambda) == 0, "lambda align too large");
36+
37+
// Implicit cast a capture-less lambda into a raw function pointer.
38+
mLambdaProxy = [](const std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> & body) {
39+
(*reinterpret_cast<const Lambda *>(&body))();
40+
};
41+
memcpy(&mLambdaBody, &lambda, sizeof(Lambda));
42+
}
43+
44+
void operator()() const { mLambdaProxy(mLambdaBody); }
45+
46+
private:
47+
void (*mLambdaProxy)(const std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> & body);
48+
std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> mLambdaBody;
49+
};
50+
51+
static_assert(std::is_trivial<LambdaBridge>::value, "LambdaBridge is not trivial");
52+
53+
} // namespace chip

src/platform/BUILD.gn

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ if (chip_device_platform != "none") {
285285
"GeneralUtils.cpp",
286286
"Globals.cpp",
287287
"LockTracker.cpp",
288-
"LwIPEventSupport.cpp",
289288
"PersistedStorage.cpp",
289+
"PlatformEventSupport.cpp",
290290
"TestIdentity.cpp",
291291
]
292292

src/platform/LwIPEventSupport.cpp renamed to src/platform/PlatformEventSupport.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ namespace System {
3434

3535
using namespace ::chip::DeviceLayer;
3636

37-
CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, const LambdaBridge & bridge)
37+
CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge)
3838
{
3939
ChipDeviceEvent event;
4040
event.Type = DeviceEventType::kChipLambdaEvent;
41-
event.LambdaEvent = bridge;
41+
event.LambdaEvent = std::move(bridge);
4242

4343
return PlatformMgr().PostEvent(&event);
4444
}

src/system/BUILD.gn

+2-1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static_library("system") {
131131
"SystemError.h",
132132
"SystemEvent.h",
133133
"SystemFaultInjection.h",
134+
"SystemLayer.cpp",
134135
"SystemLayer.h",
135136
"SystemLayerImpl${chip_system_config_event_loop}.cpp",
136137
"SystemLayerImpl${chip_system_config_event_loop}.h",
@@ -170,7 +171,7 @@ static_library("system") {
170171
}
171172

172173
if (chip_system_config_use_lwip) {
173-
sources += [ "LwIPEventSupport.h" ]
174+
sources += [ "PlatformEventSupport.h" ]
174175
}
175176

176177
if (chip_with_nlfaultinjection) {

src/system/LwIPEventSupport.h renamed to src/system/PlatformEventSupport.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Object;
2929
class PlatformEventing
3030
{
3131
public:
32-
static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, const LambdaBridge & bridge);
32+
static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge);
3333
static CHIP_ERROR PostEvent(System::Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument);
3434
static CHIP_ERROR StartTimer(System::Layer & aLayer, System::Clock::Timeout aTimeout);
3535
};

src/system/SystemLayer.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2021 Project CHIP Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <lib/support/CodeUtils.h>
18+
#include <system/PlatformEventSupport.h>
19+
#include <system/SystemLayer.h>
20+
21+
namespace chip {
22+
namespace System {
23+
24+
CHIP_ERROR Layer::ScheduleLambdaBridge(LambdaBridge && bridge)
25+
{
26+
CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, std::move(bridge));
27+
if (lReturn != CHIP_NO_ERROR)
28+
{
29+
ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn));
30+
}
31+
return lReturn;
32+
}
33+
34+
} // namespace System
35+
} // namespace chip

src/system/SystemLayer.h

+28-36
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@
2525

2626
#pragma once
2727

28+
#include <type_traits>
29+
2830
// Include configuration headers
2931
#include <system/SystemConfig.h>
3032

3133
#include <lib/core/CHIPCallback.h>
3234

3335
#include <lib/support/CodeUtils.h>
3436
#include <lib/support/DLLUtil.h>
37+
#include <lib/support/LambdaBridge.h>
3538
#include <lib/support/ObjectLifeCycle.h>
3639
#include <system/SystemClock.h>
3740
#include <system/SystemError.h>
@@ -50,12 +53,6 @@
5053
namespace chip {
5154
namespace System {
5255

53-
struct LambdaBridge
54-
{
55-
void (*LambdaProxy)(const void * context);
56-
alignas(CHIP_CONFIG_LAMBDA_EVENT_ALIGN) char LambdaBody[CHIP_CONFIG_LAMBDA_EVENT_SIZE];
57-
};
58-
5956
class Layer;
6057
using TimerCompleteCallback = void (*)(Layer * aLayer, void * appState);
6158

@@ -148,6 +145,31 @@ class DLL_EXPORT Layer
148145
*/
149146
virtual CHIP_ERROR ScheduleWork(TimerCompleteCallback aComplete, void * aAppState) = 0;
150147

148+
/**
149+
* @brief
150+
* Schedules a lambda even to be run as soon as possible in the CHIP context. This function is not thread-safe,
151+
* it must be called with in the CHIP context
152+
*
153+
* @param[in] event A object encapsulate the context of a lambda
154+
*
155+
* @retval CHIP_NO_ERROR On success.
156+
* @retval other Platform-specific errors generated indicating the reason for failure.
157+
*/
158+
CHIP_ERROR ScheduleLambdaBridge(LambdaBridge && event);
159+
160+
/**
161+
* @brief
162+
* Schedules a lambda object to be run as soon as possible in the CHIP context. This function is not thread-safe,
163+
* it must be called with in the CHIP context
164+
*/
165+
template <typename Lambda>
166+
CHIP_ERROR ScheduleLambda(const Lambda & lambda)
167+
{
168+
LambdaBridge bridge;
169+
bridge.Initialize(lambda);
170+
return ScheduleLambdaBridge(std::move(bridge));
171+
}
172+
151173
private:
152174
// Copy and assignment NOT DEFINED
153175
Layer(const Layer &) = delete;
@@ -202,36 +224,6 @@ class LayerLwIP : public Layer
202224
*/
203225
virtual CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) = 0;
204226

205-
/**
206-
* This posts an event / message of the specified type with the provided argument to this instance's platform-specific event
207-
* queue.
208-
*
209-
* @param[in] event A object encapsulate the context of a lambda
210-
*
211-
* @retval CHIP_NO_ERROR On success.
212-
* @retval CHIP_ERROR_INCORRECT_STATE If the state of the Layer object is incorrect.
213-
* @retval CHIP_ERROR_NO_MEMORY If the event queue is already full.
214-
* @retval other Platform-specific errors generated indicating the reason for failure.
215-
*/
216-
virtual CHIP_ERROR ScheduleLambdaBridge(const LambdaBridge & event) = 0;
217-
218-
template <typename Lambda>
219-
CHIP_ERROR ScheduleLambda(const Lambda & lambda)
220-
{
221-
LambdaBridge event;
222-
223-
// memcpy is used to move the lambda into the event queue, so it must be trivially copyable
224-
static_assert(std::is_trivially_copyable<Lambda>::value);
225-
static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE);
226-
static_assert(alignof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_ALIGN);
227-
228-
// Implicit cast a capture-less lambda into a raw function pointer.
229-
event.LambdaProxy = [](const void * body) { (*static_cast<const Lambda *>(body))(); };
230-
memcpy(event.LambdaBody, &lambda, sizeof(Lambda));
231-
232-
return ScheduleLambdaBridge(event);
233-
}
234-
235227
protected:
236228
// Provide access to private members of EventHandlerDelegate.
237229
struct LwIPEventHandlerDelegate : public EventHandlerDelegate

src/system/SystemLayerImplLwIP.cpp

+1-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*/
2323

2424
#include <lib/support/CodeUtils.h>
25-
#include <system/LwIPEventSupport.h>
25+
#include <system/PlatformEventSupport.h>
2626
#include <system/SystemFaultInjection.h>
2727
#include <system/SystemLayer.h>
2828
#include <system/SystemLayerImplLwIP.h>
@@ -122,18 +122,6 @@ CHIP_ERROR LayerImplLwIP::AddEventHandlerDelegate(EventHandlerDelegate & aDelega
122122
return CHIP_NO_ERROR;
123123
}
124124

125-
CHIP_ERROR LayerImplLwIP::ScheduleLambdaBridge(const LambdaBridge & bridge)
126-
{
127-
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
128-
129-
CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, bridge);
130-
if (lReturn != CHIP_NO_ERROR)
131-
{
132-
ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn));
133-
}
134-
return lReturn;
135-
}
136-
137125
CHIP_ERROR LayerImplLwIP::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
138126
{
139127
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

src/system/SystemLayerImplLwIP.h

-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class LayerImplLwIP : public LayerLwIP
4444

4545
// LayerLwIP overrides.
4646
CHIP_ERROR AddEventHandlerDelegate(EventHandlerDelegate & aDelegate);
47-
CHIP_ERROR ScheduleLambdaBridge(const LambdaBridge & bridge) override;
4847
CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
4948

5049
public:

0 commit comments

Comments
 (0)