-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalize socket-based event loop #6561
Conversation
src/inet/TCPEndPoint.cpp
Outdated
|
||
#if CHIP_SYSTEM_CONFIG_USE_IO_THREAD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unclear from the current arrangement of the code whether CHIP_SYSTEM_CONFIG_USE_IO_THREAD == (CHIP_SYSTEM_CONFIG_USE_SOCKETS == 1) && (CHIP_SYSTEM_CONFIG_SOCKETS_USE_SELECT == 0) or if CHIP_SYSTEM_CONFIG_USE_IO_THREAD is completely independent of either of those.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a part that needs to be fleshed out. It's independent of the interface for file descriptor watching, but dependent on the implementation. Some may require a thread (as select does), some may require there not be one (e.g. using a CHIP-consuming application's mechanism instead), and some may go either way. Actual #if
tests should end up much reduced, since I can probably abstract WakeIOThread()
(previously WakeSelect()
) a bit more.
src/inet/TCPEndPoint.cpp
Outdated
@@ -2368,15 +2372,15 @@ void TCPEndPoint::HandlePendingIO() | |||
// ready to be received on the socket, process the incoming connection. | |||
if (State == kState_Listening) | |||
{ | |||
if (OnConnectionReceived != nullptr && mPendingIO.IsReadable()) | |||
if (OnConnectionReceived != nullptr && mPendingIO.Has(System::SocketEventFlag::kRead)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to not make IsReadable()
as a convenience inline for Has(System::SocketEventFlag::kRead)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pattern for most other flag sets in the code is not to have them, so I didn't re-add them when moving SocketEvents
to use the type-safe BitFlags
when I had to move it from inet to system. Easy enough to replace. (A bit sad that enum class can't have methods, not to mention a bitwise mixin.)
src/inet/TCPEndPoint.cpp
Outdated
HandleIncomingConnection(); | ||
} | ||
|
||
// If in the processes of initiating a connection... | ||
else if (State == kState_Connecting) | ||
{ | ||
// The socket being writable indicates the connection has completed (successfully or otherwise). | ||
if (mPendingIO.IsWriteable()) | ||
if (mPendingIO.Has(System::SocketEventFlag::kWrite)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to not make IsWriteable()
as a convenience inline for Has(System::SocketEventFlag::kWrite)
?
src/lib/support/SafeInt.h
Outdated
@@ -35,7 +35,7 @@ namespace chip { | |||
* in the range of valid values for T. | |||
*/ | |||
template <typename T, typename U> | |||
bool CanCastTo(U arg) | |||
constexpr bool CanCastTo(U arg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably worth factoring this out as a simple one-liner PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. (The reason I touched this actually no longer exists in this PR. Most uses of CanCastTo
are testing dynamically computer values, but I think there are a small number of tests that could be replaced with a static_assert
. CanCastTo
couldn't be constexpr
in C++11, but can be now in C++14.)
@@ -111,6 +111,14 @@ | |||
|
|||
// clang-format off | |||
|
|||
#ifndef CHIP_SYSTEM_CONFIG_USE_IO_THREAD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See prior comments about CHIP_SYSTEM_CONFIG_USE_IO_THREAD. There might be an opportunity to detect and flag incorrect configurations.
FD_SET(socket, writefds); | ||
if (IsError()) | ||
if (mRequestIO.Has(System::SocketEventFlag::kError)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See prior comments on convenience inlines.
Will check this out. With CHIP, one of my integration goals would be / is to make the CHIP stack an easy add-on as a CoreFoundation run loop source. I'll be looking at this through that integration lens. |
The PR seems reasonable; however, not having ever worked with Darwin libnetwork, I'm probably not the best person to assess that integration goal (but the code doesn't seem harmful toward that end at all and certainly seems to help). As for the CoreFoundation run loop, at minimum, such an integration would seem to require an import/export of sockets, which is likely no different / worse than integrating CoreFoundation run loops with a pure BSD sockets implementation, as opposed to CFNetwork sources. |
I had previously found that for the posix platform, the following was sufficient to allow driving the task function from an existing event loop:
One of the main sales pitches here is that this set of changes also can allow such a thing. But if the above is so concise, why are the proposed changes in this PR better? I'm not asking this as a rhetorical question. It is implied what's in this PR is better and I want to understand why. I can see some other problems with select, but I don't think we have a C10K problem to solve. I'm therefore assuming performance isn't a primary motivator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had previously found that for the posix platform, the following was sufficient to allow driving the task function from an existing event loop:
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.cpp b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.cpp index 5d34c339bb..abe2087683 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_POSIX.cpp @@ -155,8 +155,11 @@ void GenericPlatformManagerImpl_POSIX<ImplClass>::SysProcess() nextTimeoutMs = mNextTimeout.tv_sec * 1000 + mNextTimeout.tv_usec / 1000; _StartChipTimer(nextTimeoutMs); + // override; select must not block. + struct timeval immediate = { .tv_sec = 0, .tv_usec = 0 }; + Impl()->UnlockChipStack(); - selectRes = select(mMaxFd + 1, &mReadSet, &mWriteSet, &mErrorSet, &mNextTimeout); + selectRes = select(mMaxFd + 1, &mReadSet, &mWriteSet, &mErrorSet, &immediate); Impl()->LockChipStack(); if (selectRes < 0) @@ -192,7 +195,7 @@ void GenericPlatformManagerImpl_POSIX<ImplClass>::_RunEventLoop() { SysUpdate(); SysProcess(); - } while (mShouldRunEventLoop.load(std::memory_order_relaxed)); + } while (0); // mShouldRunEventLoop.load(std::memory_order_relaxed)); Impl()->UnlockChipStack(); }
That code does not seem sufficient; I don't even see how you would correctly combine this approach with polling other (non-CHIP) file descriptors on the same thread.
To fix the problem, CHIP must register its file descriptors to be included in application's poll set, so that the thread can block itself pending IO on either CHIP owned or application owned file descriptors. Properly there can only be one blocking I/O poll on any given thread. If instead CHIP does a non-blocking poll, and the application does a blocking one, then we won't wake immediately when e.g. UDP packets arrive for CHIP. It may appear to work if there's ongoing activity, but it risks unbounded additional response latency.
This is not about scalability, it's about having the flexibility to use an applications' preferred event loop for the file descriptors managed by CHIP.
One of the main sales pitches here is that this set of changes also can allow such a thing. But if the above is so concise, why are the proposed changes in this PR better? I'm not asking this as a rhetorical question. It is implied what's in this PR is better and I want to understand why.
I can see some other problems with select, but I don't think we have a C10K problem to solve. I'm therefore assuming performance isn't a primary motivator.
src/inet/InetLayer.cpp
Outdated
* For BSD/POSIX Sockets, event readiness notification is handled | ||
* via file descriptors and a traditional poll / select | ||
* implementation on the platform adaptation. | ||
* For BSD/POSIX Sockets (CHIP_SYSTEM_CONFIG_USE_LWIP), event readiness |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CHIP_SYSTEM_CONFIG_USE_LWIP -> CHIP_SYSTEM_CONFIG_USE_SOCKETS ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I will definitely fix and add substantially more documentation.
void SystemSocketWatchState::HandleEvents() | ||
{ | ||
VerifyOrDie(mEventBase != nullptr); | ||
event_base_dispatch(mEventBase); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be event_base_loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably. I've gone back and forth on what exactly HandleEvents()
should mean, so the second opinion is welcome.
void ClearReadable() { mRequestIO.Clear(System::SocketEventFlag::kRead); } | ||
void ClearWritable() { mRequestIO.Clear(System::SocketEventFlag::kWrite); } | ||
|
||
// Platform is currently hard-coded to use InetLayer::HandleSelectResult(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we able to remove this discrepancy and make both work with SetCallback & remove HandleSelectResult?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think that should be easy; I just put it off. The remaining #if-select() code would be the PrepareSelect
/HandleSelectResult
stuff in //system, which looks a bit harder to refactor, but probably possible — if anybody's still going to want to use select() in the long run.
src/system/SystemSockets.h
Outdated
class SystemSocketWatcherBasis | ||
{ | ||
public: | ||
typedef void (*Callback)(int socket, SocketEvents events, void * data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could replace this class with
using SystemSocketWatcherCallback = void(int socket, SocketEvents events, void * data);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The tentative reason for the otherwise-vacuous base class is to have an easily-found place to document the SystemSocketWatcher interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, after further investigation, I do want to have a base class containing the file descriptor and active-event flags — essentially, changing the consumers' members from int mSocket; SocketEvents mPendingIO; SystemSocketWatcher mWatcher;
as here, to WatchableSocket mSocket
.
@mspang and @msandstedt both raise good points here. Ideally, I can have a single-threaded, simple application with multiple "sources" on the main select loop. CHIP should be one potential integration source in such an application. Perhaps Avahi has some inspiring APIs in this regard in terms of how Avahi can be added as such an integration source. It's been a decade-plus since I've looked at that code; however, I think it amounted to being able to import/export the descriptors Avahi uses for its passive/active sockets and being able to patch those in/out of the main select loop with appropriate callbacks when those particular descriptors have "work" to do. IIRC, Apple's mDNS/DNS-SD CFNetworkService code works similarly but in a CFRunLoop-centric way (which is just, at its core, a select loop as hand-waved above). There's a main application CFRunLoop and CFNetworkService is patched in as a source of work on that run loop. IIRC, there was/is no need to maintain a separate mDNS/DNS-SD work thread and manage complexities around multiple threads. If the CHIP stack had the ability, on POSIX-like systems, to export/import descriptors similarly, then it would be possible to have a CFRunLoop adapter, a GLib adapter, etc. for the stack to integrate with each of those run loop types. |
Followups from project-chip#6561 Generalize socket-based event loop #### Change overview * mDNS: Convert `platform/Linux/MdnsImpl`; remove Darwin stubs. * Change `mCallbackData` type to `intptr_t` (review feedback). * Comment for `System::WakeEvent` (this is minimal since it's likely to change soon for issue project-chip#7725). Fixes project-chip#7758 _Convert MDNS to WatchableSocket._ #### Testing Manual sanity check of mDNS using chip-device-ctrl on Linux. Otherwise, no change to functionality is intended.
* #### Problem Followups from #6561 Generalize socket-based event loop #### Change overview * mDNS: Convert `platform/Linux/MdnsImpl`; remove Darwin stubs. * Change `mCallbackData` type to `intptr_t` (review feedback). * Comment for `System::WakeEvent` (this is minimal since it's likely to change soon for issue #7725). Fixes #7758 _Convert MDNS to WatchableSocket._ #### Testing Manual sanity check of mDNS using chip-device-ctrl on Linux. Otherwise, no change to functionality is intended. * review * review
#### Problem XXX #### Change overview XXX socket events in project-chip#6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem XXX #### Change overview XXX socket events in project-chip#6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem XXX #### Change overview XXX socket events in project-chip#6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem XXX #### Change overview XXX socket events in project-chip#6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem XXX #### Change overview XXX socket events in project-chip#6561 Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. `System::Timer` remains as an optional `Object`-pool implementation tool for the XXX The intent is that the public `WatchableEventManager` interface will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will be its implementations. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool.
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool.
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool.
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool.
#### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool.
The event loop in JNI `IOThreadMain()` used to wait no more than ten seconds on each iteration. This timeout was temporarily removed in PR project-chip#6561. #### Change overview Add an explicit ten second timer. Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing How was this tested? (at least one bullet point required) * If unit tests were added, how do they cover this issue? * If unit tests existed, how were they fixed/modified to prevent this in future? * If new unit tests are not added, why not? * If integration tests were added, how do they verify this change? * If new integration tests are not added, why not? * If manually tested, what platforms controller and device platforms were manually tested, and how? * If no testing is required, why not?
The event loop in JNI `IOThreadMain()` used to wait no more than ten seconds on each iteration. This timeout was temporarily removed in PR project-chip#6561. #### Change overview Add an explicit ten second timer. Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Passes Android workflow.
#### Problem The event loop in JNI `IOThreadMain()` used to wait no more than ten seconds on each iteration. This timeout was temporarily removed in PR project-chip#6561. #### Change overview Add an explicit timer. Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Passes Android workflow.
* Separate System::Layer and Timer into per-implementation files. #### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR #6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool. * rebase and regen zap * Remove obsolete TODO. * restyle * remove leftover debug logging * restyle * convert outdated ChipError::FormatError() * review - add config flag CHIP_SYSTEM_CONFIG_USE_TIMER_POOL - use std::lock_guard rather than inventing ScopedMutexLock - rename mWatchableEvents and WatchableEvents()
#### Problem Some TODOs left over from PR project-chip#6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes project-chip#7760 _Some unit tests supply a timeout at low level_ Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests.
#### Problem Some TODOs left over from PR project-chip#6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes project-chip#7760 _Some unit tests supply a timeout at low level_ Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests.
#### Problem Some TODOs left over from PR project-chip#6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes project-chip#7760 _Some unit tests supply a timeout at low level_ Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests.
#### Problem Some TODOs left over from PR project-chip#6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes project-chip#7760 _Some unit tests supply a timeout at low level_ Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests.
* TODOs from PR #6561 #### Problem Some TODOs left over from PR #6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes #7760 _Some unit tests supply a timeout at low level_ Fixes #7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests. * fix kSleepTimeMilliseconds * review
* Generalize socket-based event loop #### Problem Socket event management is currently tied closely to select(2), and does not integrate well with other event loops. See issue project-chip#5556 _rework system layer event loop_ #### Change overview The primary purpose of this change is to provide a clear interface for monitoring socket events, that can be used both within the CHIP SDK and by an application using the SDK, and can be implemented either inside or outside the SDK. Functionality does not change. * Defines an interface, in `system/SystemSockets.h`. * Converts most existing uses of socket event monitoring (except mDNS, to be done as a followup). * Converts the existing select(2)-based event management into an implementation of the new interface. * Adds a second implementation of the interface, using libevent, to verify that the interface is general enough. #### Testing * Converted the applicable unit tests from select(2) to this interface, and ran them with both the select and libevent implementations. (CI remains select-only for now.) * Integration tests involving socket-based platforms exercise this code and confirm no change to functionality. * Manual verification of controller/device communication * Clarify SocketEventFlags error vs exceptional condition * restyle * fixes for CHIP_SYSTEM_CONFIG_USE_DISPATCH merge * restyle * rename System::SystemWakeEvent to System::WakeEvent
…roject-chip#7799) * #### Problem Followups from project-chip#6561 Generalize socket-based event loop #### Change overview * mDNS: Convert `platform/Linux/MdnsImpl`; remove Darwin stubs. * Change `mCallbackData` type to `intptr_t` (review feedback). * Comment for `System::WakeEvent` (this is minimal since it's likely to change soon for issue project-chip#7725). Fixes project-chip#7758 _Convert MDNS to WatchableSocket._ #### Testing Manual sanity check of mDNS using chip-device-ctrl on Linux. Otherwise, no change to functionality is intended. * review * review
…ect-chip#8800) * Separate System::Layer and Timer into per-implementation files. #### Problem Various implementations of System::Layer are provided by `#if` sections, which prevents mock versions for testing and out-of-tree platform implementations. #### Change overview Split platform `#if` sections of `System::Layer` and `System::Timer` into separate `WatchableEventManager` implementations. This change does for timers what PR project-chip#6561 did for socket I/O events. The intent is that the public `WatchableEventManager` interface here will become pure virtual methods of `System::Layer`, and the various versions of `WatchableEventManager` will become its implementations. `System::Timer` remains as an `Object`-pool based utility class for implementing the Timer API. - Make `Timer` list not LwIP-specific, mutex it, and use it in preference to iterating through the entire pool. - Move `IsEarlier` from `Timer` to `Clock`. - Fix dual definitions of `Clock::Platform` functions on Linux. #### Testing Relying on CI in general, since no externally visible functionality should have changed. Sanity-checked the libevent implementation (not in CI) using chip-tool. * rebase and regen zap * Remove obsolete TODO. * restyle * remove leftover debug logging * restyle * convert outdated ChipError::FormatError() * review - add config flag CHIP_SYSTEM_CONFIG_USE_TIMER_POOL - use std::lock_guard rather than inventing ScopedMutexLock - rename mWatchableEvents and WatchableEvents()
* TODOs from PR project-chip#6561 #### Problem Some TODOs left over from PR project-chip#6561. #### Change overview - Remove the temporary `PrepareEventsWithTimeout()`, and have the tests that used it use a timer instead. - Remove obsolete TODOs. Fixes project-chip#7760 _Some unit tests supply a timeout at low level_ Fixes project-chip#7756 _add a timer for sleepTime.tv_sec = 10; sleepTime.tv_usec = 0;_ #### Testing Ran the affected tests. * fix kSleepTimeMilliseconds * review
Problem
Socket event management is currently tied closely to select(2),
and does not integrate well with other event loops.
See issue #5556 rework system layer event loop
Change overview
The primary purpose of this change is to provide a clear interface for
monitoring socket events, that can be used both within the CHIP SDK
and by an application using the SDK, and can be implemented either
inside or outside the SDK. Functionality does not change.
system/SystemSockets.h
.to be done as a followup).
implementation of the new interface.
to verify that the interface is general enough.
Testing
and ran them with both the select and libevent implementations.
(CI remains select-only for now.)
and confirm no change to functionality.