Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 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 select().
21 : */
22 :
23 : #pragma once
24 :
25 : #include "system/SystemConfig.h"
26 :
27 : #if CHIP_SYSTEM_CONFIG_USE_POSIX_SOCKETS
28 : #include <sys/select.h>
29 : #endif
30 :
31 : #if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_SOCKETS
32 : #include <zephyr/net/socket.h>
33 : #endif
34 :
35 : #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
36 : #include <atomic>
37 : #include <pthread.h>
38 : #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
39 :
40 : #if CHIP_SYSTEM_CONFIG_USE_LIBEV
41 : #include <ev.h>
42 : #if CHIP_SYSTEM_CONFIG_USE_DISPATCH
43 : #error "CHIP_SYSTEM_CONFIG_USE_LIBEV and CHIP_SYSTEM_CONFIG_USE_DISPATCH are mutually exclusive"
44 : #endif
45 : #endif // CHIP_SYSTEM_CONFIG_USE_LIBEV
46 :
47 : #include <lib/support/ObjectLifeCycle.h>
48 : #include <system/SystemLayer.h>
49 : #include <system/SystemTimer.h>
50 : #include <system/WakeEvent.h>
51 :
52 : namespace chip {
53 : namespace System {
54 :
55 : class LayerImplSelect : public LayerSocketsLoop
56 : {
57 : public:
58 : LayerImplSelect() = default;
59 0 : ~LayerImplSelect() override { VerifyOrDie(mLayerState.Destroy()); }
60 :
61 : // Layer overrides.
62 : CHIP_ERROR Init() override;
63 : void Shutdown() override;
64 172 : bool IsInitialized() const override { return mLayerState.IsInitialized(); }
65 : CHIP_ERROR StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
66 : CHIP_ERROR ExtendTimerTo(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
67 : bool IsTimerActive(TimerCompleteCallback onComplete, void * appState) override;
68 : Clock::Timeout GetRemainingTime(TimerCompleteCallback onComplete, void * appState) override;
69 : void CancelTimer(TimerCompleteCallback onComplete, void * appState) override;
70 : CHIP_ERROR ScheduleWork(TimerCompleteCallback onComplete, void * appState) override;
71 :
72 : // LayerSocket overrides.
73 : CHIP_ERROR StartWatchingSocket(int fd, SocketWatchToken * tokenOut) override;
74 : CHIP_ERROR SetCallback(SocketWatchToken token, SocketWatchCallback callback, intptr_t data) override;
75 : CHIP_ERROR RequestCallbackOnPendingRead(SocketWatchToken token) override;
76 : CHIP_ERROR RequestCallbackOnPendingWrite(SocketWatchToken token) override;
77 : CHIP_ERROR ClearCallbackOnPendingRead(SocketWatchToken token) override;
78 : CHIP_ERROR ClearCallbackOnPendingWrite(SocketWatchToken token) override;
79 : CHIP_ERROR StopWatchingSocket(SocketWatchToken * tokenInOut) override;
80 199 : SocketWatchToken InvalidSocketWatchToken() override { return reinterpret_cast<SocketWatchToken>(nullptr); }
81 :
82 : // LayerSocketLoop overrides.
83 : void Signal() override;
84 61 : void EventLoopBegins() override {}
85 : void PrepareEvents() override;
86 : void WaitForEvents() override;
87 : void HandleEvents() override;
88 61 : void EventLoopEnds() override {}
89 :
90 : #if !CHIP_SYSTEM_CONFIG_USE_DISPATCH
91 : void AddLoopHandler(EventLoopHandler & handler) override;
92 : void RemoveLoopHandler(EventLoopHandler & handler) override;
93 : #endif // !CHIP_SYSTEM_CONFIG_USE_DISPATCH
94 :
95 : #if CHIP_SYSTEM_CONFIG_USE_DISPATCH
96 : void SetDispatchQueue(dispatch_queue_t dispatchQueue) override { mDispatchQueue = dispatchQueue; };
97 : dispatch_queue_t GetDispatchQueue() override { return mDispatchQueue; };
98 : void HandleTimerComplete(TimerList::Node * timer);
99 : #elif CHIP_SYSTEM_CONFIG_USE_LIBEV
100 : virtual void SetLibEvLoop(struct ev_loop * aLibEvLoopP) override { mLibEvLoopP = aLibEvLoopP; };
101 : virtual struct ev_loop * GetLibEvLoop() override { return mLibEvLoopP; };
102 : static void HandleLibEvTimer(EV_P_ struct ev_timer * t, int revents);
103 : static void HandleLibEvIoWatcher(EV_P_ struct ev_io * i, int revents);
104 : #endif // CHIP_SYSTEM_CONFIG_USE_DISPATCH/LIBEV
105 :
106 : // Expose the result of WaitForEvents() for non-blocking socket implementations.
107 6601584 : bool IsSelectResultValid() const { return mSelectResult >= 0; }
108 :
109 : protected:
110 : static SocketEvents SocketEventsFromFDs(int socket, const fd_set & readfds, const fd_set & writefds, const fd_set & exceptfds);
111 :
112 : static constexpr int kSocketWatchMax = (INET_CONFIG_ENABLE_TCP_ENDPOINT ? INET_CONFIG_NUM_TCP_ENDPOINTS : 0) +
113 : (INET_CONFIG_ENABLE_UDP_ENDPOINT ? INET_CONFIG_NUM_UDP_ENDPOINTS : 0);
114 :
115 : struct SocketWatch
116 : {
117 : void Clear();
118 : int mFD;
119 : SocketEvents mPendingIO;
120 : SocketWatchCallback mCallback;
121 : #if CHIP_SYSTEM_CONFIG_USE_DISPATCH
122 : dispatch_source_t mRdSource;
123 : dispatch_source_t mWrSource;
124 : void DisableAndClear();
125 : #endif
126 : #if CHIP_SYSTEM_CONFIG_USE_LIBEV
127 : struct ev_io mIoWatcher;
128 : LayerImplSelect * mLayerImplSelectP;
129 : void DisableAndClear();
130 : #endif
131 :
132 : intptr_t mCallbackData;
133 : };
134 : SocketWatch mSocketWatchPool[kSocketWatchMax];
135 :
136 : TimerPool<TimerList::Node> mTimerPool;
137 : TimerList mTimerList;
138 : // List of expired timers being processed right now. Stored in a member so
139 : // we can cancel them.
140 : TimerList mExpiredTimers;
141 : timeval mNextTimeout;
142 :
143 : #if !CHIP_SYSTEM_CONFIG_USE_DISPATCH
144 : IntrusiveList<EventLoopHandler> mLoopHandlers;
145 : #endif
146 :
147 : // Members for select loop
148 : struct SelectSets
149 : {
150 : fd_set mReadSet;
151 : fd_set mWriteSet;
152 : fd_set mErrorSet;
153 : };
154 : SelectSets mSelected;
155 : int mMaxFd;
156 :
157 : // Return value from select(), carried between WaitForEvents() and HandleEvents().
158 : int mSelectResult;
159 :
160 : ObjectLifeCycle mLayerState;
161 : #if !CHIP_SYSTEM_CONFIG_USE_LIBEV && !CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
162 : WakeEvent mWakeEvent;
163 : #endif
164 :
165 : #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
166 : std::atomic<pthread_t> mHandleSelectThread;
167 : #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
168 :
169 : #if CHIP_SYSTEM_CONFIG_USE_DISPATCH
170 : dispatch_queue_t mDispatchQueue = nullptr;
171 : #elif CHIP_SYSTEM_CONFIG_USE_LIBEV
172 : struct ev_loop * mLibEvLoopP;
173 : #endif
174 : };
175 :
176 : using LayerImpl = LayerImplSelect;
177 :
178 : } // namespace System
179 : } // namespace chip
|