Skip to content

Commit 49e6546

Browse files
committed
[Darwin][Network.framework] Add src/platform/Darwin/system/SystemLayerImplDispatch.mm such that the unit tests runs using the dispatch mechanism instead of the socket based implementation
1 parent 4cb3032 commit 49e6546

16 files changed

+849
-238
lines changed

.github/workflows/lint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ jobs:
126126
--known-failure platform/DeviceSafeQueue.h \
127127
--known-failure platform/GLibTypeDeleter.h \
128128
--known-failure platform/SingletonConfigurationManager.cpp \
129+
--known-failure system/SystemLayerImplDispatch.h \
129130
"
130131
# These ARE actually orphaned but due to dynamic-server we have code paths
131132
# for them. Keeping them as a list as they still need review ...

src/inet/tests/TestInetCommonPosix.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,16 +358,22 @@ void ServiceEvents(uint32_t aSleepTimeMilliseconds)
358358
}
359359
}
360360

361+
#if !CHIP_SYSTEM_CONFIG_USE_DISPATCH
361362
// Start a timer (with a no-op callback) to ensure that WaitForEvents() does not block longer than aSleepTimeMilliseconds.
362363
gSystemLayer.StartTimer(
363364
System::Clock::Milliseconds32(aSleepTimeMilliseconds), [](System::Layer *, void *) -> void {}, nullptr);
365+
#endif
364366

365-
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
367+
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && !CHIP_SYSTEM_CONFIG_USE_DISPATCH
366368
gSystemLayer.PrepareEvents();
367369
gSystemLayer.WaitForEvents();
368370
gSystemLayer.HandleEvents();
369371
#endif
370372

