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 <inet/ZephyrSocket.h> // nogncheck
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 : #endif // CHIP_SYSTEM_CONFIG_USE_LIBEV
43 :
44 : #include <lib/support/ObjectLifeCycle.h>
45 : #include <system/SystemLayer.h>
46 : #include <system/SystemTimer.h>
47 : #include <system/WakeEvent.h>
48 :
49 : namespace chip {
50 : namespace System {
51 :
52 : class LayerImplSelect : public LayerSocketsLoop
53 : {
54 : public:
55 : LayerImplSelect() = default;
56 0 : ~LayerImplSelect() override { VerifyOrDie(mLayerState.Destroy()); }
57 :
58 : // Layer overrides.
59 : CHIP_ERROR Init() override;
60 : void Shutdown() override;
61 174 : bool IsInitialized() const override { return mLayerState.IsInitialized(); }
62 : CHIP_ERROR StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
63 : CHIP_ERROR ExtendTimerTo(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState) override;
64 : bool IsTimerActive(TimerCompleteCallback onComplete, void * appState) override;
65 : Clock::Timeout GetRemainingTime(TimerCompleteCallback onComplete, void * appState) override;
66 : void CancelTimer(TimerCompleteCallback onComplete, void * appState) override;
67 : CHIP_ERROR ScheduleWork(TimerCompleteCallback onComplete, void * appState) override;
68 :
69 : // LayerSocket overrides.
70 : CHIP_ERROR StartWatchingSocket(int fd, SocketWatchToken * tokenOut) override;
71 : CHIP_ERROR SetCallback(SocketWatchToken token, SocketWatchCallback callback, intptr_t data) override;
72 : CHIP_ERROR RequestCallbackOnPendingRead(SocketWatchToken token) override;
73 : CHIP_ERROR RequestCallbackOnPendingWrite(SocketWatchToken token) override;
74 : CHIP_ERROR ClearCallbackOnPendingRead(SocketWatchToken token) override;
75 : CHIP_ERROR ClearCallbackOnPendingWrite(SocketWatchToken token) override;
76 : CHIP_ERROR StopWatchingSocket(SocketWatchToken * tokenInOut) override;
77 206 : SocketWatchToken InvalidSocketWatchToken() override { return reinterpret_cast<SocketWatchToken>(nullptr); }
78 :
79 : // LayerSocketLoop overrides.
80 : void Signal() override;
81 62 : void EventLoopBegins() override {}
82 : void PrepareEvents() override;
83 : void WaitForEvents() override;
84 : void HandleEvents() override;
85 62 : void EventLoopEnds() override {}
86 :
87 : void AddLoopHandler(EventLoopHandler & handler) override;
88 : void RemoveLoopHandler(EventLoopHandler & handler) override;
89 :
90 : #if CHIP_SYSTEM_CONFIG_USE_LIBEV
91 : virtual void SetLibEvLoop(struct ev_loop * aLibEvLoopP) override { mLibEvLoopP = aLibEvLoopP; };
92 : virtual struct ev_loop * GetLibEvLoop() override { return mLibEvLoopP; };
93 : static void HandleLibEvTimer(EV_P_ struct ev_timer * t, int revents);
94 : static void HandleLibEvIoWatcher(EV_P_ struct ev_io * i, int revents);
95 : #endif // CHIP_SYSTEM_CONFIG_USE_LIBEV
96 :
97 : // Expose the result of WaitForEvents() for non-blocking socket implementations.
98 21842105 : bool IsSelectResultValid() const { return mSelectResult >= 0; }
99 :
100 : protected:
101 : static SocketEvents SocketEventsFromFDs(int socket, const fd_set & readfds, const fd_set & writefds, const fd_set & exceptfds);
102 :
103 : static constexpr int kSocketWatchMax = (INET_CONFIG_ENABLE_TCP_ENDPOINT ? INET_CONFIG_NUM_TCP_ENDPOINTS : 0) +
104 : (INET_CONFIG_ENABLE_UDP_ENDPOINT ? INET_CONFIG_NUM_UDP_ENDPOINTS : 0);
105 :
106 : struct SocketWatch
107 : {
108 : void Clear();
109 : int mFD;
110 : SocketEvents mPendingIO;
111 : SocketWatchCallback mCallback;
112 : #if CHIP_SYSTEM_CONFIG_USE_LIBEV
113 : struct ev_io mIoWatcher;
114 : LayerImplSelect * mLayerImplSelectP;
115 : void DisableAndClear();
116 : #endif
117 :
118 : intptr_t mCallbackData;
119 : };
120 : SocketWatch mSocketWatchPool[kSocketWatchMax];
121 :
122 : TimerPool<TimerList::Node> mTimerPool;
123 : TimerList mTimerList;
124 : // List of expired timers being processed right now. Stored in a member so
125 : // we can cancel them.
126 : TimerList mExpiredTimers;
127 : timeval mNextTimeout;
128 :
129 : IntrusiveList<EventLoopHandler> mLoopHandlers;
130 :
131 : // Members for select loop
132 : struct SelectSets
133 : {
134 : fd_set mReadSet;
135 : fd_set mWriteSet;
136 : fd_set mErrorSet;
137 : };
138 : SelectSets mSelected;
139 : int mMaxFd;
140 :
141 : // Return value from select(), carried between WaitForEvents() and HandleEvents().
142 : int mSelectResult;
143 :
144 : ObjectLifeCycle mLayerState;
145 : #if !CHIP_SYSTEM_CONFIG_USE_LIBEV
146 : WakeEvent mWakeEvent;
147 : #endif
148 :
149 : #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
150 : std::atomic<pthread_t> mHandleSelectThread;
151 : #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
152 :
153 : #if CHIP_SYSTEM_CONFIG_USE_LIBEV
154 : struct ev_loop * mLibEvLoopP;
155 : #endif
156 : };
157 :
158 : using LayerImpl = LayerImplSelect;
159 :
160 : } // namespace System
161 : } // namespace chip
|