diff --git a/src/posix/platform/alarm.cpp b/src/posix/platform/alarm.cpp index 770a51dab..f6bd5bf3d 100644 --- a/src/posix/platform/alarm.cpp +++ b/src/posix/platform/alarm.cpp @@ -38,6 +38,7 @@ #include #include +#include "mainloop.hpp" #include "common/code_utils.hpp" static bool sIsMsRunning = false; diff --git a/src/posix/platform/daemon.cpp b/src/posix/platform/daemon.cpp index 5a2a9c438..62420ca3d 100644 --- a/src/posix/platform/daemon.cpp +++ b/src/posix/platform/daemon.cpp @@ -334,56 +334,38 @@ void Daemon::TearDown(void) #endif } -void Daemon::Update(otSysMainloopContext &aContext) +void Daemon::Update(Mainloop::Context &aContext) { - if (mListenSocket != -1) - { - FD_SET(mListenSocket, &aContext.mReadFdSet); - FD_SET(mListenSocket, &aContext.mErrorFdSet); + Mainloop::AddToReadFdSet(mListenSocket, aContext); + Mainloop::AddToErrorFdSet(mListenSocket, aContext); - if (aContext.mMaxFd < mListenSocket) - { - aContext.mMaxFd = mListenSocket; - } - } - - if (mSessionSocket != -1) - { - FD_SET(mSessionSocket, &aContext.mReadFdSet); - FD_SET(mSessionSocket, &aContext.mErrorFdSet); - - if (aContext.mMaxFd < mSessionSocket) - { - aContext.mMaxFd = mSessionSocket; - } - } - - return; + Mainloop::AddToReadFdSet(mSessionSocket, aContext); + Mainloop::AddToErrorFdSet(mSessionSocket, aContext); } -void Daemon::Process(const otSysMainloopContext &aContext) +void Daemon::Process(const Mainloop::Context &aContext) { ssize_t rval; VerifyOrExit(mListenSocket != -1); - if (FD_ISSET(mListenSocket, &aContext.mErrorFdSet)) + if (Mainloop::HasFdErrored(mListenSocket, aContext)) { DieNowWithMessage("daemon socket error", OT_EXIT_FAILURE); } - else if (FD_ISSET(mListenSocket, &aContext.mReadFdSet)) + else if (Mainloop::IsFdReadable(mListenSocket, aContext)) { InitializeSessionSocket(); } VerifyOrExit(mSessionSocket != -1); - if (FD_ISSET(mSessionSocket, &aContext.mErrorFdSet)) + if (Mainloop::HasFdErrored(mSessionSocket, aContext)) { close(mSessionSocket); mSessionSocket = -1; } - else if (FD_ISSET(mSessionSocket, &aContext.mReadFdSet)) + else if (Mainloop::IsFdReadable(mSessionSocket, aContext)) { uint8_t buffer[OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH]; diff --git a/src/posix/platform/daemon.hpp b/src/posix/platform/daemon.hpp index be3738b8f..c4ced601b 100644 --- a/src/posix/platform/daemon.hpp +++ b/src/posix/platform/daemon.hpp @@ -47,8 +47,8 @@ public: void SetUp(void); void TearDown(void); - void Update(otSysMainloopContext &aContext) override; - void Process(const otSysMainloopContext &aContext) override; + void Update(Mainloop::Context &aContext) override; + void Process(const Mainloop::Context &aContext) override; int OutputFormatV(const char *aFormat, va_list aArguments); private: diff --git a/src/posix/platform/infra_if.cpp b/src/posix/platform/infra_if.cpp index 71c5d785c..c098ddf12 100644 --- a/src/posix/platform/infra_if.cpp +++ b/src/posix/platform/infra_if.cpp @@ -516,7 +516,7 @@ void InfraNetif::Deinit(void) mInfraIfIndex = 0; } -void InfraNetif::Update(otSysMainloopContext &aContext) +void InfraNetif::Update(Mainloop::Context &aContext) { #ifdef __linux__ VerifyOrExit(mNetLinkSocket != -1); @@ -525,13 +525,11 @@ void InfraNetif::Update(otSysMainloopContext &aContext) #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE VerifyOrExit(mInfraIfIcmp6Socket != -1); - FD_SET(mInfraIfIcmp6Socket, &aContext.mReadFdSet); - aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mInfraIfIcmp6Socket); + Mainloop::AddToReadFdSet(mInfraIfIcmp6Socket, aContext); #endif #ifdef __linux__ - FD_SET(mNetLinkSocket, &aContext.mReadFdSet); - aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mNetLinkSocket); + Mainloop::AddToReadFdSet(mNetLinkSocket, aContext); #endif exit: @@ -682,7 +680,7 @@ void InfraNetif::SetInfraNetifIcmp6SocketForBorderRouting(int aIcmp6Socket) } #endif -void InfraNetif::Process(const otSysMainloopContext &aContext) +void InfraNetif::Process(const Mainloop::Context &aContext) { #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE VerifyOrExit(mInfraIfIcmp6Socket != -1); @@ -693,14 +691,14 @@ void InfraNetif::Process(const otSysMainloopContext &aContext) #endif #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - if (FD_ISSET(mInfraIfIcmp6Socket, &aContext.mReadFdSet)) + if (Mainloop::IsFdReadable(mInfraIfIcmp6Socket, aContext)) { ReceiveIcmp6Message(); } #endif #ifdef __linux__ - if (FD_ISSET(mNetLinkSocket, &aContext.mReadFdSet)) + if (Mainloop::IsFdReadable(mNetLinkSocket, aContext)) { ReceiveNetLinkMessage(); } diff --git a/src/posix/platform/infra_if.hpp b/src/posix/platform/infra_if.hpp index c36ff1d9a..5abba0412 100644 --- a/src/posix/platform/infra_if.hpp +++ b/src/posix/platform/infra_if.hpp @@ -64,14 +64,14 @@ public: * * @param[in,out] aContext A reference to the mainloop context. */ - void Update(otSysMainloopContext &aContext) override; + void Update(Mainloop::Context &aContext) override; /** * Performs infrastructure network interface processing. * * @param[in] aContext A reference to the mainloop context. */ - void Process(const otSysMainloopContext &aContext) override; + void Process(const Mainloop::Context &aContext) override; /** * Initializes the infrastructure network interface. diff --git a/src/posix/platform/mainloop.cpp b/src/posix/platform/mainloop.cpp index 9accbc9b4..4b5f2404d 100644 --- a/src/posix/platform/mainloop.cpp +++ b/src/posix/platform/mainloop.cpp @@ -30,12 +30,51 @@ #include +#include + #include "common/code_utils.hpp" namespace ot { namespace Posix { namespace Mainloop { +//--------------------------------------------------------------------------------------------------------------------- + +static void AddFd(int aFd, Context &aContext, fd_set &aFdSet) +{ + VerifyOrExit(aFd >= 0); + + FD_SET(aFd, &aFdSet); + aContext.mMaxFd = OT_MAX(aContext.mMaxFd, aFd); + +exit: + return; +} + +void AddToReadFdSet(int aFd, Context &aContext) { AddFd(aFd, aContext, aContext.mReadFdSet); } +void AddToWriteFdSet(int aFd, Context &aContext) { AddFd(aFd, aContext, aContext.mWriteFdSet); } +void AddToErrorFdSet(int aFd, Context &aContext) { AddFd(aFd, aContext, aContext.mErrorFdSet); } + +uint64_t GetTimeout(const Context &aContext) +{ + return static_cast(aContext.mTimeout.tv_sec) * OT_US_PER_S + + static_cast(aContext.mTimeout.tv_usec); +} + +void SetTimeoutIfEarlier(uint64_t aTimeout, Context &aContext) +{ + VerifyOrExit(aTimeout < GetTimeout(aContext)); + + aContext.mTimeout.tv_sec = static_cast(aTimeout / OT_US_PER_S); + aContext.mTimeout.tv_usec = static_cast(aTimeout % OT_US_PER_S); + +exit: + return; +} + +//--------------------------------------------------------------------------------------------------------------------- +// Manager + void Manager::Add(Source &aSource) { assert(aSource.mNext == nullptr); @@ -58,7 +97,7 @@ void Manager::Remove(Source &aSource) aSource.mNext = nullptr; } -void Manager::Update(otSysMainloopContext &aContext) +void Manager::Update(Context &aContext) { for (Source *source = mSources; source != nullptr; source = source->mNext) { @@ -66,7 +105,7 @@ void Manager::Update(otSysMainloopContext &aContext) } } -void Manager::Process(const otSysMainloopContext &aContext) +void Manager::Process(const Context &aContext) { for (Source *source = mSources; source != nullptr; source = source->mNext) { diff --git a/src/posix/platform/mainloop.hpp b/src/posix/platform/mainloop.hpp index dbc7c1fe7..2e7a510f9 100644 --- a/src/posix/platform/mainloop.hpp +++ b/src/posix/platform/mainloop.hpp @@ -40,6 +40,97 @@ namespace ot { namespace Posix { namespace Mainloop { +typedef otSysMainloopContext Context; ///< Represents a `Mainloop` context. + +/** + * Adds a file descriptor to the read set in the mainloop context. + * + * If the file descriptor @p aFd is valid (non-negative), this method adds it to `aContext.mReadFdSet` and + * updates `aContext.mMaxFd` if @p aFd is larger than the current max. If @p aFd is negative, no action is taken. + * + * @param[in] aFd The file descriptor to add. + * @param[in,out] aContext A reference to the mainloop context. + */ +void AddToReadFdSet(int aFd, Context &aContext); + +/** + * Adds a file descriptor to the write set in the mainloop context. + * + * If the file descriptor @p aFd is valid (non-negative), this method adds it to `aContext.mWriteFdSet` and + * updates `aContext.mMaxFd` if @p aFd is larger than the current max. If @p aFd is negative, no action is taken. + * + * @param[in] aFd The file descriptor to add. + * @param[in,out] aContext A reference to the mainloop context. + */ +void AddToWriteFdSet(int aFd, Context &aContext); + +/** + * Adds a file descriptor to the error set in the mainloop context. + * + * If the file descriptor @p aFd is valid (non-negative), this method adds it to `aContext.mErrorFdSet` and + * updates `aContext.mMaxFd` if @p aFd is larger than the current max. If @p aFd is negative, no action is taken. + * + * @param[in] aFd The file descriptor to add. + * @param[in,out] aContext A reference to the mainloop context. + */ +void AddToErrorFdSet(int aFd, Context &aContext); + +/** + * Checks if a file descriptor is in the read set of the mainloop context. + * + * This is intended to be called after the `select()` call has returned. + * + * @param[in] aFd The file descriptor to check. + * @param[in] aContext A reference to the mainloop context. + * + * @returns `true` if the given file descriptor is readable, `false` otherwise. + */ +inline bool IsFdReadable(int aFd, const Context &aContext) { return FD_ISSET(aFd, &aContext.mReadFdSet); } + +/** + * Checks if a file descriptor is in the write set of the mainloop context. + * + * This is intended to be called after the `select()` call has returned. + * + * @param[in] aFd The file descriptor to check. + * @param[in] aContext A reference to the mainloop context. + * + * @returns `true` if the given file descriptor is writable, `false` otherwise. + */ +inline bool IsFdWritable(int aFd, const Context &aContext) { return FD_ISSET(aFd, &aContext.mWriteFdSet); } + +/** + * Checks if a file descriptor is in the error set of the mainloop context. + * + * This is intended to be called after the `select()` call has returned. + * + * @param[in] aFd The file descriptor to check. + * @param[in] aContext A reference to the mainloop context. + * + * @returns `true` if the given file descriptor has an error, `false` otherwise. + */ +inline bool HasFdErrored(int aFd, const Context &aContext) { return FD_ISSET(aFd, &aContext.mErrorFdSet); } + +/** + * Gets the current timeout value from the mainloop context. + * + * @param[in] aContext A reference to the mainloop context. + * + * @returns The timeout value. + */ +uint64_t GetTimeout(const Context &aContext); + +/** + * Sets the timeout in the mainloop context if the new timeout is earlier than the existing one. + * + * This method compares `aTimeout` with the current timeout in `aContext` and updates the context's + * timeout to `aTimeout` if it is smaller (earlier). + * + * @param[in] aTimeout The new timeout value to potentially set. + * @param[in,out] aContext A reference to the mainloop context. + */ +void SetTimeoutIfEarlier(uint64_t aTimeout, Context &aContext); + /** * Is the base for all mainloop event sources. */ @@ -53,21 +144,23 @@ public: * * @param[in,out] aContext A reference to the mainloop context. */ - virtual void Update(otSysMainloopContext &aContext) = 0; + virtual void Update(Context &aContext) = 0; /** * Processes the mainloop events. * * @param[in] aContext A reference to the mainloop context. */ - virtual void Process(const otSysMainloopContext &aContext) = 0; + virtual void Process(const Context &aContext) = 0; /** * Marks destructor virtual method. */ - virtual ~Source() = default; + virtual ~Source(void) = default; private: + static void AddFd(int aFd, Context &aContext, fd_set &aFdSet); + Source *mNext = nullptr; }; @@ -82,14 +175,14 @@ public: * * @param[in,out] aContext A reference to the mainloop context. */ - void Update(otSysMainloopContext &aContext); + void Update(Context &aContext); /** * Processes events in the mainloop context. * * @param[in] aContext A reference to the mainloop context. */ - void Process(const otSysMainloopContext &aContext); + void Process(const Context &aContext); /** * Adds a new event source into the mainloop. diff --git a/src/posix/platform/mdns_socket.cpp b/src/posix/platform/mdns_socket.cpp index 14b370ef8..1c1088352 100644 --- a/src/posix/platform/mdns_socket.cpp +++ b/src/posix/platform/mdns_socket.cpp @@ -133,35 +133,25 @@ void MdnsSocket::Deinit(void) CloseIp6Socket(); } -void MdnsSocket::Update(otSysMainloopContext &aContext) +void MdnsSocket::Update(Mainloop::Context &aContext) { VerifyOrExit(mEnabled); - FD_SET(mFd6, &aContext.mReadFdSet); - FD_SET(mFd4, &aContext.mReadFdSet); + Mainloop::AddToReadFdSet(mFd6, aContext); + Mainloop::AddToReadFdSet(mFd4, aContext); if (mPendingIp6Tx > 0) { - FD_SET(mFd6, &aContext.mWriteFdSet); + Mainloop::AddToWriteFdSet(mFd6, aContext); } if (mPendingIp4Tx > 0) { - FD_SET(mFd4, &aContext.mWriteFdSet); - } - - if (aContext.mMaxFd < mFd6) - { - aContext.mMaxFd = mFd6; - } - - if (aContext.mMaxFd < mFd4) - { - aContext.mMaxFd = mFd4; + Mainloop::AddToWriteFdSet(mFd4, aContext); } #if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC) - UpdateTimeout(aContext.mTimeout); + UpdateTimeout(aContext); #elif (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_NETLINK) UpdateNetlink(aContext); #endif @@ -170,26 +160,26 @@ exit: return; } -void MdnsSocket::Process(const otSysMainloopContext &aContext) +void MdnsSocket::Process(const Mainloop::Context &aContext) { VerifyOrExit(mEnabled); - if (FD_ISSET(mFd6, &aContext.mWriteFdSet)) + if (Mainloop::IsFdWritable(mFd6, aContext)) { SendQueuedMessages(kIp6Msg); } - if (FD_ISSET(mFd4, &aContext.mWriteFdSet)) + if (Mainloop::IsFdWritable(mFd4, aContext)) { SendQueuedMessages(kIp4Msg); } - if (FD_ISSET(mFd6, &aContext.mReadFdSet)) + if (Mainloop::IsFdReadable(mFd6, aContext)) { ReceiveMessage(kIp6Msg); } - if (FD_ISSET(mFd4, &aContext.mReadFdSet)) + if (Mainloop::IsFdReadable(mFd4, aContext)) { ReceiveMessage(kIp4Msg); } @@ -576,24 +566,17 @@ void MdnsSocket::StartAddressMonitoring(void) { ReportInfraIfAddresses(); } void MdnsSocket::StopAddressMonitoring(void) {} -void MdnsSocket::UpdateTimeout(struct timeval &aTimeout) +void MdnsSocket::UpdateTimeout(Mainloop::Context &aContext) { uint64_t now = otPlatTimeGet(); uint64_t remaining = 1; - uint64_t timeout; if (mNextReportTime > now) { remaining = mNextReportTime - now; } - timeout = static_cast(aTimeout.tv_sec) * OT_US_PER_S + static_cast(aTimeout.tv_usec); - - if (remaining < timeout) - { - aTimeout.tv_sec = static_cast(remaining / OT_US_PER_S); - aTimeout.tv_usec = static_cast(remaining % OT_US_PER_S); - } + Mainloop::SetTimeoutIfEarlier(remaining, aContext); } void MdnsSocket::ProcessTimeout(void) @@ -638,22 +621,9 @@ void MdnsSocket::StopAddressMonitoring(void) mNetlinkFd = -1; } -void MdnsSocket::UpdateNetlink(otSysMainloopContext &aContext) const -{ - VerifyOrExit(mNetlinkFd >= 0); +void MdnsSocket::UpdateNetlink(Mainloop::Context &aContext) const { Mainloop::AddToReadFdSet(mNetlinkFd, aContext); } - FD_SET(mNetlinkFd, &aContext.mReadFdSet); - - if (aContext.mMaxFd < mNetlinkFd) - { - aContext.mMaxFd = mNetlinkFd; - } - -exit: - return; -} - -void MdnsSocket::ProcessNetlink(const otSysMainloopContext &aContext) const +void MdnsSocket::ProcessNetlink(const Mainloop::Context &aContext) const { static const size_t kBufSize = 8192; @@ -669,7 +639,7 @@ void MdnsSocket::ProcessNetlink(const otSysMainloopContext &aContext) const VerifyOrExit(mNetlinkFd >= 0); - VerifyOrExit(FD_ISSET(mNetlinkFd, &aContext.mReadFdSet)); + VerifyOrExit(Mainloop::IsFdReadable(mNetlinkFd, aContext)); rval = recv(mNetlinkFd, rcvMsg.mBuffer, sizeof(rcvMsg.mBuffer), 0); diff --git a/src/posix/platform/mdns_socket.hpp b/src/posix/platform/mdns_socket.hpp index 3c49262c0..8f33e2405 100644 --- a/src/posix/platform/mdns_socket.hpp +++ b/src/posix/platform/mdns_socket.hpp @@ -114,14 +114,14 @@ public: * * @param[in,out] aContext A reference to the mainloop context. */ - void Update(otSysMainloopContext &aContext) override; + void Update(Mainloop::Context &aContext) override; /** * Performs `MdnsSocket` processing. * * @param[in] aContext A reference to the mainloop context. */ - void Process(const otSysMainloopContext &aContext) override; + void Process(const Mainloop::Context &aContext) override; // otPlatMdns APIs otError SetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex); @@ -158,11 +158,11 @@ private: void StopAddressMonitoring(void); void ReportInfraIfAddresses(void); #if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC) - void UpdateTimeout(struct timeval &aTimeout); + void UpdateTimeout(Mainloop::Context &aContext); void ProcessTimeout(void); #elif (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_NETLINK) - void UpdateNetlink(otSysMainloopContext &aContext) const; - void ProcessNetlink(const otSysMainloopContext &aContext) const; + void UpdateNetlink(Mainloop::Context &aContext) const; + void ProcessNetlink(const Mainloop::Context &aContext) const; void ProcessNetlinkAddrEvent(void *aNetlinkMsg) const; #endif diff --git a/src/posix/platform/multicast_routing.cpp b/src/posix/platform/multicast_routing.cpp index 07a00664e..3835a3bcc 100644 --- a/src/posix/platform/multicast_routing.cpp +++ b/src/posix/platform/multicast_routing.cpp @@ -187,24 +187,23 @@ exit: return found; } -void MulticastRoutingManager::Update(otSysMainloopContext &aContext) +void MulticastRoutingManager::Update(Mainloop::Context &aContext) { VerifyOrExit(IsEnabled()); - FD_SET(mMulticastRouterSock, &aContext.mReadFdSet); - aContext.mMaxFd = OT_MAX(aContext.mMaxFd, mMulticastRouterSock); + Mainloop::AddToReadFdSet(mMulticastRouterSock, aContext); exit: return; } -void MulticastRoutingManager::Process(const otSysMainloopContext &aContext) +void MulticastRoutingManager::Process(const Mainloop::Context &aContext) { VerifyOrExit(IsEnabled()); ExpireMulticastForwardingCache(); - if (FD_ISSET(mMulticastRouterSock, &aContext.mReadFdSet)) + if (Mainloop::IsFdReadable(mMulticastRouterSock, aContext)) { ProcessMulticastRouterMessages(); } diff --git a/src/posix/platform/multicast_routing.hpp b/src/posix/platform/multicast_routing.hpp index 9d4e0491e..2645a5d5e 100644 --- a/src/posix/platform/multicast_routing.hpp +++ b/src/posix/platform/multicast_routing.hpp @@ -64,8 +64,8 @@ public: bool IsEnabled(void) const { return mMulticastRouterSock >= 0; } void SetUp(void); void TearDown(void); - void Update(otSysMainloopContext &aContext) override; - void Process(const otSysMainloopContext &aContext) override; + void Update(Mainloop::Context &aContext) override; + void Process(const Mainloop::Context &aContext) override; void HandleStateChange(otInstance *aInstance, otChangedFlags aFlags); private: diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp index 1fb3fa0bc..4cf0ed724 100644 --- a/src/posix/platform/netif.cpp +++ b/src/posix/platform/netif.cpp @@ -154,6 +154,7 @@ extern int #include "ip6_utils.hpp" #include "logger.hpp" +#include "mainloop.hpp" #include "resolver.hpp" #include "utils.hpp" #include "common/code_utils.hpp" @@ -2331,7 +2332,7 @@ void platformNetifDeinit(void) gNetifIndex = 0; } -void platformNetifUpdateFdSet(otSysMainloopContext *aContext) +void platformNetifUpdateFdSet(ot::Posix::Mainloop::Context *aContext) { VerifyOrExit(gNetifIndex > 0); @@ -2340,72 +2341,56 @@ void platformNetifUpdateFdSet(otSysMainloopContext *aContext) assert(sNetlinkFd >= 0); assert(sIpFd >= 0); - FD_SET(sTunFd, &aContext->mReadFdSet); - FD_SET(sTunFd, &aContext->mErrorFdSet); - FD_SET(sNetlinkFd, &aContext->mReadFdSet); - FD_SET(sNetlinkFd, &aContext->mErrorFdSet); + ot::Posix::Mainloop::AddToReadFdSet(sTunFd, *aContext); + ot::Posix::Mainloop::AddToErrorFdSet(sTunFd, *aContext); + ot::Posix::Mainloop::AddToReadFdSet(sNetlinkFd, *aContext); + ot::Posix::Mainloop::AddToErrorFdSet(sNetlinkFd, *aContext); #if OPENTHREAD_POSIX_USE_MLD_MONITOR - FD_SET(sMLDMonitorFd, &aContext->mReadFdSet); - FD_SET(sMLDMonitorFd, &aContext->mErrorFdSet); + ot::Posix::Mainloop::AddToReadFdSet(sMLDMonitorFd, *aContext); + ot::Posix::Mainloop::AddToErrorFdSet(sMLDMonitorFd, *aContext); #endif - if (sTunFd > aContext->mMaxFd) - { - aContext->mMaxFd = sTunFd; - } - - if (sNetlinkFd > aContext->mMaxFd) - { - aContext->mMaxFd = sNetlinkFd; - } - -#if OPENTHREAD_POSIX_USE_MLD_MONITOR - if (sMLDMonitorFd > aContext->mMaxFd) - { - aContext->mMaxFd = sMLDMonitorFd; - } -#endif exit: return; } -void platformNetifProcess(const otSysMainloopContext *aContext) +void platformNetifProcess(const ot::Posix::Mainloop::Context *aContext) { assert(aContext != nullptr); VerifyOrExit(gNetifIndex > 0); - if (FD_ISSET(sTunFd, &aContext->mErrorFdSet)) + if (ot::Posix::Mainloop::HasFdErrored(sTunFd, *aContext)) { close(sTunFd); DieNow(OT_EXIT_FAILURE); } - if (FD_ISSET(sNetlinkFd, &aContext->mErrorFdSet)) + if (ot::Posix::Mainloop::HasFdErrored(sNetlinkFd, *aContext)) { close(sNetlinkFd); DieNow(OT_EXIT_FAILURE); } #if OPENTHREAD_POSIX_USE_MLD_MONITOR - if (FD_ISSET(sMLDMonitorFd, &aContext->mErrorFdSet)) + if (ot::Posix::Mainloop::HasFdErrored(sMLDMonitorFd, *aContext)) { close(sMLDMonitorFd); DieNow(OT_EXIT_FAILURE); } #endif - if (FD_ISSET(sTunFd, &aContext->mReadFdSet)) + if (ot::Posix::Mainloop::IsFdReadable(sTunFd, *aContext)) { processTransmit(gInstance); } - if (FD_ISSET(sNetlinkFd, &aContext->mReadFdSet)) + if (ot::Posix::Mainloop::IsFdReadable(sNetlinkFd, *aContext)) { processNetlinkEvent(gInstance); } #if OPENTHREAD_POSIX_USE_MLD_MONITOR - if (FD_ISSET(sMLDMonitorFd, &aContext->mReadFdSet)) + if (ot::Posix::Mainloop::IsFdReadable(sMLDMonitorFd, *aContext)) { processMLDEvent(gInstance); } diff --git a/src/posix/platform/resolver.cpp b/src/posix/platform/resolver.cpp index 47f20f04e..d4ae49e46 100644 --- a/src/posix/platform/resolver.cpp +++ b/src/posix/platform/resolver.cpp @@ -422,42 +422,33 @@ void Resolver::CloseTransaction(Transaction *aTxn) aTxn->mThreadTxn = nullptr; } -void Resolver::UpdateFdSet(otSysMainloopContext &aContext) +void Resolver::UpdateFdSet(Mainloop::Context &aContext) { for (Transaction &txn : mUpstreamTransaction) { if (txn.mThreadTxn != nullptr) { - FD_SET(txn.mUdpFd4, &aContext.mReadFdSet); - FD_SET(txn.mUdpFd4, &aContext.mErrorFdSet); - FD_SET(txn.mUdpFd6, &aContext.mReadFdSet); - FD_SET(txn.mUdpFd6, &aContext.mErrorFdSet); - - if (txn.mUdpFd6 > aContext.mMaxFd) - { - aContext.mMaxFd = txn.mUdpFd6; - } - if (txn.mUdpFd4 > aContext.mMaxFd) - { - aContext.mMaxFd = txn.mUdpFd4; - } + Mainloop::AddToReadFdSet(txn.mUdpFd4, aContext); + Mainloop::AddToErrorFdSet(txn.mUdpFd4, aContext); + Mainloop::AddToReadFdSet(txn.mUdpFd6, aContext); + Mainloop::AddToErrorFdSet(txn.mUdpFd6, aContext); } } } -void Resolver::Process(const otSysMainloopContext &aContext) +void Resolver::Process(const Mainloop::Context &aContext) { for (Transaction &txn : mUpstreamTransaction) { if (txn.mThreadTxn != nullptr) { // Note: On Linux, we can only get the error via read, so they should share the same logic. - if (FD_ISSET(txn.mUdpFd4, &aContext.mErrorFdSet) || FD_ISSET(txn.mUdpFd4, &aContext.mReadFdSet)) + if (Mainloop::HasFdErrored(txn.mUdpFd4, aContext) || Mainloop::IsFdReadable(txn.mUdpFd4, aContext)) { ForwardResponse(txn.mThreadTxn, txn.mUdpFd4); CloseTransaction(&txn); } - else if (FD_ISSET(txn.mUdpFd6, &aContext.mErrorFdSet) || FD_ISSET(txn.mUdpFd6, &aContext.mReadFdSet)) + else if (Mainloop::HasFdErrored(txn.mUdpFd6, aContext) || Mainloop::IsFdReadable(txn.mUdpFd6, aContext)) { ForwardResponse(txn.mThreadTxn, txn.mUdpFd6); CloseTransaction(&txn); diff --git a/src/posix/platform/resolver.hpp b/src/posix/platform/resolver.hpp index 8b9261951..5f9127070 100644 --- a/src/posix/platform/resolver.hpp +++ b/src/posix/platform/resolver.hpp @@ -36,6 +36,7 @@ #include #include "logger.hpp" +#include "mainloop.hpp" #if OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE @@ -92,14 +93,14 @@ public: * * @param[in,out] aContext The mainloop context. */ - void UpdateFdSet(otSysMainloopContext &aContext); + void UpdateFdSet(Mainloop::Context &aContext); /** * Handles the result of select. * * @param[in] aContext The mainloop context. */ - void Process(const otSysMainloopContext &aContext); + void Process(const Mainloop::Context &aContext); /** * Sets whether to retrieve upstream DNS servers from "resolv.conf". diff --git a/src/posix/platform/trel.cpp b/src/posix/platform/trel.cpp index 6394c0b23..690afa267 100644 --- a/src/posix/platform/trel.cpp +++ b/src/posix/platform/trel.cpp @@ -47,6 +47,7 @@ #include #include "logger.hpp" +#include "mainloop.hpp" #include "radio_url.hpp" #include "system.hpp" #include "utils.hpp" @@ -666,22 +667,17 @@ exit: return; } -void platformTrelUpdateFdSet(otSysMainloopContext *aContext) +void platformTrelUpdateFdSet(ot::Posix::Mainloop::Context *aContext) { assert(aContext != nullptr); VerifyOrExit(sEnabled); - FD_SET(sSocket, &aContext->mReadFdSet); + ot::Posix::Mainloop::AddToReadFdSet(sSocket, *aContext); if (sTxPacketQueueTail != nullptr) { - FD_SET(sSocket, &aContext->mWriteFdSet); - } - - if (aContext->mMaxFd < sSocket) - { - aContext->mMaxFd = sSocket; + ot::Posix::Mainloop::AddToWriteFdSet(sSocket, *aContext); } trelDnssdUpdateFdSet(aContext); @@ -690,16 +686,16 @@ exit: return; } -void platformTrelProcess(otInstance *aInstance, const otSysMainloopContext *aContext) +void platformTrelProcess(otInstance *aInstance, const ot::Posix::Mainloop::Context *aContext) { VerifyOrExit(sEnabled); - if (FD_ISSET(sSocket, &aContext->mWriteFdSet)) + if (ot::Posix::Mainloop::IsFdWritable(sSocket, *aContext)) { SendQueuedPackets(); } - if (FD_ISSET(sSocket, &aContext->mReadFdSet)) + if (ot::Posix::Mainloop::IsFdReadable(sSocket, *aContext)) { ReceivePacket(sSocket, aInstance); } diff --git a/src/posix/platform/udp.cpp b/src/posix/platform/udp.cpp index 702580790..c6901c70d 100644 --- a/src/posix/platform/udp.cpp +++ b/src/posix/platform/udp.cpp @@ -565,7 +565,7 @@ namespace Posix { const char Udp::kLogModuleName[] = "Udp"; -void Udp::Update(otSysMainloopContext &aContext) +void Udp::Update(Mainloop::Context &aContext) { VerifyOrExit(gNetifIndex != 0); @@ -579,12 +579,7 @@ void Udp::Update(otSysMainloopContext &aContext) } fd = FdFromHandle(socket->mHandle); - FD_SET(fd, &aContext.mReadFdSet); - - if (aContext.mMaxFd < fd) - { - aContext.mMaxFd = fd; - } + Mainloop::AddToReadFdSet(fd, aContext); } exit: @@ -626,7 +621,7 @@ Udp &Udp::Get(void) return sInstance; } -void Udp::Process(const otSysMainloopContext &aContext) +void Udp::Process(const Mainloop::Context &aContext) { otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL}; @@ -634,7 +629,7 @@ void Udp::Process(const otSysMainloopContext &aContext) { int fd = FdFromHandle(socket->mHandle); - if (fd > 0 && FD_ISSET(fd, &aContext.mReadFdSet)) + if (fd > 0 && Mainloop::IsFdReadable(fd, aContext)) { otMessageInfo messageInfo; otMessage *message = nullptr; diff --git a/src/posix/platform/udp.hpp b/src/posix/platform/udp.hpp index f22a8cf22..6bcae387c 100644 --- a/src/posix/platform/udp.hpp +++ b/src/posix/platform/udp.hpp @@ -47,8 +47,8 @@ public: void SetUp(void); void TearDown(void); void Deinit(void); - void Update(otSysMainloopContext &aContext) override; - void Process(const otSysMainloopContext &aContext) override; + void Update(Mainloop::Context &aContext) override; + void Process(const Mainloop::Context &aContext) override; }; } // namespace Posix diff --git a/src/posix/platform/virtual_time.cpp b/src/posix/platform/virtual_time.cpp index d5e90cfcc..87d6b0d6e 100644 --- a/src/posix/platform/virtual_time.cpp +++ b/src/posix/platform/virtual_time.cpp @@ -43,6 +43,7 @@ #include #include +#include "mainloop.hpp" #include "utils.hpp" #if OPENTHREAD_POSIX_VIRTUAL_TIME @@ -220,22 +221,15 @@ void virtualTimeSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength virtualTimeSendEvent(&event, offsetof(struct VirtualTimeEvent, mData) + event.mDataLength); } -void virtualTimeUpdateFdSet(otSysMainloopContext *aContext) -{ - FD_SET(sSockFd, &aContext->mReadFdSet); - if (aContext->mMaxFd < sSockFd) - { - aContext->mMaxFd = sSockFd; - } -} +void virtualTimeUpdateFdSet(Mainloop::Context *aContext) { Mainloop::AddToReadFdSet(sSockFd, *aContext); } -void virtualTimeProcess(otInstance *aInstance, const otSysMainloopContext *aContext) +void virtualTimeProcess(otInstance *aInstance, const Mainloop::Context *aContext) { struct VirtualTimeEvent event; memset(&event, 0, sizeof(event)); - if (FD_ISSET(sSockFd, &aContext->mReadFdSet)) + if (Mainloop::IsFdReadable(sSockFd, *aContext)) { virtualTimeReceiveEvent(&event); }