373+
#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
374+
gSystemLayer.HandleDispatchQueueEvents(System::Clock::Milliseconds32(aSleepTimeMilliseconds));
375+
#endif
376+
371377
#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
372378
if (gSystemLayer.IsInitialized())
373379
{

src/platform/Darwin/BUILD.gn

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import("//build_overrides/chip.gni")
1616
import("//build_overrides/nlassert.gni")
1717

1818
import("${chip_root}/src/platform/device.gni")
19+
import("${chip_root}/src/system/system.gni")
1920

2021
assert(chip_device_platform == "darwin")
2122

@@ -79,8 +80,14 @@ static_library("Darwin") {
7980
"UserDefaults.mm",
8081
"inet/InterfacesMonitor.h",
8182
"inet/InterfacesMonitor.mm",
83+
"system/SystemLayerImplDispatch.h",
84+
"system/SystemLayerImplDispatch.mm",
8285
]
8386

87+
if (chip_system_config_use_sockets) {
88+
sources += [ "system/SystemLayerImplDispatchSockets.mm" ]
89+
}
90+
8491
if (chip_enable_wifi) {
8592
sources += [
8693
"WiFi/ConfigurationManagerImplWiFi.cpp",

src/platform/Darwin/PlatformManagerImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack()
7070

7171
#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
7272
// Ensure there is a dispatch queue available
73-
static_cast<System::LayerSocketsLoop &>(DeviceLayer::SystemLayer()).SetDispatchQueue(GetWorkQueue());
73+
static_cast<System::LayerDispatch &>(DeviceLayer::SystemLayer()).SetDispatchQueue(GetWorkQueue());
7474
#endif
7575

7676
// Call _InitChipStack() on the generic implementation base class
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
*
3+
* Copyright (c) 2025 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* @file
20+
* This file declares an implementation of System::Layer using dispatch.
21+
*/
22+
23+
#pragma once
24+
25+
#include "system/SystemConfig.h"
26+
27+
#include <lib/support/ObjectLifeCycle.h>
28+
#include <system/SystemLayer.h>
29+
#include <system/SystemTimer.h>
30+
31+
namespace chip {
32+
namespace System {
33+
34+
class LayerImplDispatch : public LayerDispatch
35+
{
36+
public:
37+
LayerImplDispatch() = default;
38+
~LayerImplDispatch() override { VerifyOrDie(mLayerState.Destroy()); }
39+
40+
// Layer overrides.
41+
CHIP_ERROR Init() override;
42+
void Shutdown() override;
43+
bool IsInitialized() const override { return mLayerState.IsInitialized(); }
44+
CHIP_ERROR StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
45+
CHIP_ERROR ExtendTimerTo(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
46+
bool IsTimerActive(TimerCompleteCallback onComplete, void * appState) override;
47+
Clock::Timeout GetRemainingTime(TimerCompleteCallback onComplete, void * appState) override;
48+
void CancelTimer(TimerCompleteCallback onComplete, void * appState) override;
49+
CHIP_ERROR ScheduleWork(TimerCompleteCallback onComplete, void * appState) override;
50+
51+
// LayerDispatch overrides.
52+
void SetDispatchQueue(dispatch_queue_t dispatchQueue) override { mDispatchQueue = dispatchQueue; };
53+
dispatch_queue_t GetDispatchQueue() override { return mDispatchQueue; };
54+
void HandleDispatchQueueEvents(Clock::Timeout timeout) override;
55+
CHIP_ERROR ScheduleWorkWithBlock(dispatch_block_t block) override;
56+
57+
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
58+
// LayerSocket overrides.
59+
CHIP_ERROR StartWatchingSocket(int fd, SocketWatchToken * tokenOut) override;
60+
CHIP_ERROR SetCallback(SocketWatchToken token, SocketWatchCallback callback, intptr_t data) override;
61+
CHIP_ERROR RequestCallbackOnPendingRead(SocketWatchToken token) override;
62+
CHIP_ERROR RequestCallbackOnPendingWrite(SocketWatchToken token) override;
63+
CHIP_ERROR ClearCallbackOnPendingRead(SocketWatchToken token) override;
64+
CHIP_ERROR ClearCallbackOnPendingWrite(SocketWatchToken token) override;
65+
CHIP_ERROR StopWatchingSocket(SocketWatchToken * tokenInOut) override;
66+
SocketWatchToken InvalidSocketWatchToken() override { return reinterpret_cast<SocketWatchToken>(nullptr); }
67+
#endif
68+
69+
protected:
70+
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
71+
struct SelectSets
72+
{
73+
fd_set mReadSet;
74+
fd_set mWriteSet;
75+
fd_set mErrorSet;
76+
};
77+
78+
struct SocketWatch
79+
{
80+
int mFD;
81+
SocketEvents mPendingIO;
82+
SocketWatchCallback mCallback;
83+
intptr_t mCallbackData;
84+
85+
dispatch_source_t mRdSource = nullptr;
86+
dispatch_source_t mWrSource = nullptr;
87+
88+
bool IsActive() const { return mFD != kInvalidFd; }
89+
void PrepareEvents(SelectSets & sets, int & maxFd) const;
90+
void HandleEvents(const SelectSets & sets) const;
91+
void Clear();
92+
};
93+
94+
class SocketWatchPool
95+
{
96+
public:
97+
CHIP_ERROR Allocate(int fd, SocketWatch *& outWatch);
98+
CHIP_ERROR Release(SocketWatch * watch);
99+
void Clear();
100+
101+
bool PrepareEvents(SelectSets & sets, timeval timeout) const;
102+
void HandleEvents(const SelectSets & sets) const;
103+
104+
private:
105+
static constexpr int kSocketWatchMax = (INET_CONFIG_ENABLE_TCP_ENDPOINT ? INET_CONFIG_NUM_TCP_ENDPOINTS : 0) +
106+
(INET_CONFIG_ENABLE_UDP_ENDPOINT ? INET_CONFIG_NUM_UDP_ENDPOINTS : 0);
107+
SocketWatch mPool[kSocketWatchMax];
108+
};
109+
110+
SocketWatchPool mSocketWatchPool;
111+
void HandleSocketsAndTimerEvents(Clock::Timeout timeout);
112+
CHIP_ERROR RequestCallback(SocketWatchToken token, SocketEventFlags flag);
113+
CHIP_ERROR ClearCallback(SocketWatchToken token, SocketEventFlags flag);
114+
#endif
115+
116+
TimerPool<TimerList::Node> mTimerPool;
117+
TimerList mTimerList;
118+
// List of expired timers being processed right now. Stored in a member so
119+
// we can cancel them.
120+
TimerList mExpiredTimers;
121+
void EnableTimer(const char * source, TimerList::Node *);
122+
void DisableTimer(const char * source, TimerList::Node *);
123+
CHIP_ERROR StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState, bool shouldCancel);
124+
void HandleTimerEvents(Clock::Timeout timeout);
125+
126+
ObjectLifeCycle mLayerState;
127+
128+
dispatch_queue_t mDispatchQueue = nullptr;
129+
};
130+
131+
using LayerImpl = LayerImplDispatch;
132+
133+
} // namespace System
134+
} // namespace chip

0 commit comments

Comments
 (0)