Skip to content

Commit 7f94440

Browse files
Add the ability for EventLoopHandlers to participate in the event loop
1 parent 8ba371a commit 7f94440

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

src/lib/support/IntrusiveList.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ enum class IntrusiveMode
8484
class IntrusiveListNodePrivateBase
8585
{
8686
public:
87-
IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {}
87+
constexpr IntrusiveListNodePrivateBase() : mPrev(nullptr), mNext(nullptr) {}
8888
~IntrusiveListNodePrivateBase() { VerifyOrDie(!IsInList()); }
8989

9090
// Note: The copy construct/assignment is not provided because the list node state is not copyable.
@@ -98,7 +98,7 @@ class IntrusiveListNodePrivateBase
9898

9999
private:
100100
friend class IntrusiveListBase;
101-
IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) :
101+
constexpr IntrusiveListNodePrivateBase(IntrusiveListNodePrivateBase * prev, IntrusiveListNodePrivateBase * next) :
102102
mPrev(prev), mNext(next)
103103
{}
104104

@@ -284,7 +284,7 @@ class IntrusiveListBase
284284
// ^ |
285285
// \------------------------------------------/
286286
//
287-
IntrusiveListBase() : mNode(&mNode, &mNode) {}
287+
constexpr IntrusiveListBase() : mNode(&mNode, &mNode) {}
288288
~IntrusiveListBase()
289289
{
290290
VerifyOrDie(Empty());
@@ -399,7 +399,7 @@ template <typename T, IntrusiveMode Mode = IntrusiveMode::Strict, typename Hook
399399
class IntrusiveList : public IntrusiveListBase
400400
{
401401
public:
402-
IntrusiveList() : IntrusiveListBase() {}
402+
constexpr IntrusiveList() : IntrusiveListBase() {}
403403

404404
IntrusiveList(IntrusiveList &&) = default;
405405
IntrusiveList & operator=(IntrusiveList &&) = default;

src/system/SystemLayer.h

+22
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <system/SystemEvent.h>
3939

4040
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
41+
#include <lib/support/IntrusiveList.h>
4142
#include <system/SocketEvents.h>
4243
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
4344

@@ -242,6 +243,7 @@ class LayerSockets : public Layer
242243
* Initialize watching for events on a file descriptor.
243244
*
244245
* Returns an opaque token through @a tokenOut that must be passed to subsequent operations for this file descriptor.
246+
* Multiple calls to start watching the same file descriptor will return the same token.
245247
* StopWatchingSocket() must be called before closing the file descriptor.
246248
*/
247249
virtual CHIP_ERROR StartWatchingSocket(int fd, SocketWatchToken * tokenOut) = 0;
@@ -287,6 +289,23 @@ class LayerSockets : public Layer
287289
virtual SocketWatchToken InvalidSocketWatchToken() = 0;
288290
};
289291

292+
class LayerSocketsLoop;
293+
294+
/**
295+
* Enables the participation of subordinate event loops in the SystemLayer event loop.
296+
*/
297+
class EventLoopHandler : public chip::IntrusiveListNodeBase<>
298+
{
299+
public:
300+
virtual ~EventLoopHandler() {}
301+
302+
/** Prepares events and returns the next requested wake time. */
303+
virtual Clock::Timestamp PrepareEvents(Clock::Timestamp now) { return Clock::Timestamp::max(); }
304+
305+
/** Handles / dispatches pending events. */
306+
virtual void HandleEvents() = 0;
307+
};
308+
290309
class LayerSocketsLoop : public LayerSockets
291310
{
292311
public:
@@ -297,6 +316,9 @@ class LayerSocketsLoop : public LayerSockets
297316
virtual void HandleEvents() = 0;
298317
virtual void EventLoopEnds() = 0;
299318

319+
virtual void AddLoopHandler(EventLoopHandler & handler) = 0;
320+
virtual void RemoveLoopHandler(EventLoopHandler & handler) = 0;
321+
300322
#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
301323
virtual void SetDispatchQueue(dispatch_queue_t dispatchQueue) = 0;
302324
virtual dispatch_queue_t GetDispatchQueue() = 0;

src/system/SystemLayerImplSelect.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,9 @@ CHIP_ERROR LayerImplSelect::StartWatchingSocket(int fd, SocketWatchToken * token
370370
{
371371
if (w.mFD == fd)
372372
{
373-
// Duplicate registration is an error.
374-
return CHIP_ERROR_INVALID_ARGUMENT;
373+
// Already registered, return the existing token
374+
*tokenOut = reinterpret_cast<SocketWatchToken>(&w);
375+
return CHIP_NO_ERROR;
375376
}
376377
if ((w.mFD == kInvalidFd) && (watch == nullptr))
377378
{
@@ -621,6 +622,15 @@ void LayerImplSelect::PrepareEvents()
621622
awakenTime = timer->AwakenTime();
622623
}
623624

625+
for (auto & loop : mLoopHandlers)
626+
{
627+
Clock::Timestamp requestedWakeTime = loop.PrepareEvents(currentTime);
628+
if (requestedWakeTime < awakenTime)
629+
{
630+
awakenTime = requestedWakeTime;
631+
}
632+
}
633+
624634
const Clock::Timestamp sleepTime = (awakenTime > currentTime) ? (awakenTime - currentTime) : Clock::kZero;
625635
Clock::ToTimeval(sleepTime, mNextTimeout);
626636

@@ -685,16 +695,21 @@ void LayerImplSelect::HandleEvents()
685695

686696
for (auto & w : mSocketWatchPool)
687697
{
688-
if (w.mFD != kInvalidFd)
698+
if (w.mFD != kInvalidFd && w.mCallback != nullptr)
689699
{
690700
SocketEvents events = SocketEventsFromFDs(w.mFD, mSelected.mReadSet, mSelected.mWriteSet, mSelected.mErrorSet);
691-
if (events.HasAny() && w.mCallback != nullptr)
701+
if (events.HasAny())
692702
{
693703
w.mCallback(events, w.mCallbackData);
694704
}
695705
}
696706
}
697707

708+
for (auto & loop : mLoopHandlers)
709+
{
710+
loop.HandleEvents();
711+
}
712+
698713
#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
699714
mHandleSelectThread = PTHREAD_NULL;
700715
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

src/system/SystemLayerImplSelect.h

+5
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ class LayerImplSelect : public LayerSocketsLoop
8787
void HandleEvents() override;
8888
void EventLoopEnds() override {}
8989

90+
void AddLoopHandler(EventLoopHandler & handler) override { mLoopHandlers.PushBack(&handler); }
91+
void RemoveLoopHandler(EventLoopHandler & handler) override { mLoopHandlers.Remove(&handler); }
92+
9093
#if CHIP_SYSTEM_CONFIG_USE_DISPATCH
9194
void SetDispatchQueue(dispatch_queue_t dispatchQueue) override { mDispatchQueue = dispatchQueue; };
9295
dispatch_queue_t GetDispatchQueue() override { return mDispatchQueue; };
@@ -135,6 +138,8 @@ class LayerImplSelect : public LayerSocketsLoop
135138
TimerList mExpiredTimers;
136139
timeval mNextTimeout;
137140

141+
IntrusiveList<EventLoopHandler> mLoopHandlers;
142+
138143
// Members for select loop
139144
struct SelectSets
140145
{

0 commit comments

Comments
 (0)