/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2014-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements Layer using select().
 */

#include <lib/support/CodeUtils.h>
#include <lib/support/TimeUtils.h>
#include <platform/LockTracker.h>
#include <system/SystemFaultInjection.h>
#include <system/SystemLayer.h>
#include <system/SystemLayerImplSelect.h>

#include <algorithm>
#include <errno.h>

// Choose an approximation of PTHREAD_NULL if pthread.h doesn't define one.
#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL)
#define PTHREAD_NULL 0
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING && !defined(PTHREAD_NULL)

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
// older libev do not yet have ev_io_modify
#ifndef ev_io_modify
#define ev_io_modify(ev, events_)                                                                                                  \
    do                                                                                                                             \
    {                                                                                                                              \
        (ev)->events = ((ev)->events & EV__IOFDSET) | (events_);                                                                   \
    } while (0)
#endif // ev_io_modify
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

namespace chip {
namespace System {

constexpr Clock::Seconds64 kDefaultMinSleepPeriod = Clock::Seconds64(60 * 60 * 24 * 30); // Month [sec]

CriticalFailure LayerImplSelect::Init()
{
    VerifyOrReturnError(mLayerState.SetInitializing(), CHIP_ERROR_INCORRECT_STATE);

    RegisterPOSIXErrorFormatter();

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    for (auto & w : mSocketWatchPool)
    {
        w.Clear();
    }
#endif

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    mHandleSelectThread = PTHREAD_NULL;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

#if !CHIP_SYSTEM_CONFIG_USE_LIBEV
    // Create an event to allow an arbitrary thread to wake the thread in the select loop.
    ReturnErrorOnFailure(mWakeEvent.Open());
#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV

    VerifyOrReturnError(mLayerState.SetInitialized(), CHIP_ERROR_INCORRECT_STATE);
    return CHIP_NO_ERROR;
}

void LayerImplSelect::Shutdown()
{
    VerifyOrReturn(mLayerState.SetShuttingDown());

    EventSourceClear();
#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    TimerList::Node * timer;
    while ((timer = mTimerList.PopEarliest()) != nullptr)
    {
        if (ev_is_active(&timer->mLibEvTimer))
        {
            ev_timer_stop(mLibEvLoopP, &timer->mLibEvTimer);
        }
    }
    mTimerPool.ReleaseAll();

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    for (auto & w : mSocketWatchPool)
    {
        w.DisableAndClear();
    }
#endif
#else
    mTimerList.Clear();
    mTimerPool.ReleaseAll();
    mWakeEvent.Close();
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    mLayerState.ResetFromShuttingDown(); // Return to uninitialized state to permit re-initialization.
}

void LayerImplSelect::Signal()
{
#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    ChipLogError(DeviceLayer, "Signal() should not be called in CHIP_SYSTEM_CONFIG_USE_LIBEV builds (might be ok in tests)");
#else
    /*
     * Wake up the I/O thread by writing a single byte to the wake pipe.
     *
     * If this is being called from within an I/O event callback, then writing to the wake pipe can be skipped,
     * since the I/O thread is already awake.
     *
     * Furthermore, we don't care if this write fails as the only reasonably likely failure is that the pipe is full, in which
     * case the select calling thread is going to wake up anyway.
     */
#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    if (pthread_equal(mHandleSelectThread, pthread_self()))
    {
        return;
    }
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

    // Send notification to wake up the select call.
    CHIP_ERROR status = mWakeEvent.Notify();
    if (status != CHIP_NO_ERROR)
    {

        ChipLogError(chipSystemLayer, "System wake event notify failed: %" CHIP_ERROR_FORMAT, status.Format());
    }
#endif // !CHIP_SYSTEM_CONFIG_USE_LIBEV
}

CriticalFailure LayerImplSelect::StartTimer(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState)
{
    assertChipStackLockedByCurrentThread();

    VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

    CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_TimeoutImmediate, delay = System::Clock::kZero);

    CancelTimer(onComplete, appState);

    TimerList::Node * timer = mTimerPool.Create(*this, SystemClock().GetMonotonicTimestamp() + delay, onComplete, appState);
    VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    VerifyOrDie(mLibEvLoopP != nullptr);
    ev_timer_init(&timer->mLibEvTimer, &LayerImplSelect::HandleLibEvTimer, 1, 0);
    timer->mLibEvTimer.data = timer;
    auto t                  = Clock::Milliseconds64(delay).count();
    // Note: libev uses the time when events started processing as the "now" reference for relative timers,
    //   for efficiency reasons. This point in time is represented by ev_now().
    //   The real time is represented by ev_time().
    //   Without correction, this leads to timers firing a bit too early relative to the time StartTimer()
    //   is called. So the relative value passed to ev_timer_set() is adjusted (increased) here.
    // Note: Still, slightly early (and of course, late) firing timers are something the caller MUST be prepared for,
    //   because edge cases like system clock adjustments may cause them even with the correction applied here.
    ev_timer_set(&timer->mLibEvTimer, (static_cast<double>(t) / 1E3) + ev_time() - ev_now(mLibEvLoopP), 0.);
    (void) mTimerList.Add(timer);
    ev_timer_start(mLibEvLoopP, &timer->mLibEvTimer);
#else
    if (mTimerList.Add(timer) == timer)
    {
        // The new timer is the earliest, so the time until the next event has probably changed.
        Signal();
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::ExtendTimerTo(Clock::Timeout delay, TimerCompleteCallback onComplete, void * appState)
{
    VerifyOrReturnError(delay.count() > 0, CHIP_ERROR_INVALID_ARGUMENT);

    assertChipStackLockedByCurrentThread();

    Clock::Timeout remainingTime = mTimerList.GetRemainingTime(onComplete, appState);
    if (remainingTime.count() < delay.count())
    {
        // Just call StartTimer; it will invoke CancelTimer(), then start a new timer.  That handles
        // all the various "timer was about to fire" edge cases correctly too.
        return StartTimer(delay, onComplete, appState);
    }

    return CHIP_NO_ERROR;
}

bool LayerImplSelect::IsTimerActive(TimerCompleteCallback onComplete, void * appState)
{
    bool timerIsActive = (mTimerList.GetRemainingTime(onComplete, appState) > Clock::kZero);

    if (!timerIsActive)
    {
        // check if the timer is in the mExpiredTimers list about to be fired.
        for (TimerList::Node * timer = mExpiredTimers.Earliest(); timer != nullptr; timer = timer->mNextTimer)
        {
            if (timer->GetCallback().GetOnComplete() == onComplete && timer->GetCallback().GetAppState() == appState)
            {
                return true;
            }
        }
    }

    return timerIsActive;
}

Clock::Timeout LayerImplSelect::GetRemainingTime(TimerCompleteCallback onComplete, void * appState)
{
    return mTimerList.GetRemainingTime(onComplete, appState);
}

void LayerImplSelect::CancelTimer(TimerCompleteCallback onComplete, void * appState)
{
    assertChipStackLockedByCurrentThread();

    VerifyOrReturn(mLayerState.IsInitialized());

    TimerList::Node * timer = mTimerList.Remove(onComplete, appState);
    if (timer == nullptr)
    {
        // The timer was not in our "will fire in the future" list, but it might
        // be in the "we're about to fire these" chunk we already grabbed from
        // that list.  Check for it there too, and if found there we still want
        // to cancel it.
        timer = mExpiredTimers.Remove(onComplete, appState);
    }
    VerifyOrReturn(timer != nullptr);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    VerifyOrDie(mLibEvLoopP != nullptr);
    ev_timer_stop(mLibEvLoopP, &timer->mLibEvTimer);
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    mTimerPool.Release(timer);
#if !CHIP_SYSTEM_CONFIG_USE_LIBEV
    // LIBEV builds does not include an I/O wakeup thread, so must not call Signal().
    Signal();
#endif
}

CriticalFailure LayerImplSelect::ScheduleWork(TimerCompleteCallback onComplete, void * appState)
{
    assertChipStackLockedByCurrentThread();

    VerifyOrReturnError(mLayerState.IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    // schedule as timer with no delay, but do NOT cancel previous timers with same onComplete/appState!
    TimerList::Node * timer = mTimerPool.Create(*this, SystemClock().GetMonotonicTimestamp(), onComplete, appState);
    VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY);
    VerifyOrDie(mLibEvLoopP != nullptr);
    ev_timer_init(&timer->mLibEvTimer, &LayerImplSelect::HandleLibEvTimer, 1, 0);
    timer->mLibEvTimer.data = timer;
    auto t                  = Clock::Milliseconds64(0).count();
    ev_timer_set(&timer->mLibEvTimer, static_cast<double>(t) / 1E3, 0.);
    (void) mTimerList.Add(timer);
    ev_timer_start(mLibEvLoopP, &timer->mLibEvTimer);
#else
    // Ideally we would not use a timer here at all, but if we try to just
    // ScheduleLambda the lambda needs to capture the following:
    // 1) onComplete
    // 2) appState
    // 3) The `this` pointer, because onComplete needs to be passed a pointer to
    //    the System::Layer.
    //
    // On a 64-bit system that's 24 bytes, but lambdas passed to ScheduleLambda
    // are capped at CHIP_CONFIG_LAMBDA_EVENT_SIZE which is 16 bytes.
    //
    // So for now use a timer as a poor-man's closure that captures `this` and
    // onComplete and appState in a single pointer, so we fit inside the size
    // limit.
    //
    // TODO: We could do something here where we compile-time condition on the
    // sizes of things and use a direct ScheduleLambda if it would fit and this
    // setup otherwise.
    //
    // TODO: But also, unit tests seem to do SystemLayer::ScheduleWork without
    // actually running a useful event loop (in the PlatformManager sense),
    // which breaks if we use ScheduleLambda here, since that does rely on the
    // PlatformManager event loop. So for now, keep scheduling an expires-ASAP
    // timer, but just make sure we don't cancel existing timers with the same
    // callback and appState, so ScheduleWork invocations don't stomp on each
    // other.
    TimerList::Node * timer = mTimerPool.Create(*this, SystemClock().GetMonotonicTimestamp(), onComplete, appState);
    VerifyOrReturnError(timer != nullptr, CHIP_ERROR_NO_MEMORY);

    if (mTimerList.Add(timer) == timer)
    {
        // The new timer is the earliest, so the time until the next event has probably changed.
        Signal();
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    return CHIP_NO_ERROR;
}

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
CHIP_ERROR LayerImplSelect::StartWatchingSocket(int fd, SocketWatchToken * tokenOut)
{
    // Find a free slot.
    SocketWatch * watch = nullptr;
    for (auto & w : mSocketWatchPool)
    {
        if (w.mFD == fd)
        {
            // Already registered, return the existing token
            *tokenOut = reinterpret_cast<SocketWatchToken>(&w);
            return CHIP_NO_ERROR;
        }
        if ((w.mFD == kInvalidFd) && (watch == nullptr))
        {
            watch = &w;
        }
    }
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_ENDPOINT_POOL_FULL);

    watch->mFD = fd;
#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    ev_io_init(&watch->mIoWatcher, &LayerImplSelect::HandleLibEvIoWatcher, 0, 0);
    watch->mIoWatcher.data   = watch;
    watch->mLayerImplSelectP = this;
#endif

    *tokenOut = reinterpret_cast<SocketWatchToken>(watch);
    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::SetCallback(SocketWatchToken token, SocketWatchCallback callback, intptr_t data)
{
    SocketWatch * watch = reinterpret_cast<SocketWatch *>(token);
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    watch->mCallback     = callback;
    watch->mCallbackData = data;
    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::RequestCallbackOnPendingRead(SocketWatchToken token)
{
    SocketWatch * watch = reinterpret_cast<SocketWatch *>(token);
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    watch->mPendingIO.Set(SocketEventFlags::kRead);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    VerifyOrDie(mLibEvLoopP != nullptr);
    int evs = (watch->mPendingIO.Has(SocketEventFlags::kRead) ? EV_READ : 0) |
        (watch->mPendingIO.Has(SocketEventFlags::kWrite) ? EV_WRITE : 0);
    if (!ev_is_active(&watch->mIoWatcher))
    {
        // First time actually using that watch
        ev_io_set(&watch->mIoWatcher, watch->mFD, evs);
        ev_io_start(mLibEvLoopP, &watch->mIoWatcher);
    }
    else
    {
        // already active, just change flags
        // Note: changing flags only reliably works when the watcher is stopped
        ev_io_stop(mLibEvLoopP, &watch->mIoWatcher);
        ev_io_modify(&watch->mIoWatcher, evs);
        ev_io_start(mLibEvLoopP, &watch->mIoWatcher);
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::RequestCallbackOnPendingWrite(SocketWatchToken token)
{
    SocketWatch * watch = reinterpret_cast<SocketWatch *>(token);
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    watch->mPendingIO.Set(SocketEventFlags::kWrite);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    VerifyOrDie(mLibEvLoopP != nullptr);
    int evs = (watch->mPendingIO.Has(SocketEventFlags::kRead) ? EV_READ : 0) |
        (watch->mPendingIO.Has(SocketEventFlags::kWrite) ? EV_WRITE : 0);
    if (!ev_is_active(&watch->mIoWatcher))
    {
        // First time actually using that watch
        ev_io_set(&watch->mIoWatcher, watch->mFD, evs);
        ev_io_start(mLibEvLoopP, &watch->mIoWatcher);
    }
    else
    {
        // already active, just change flags
        // Note: changing flags only reliably works when the watcher is stopped
        ev_io_stop(mLibEvLoopP, &watch->mIoWatcher);
        ev_io_modify(&watch->mIoWatcher, evs);
        ev_io_start(mLibEvLoopP, &watch->mIoWatcher);
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::ClearCallbackOnPendingRead(SocketWatchToken token)
{
    SocketWatch * watch = reinterpret_cast<SocketWatch *>(token);
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    watch->mPendingIO.Clear(SocketEventFlags::kRead);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    if (ev_is_active(&watch->mIoWatcher) && watch->mPendingIO.Raw() == 0)
    {
        // all flags cleared now, stop watching
        ev_io_stop(mLibEvLoopP, &watch->mIoWatcher);
    }
#endif

    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::ClearCallbackOnPendingWrite(SocketWatchToken token)
{
    SocketWatch * watch = reinterpret_cast<SocketWatch *>(token);
    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    watch->mPendingIO.Clear(SocketEventFlags::kWrite);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    if (ev_is_active(&watch->mIoWatcher) && watch->mPendingIO.Raw() == 0)
    {
        // all flags cleared now, stop watching
        ev_io_stop(mLibEvLoopP, &watch->mIoWatcher);
    }
#endif

    return CHIP_NO_ERROR;
}

CHIP_ERROR LayerImplSelect::StopWatchingSocket(SocketWatchToken * tokenInOut)
{
    VerifyOrReturnError(tokenInOut != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

    SocketWatch * watch = reinterpret_cast<SocketWatch *>(*tokenInOut);
    *tokenInOut         = InvalidSocketWatchToken();

    VerifyOrReturnError(watch != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    VerifyOrReturnError(watch->mFD >= 0, CHIP_ERROR_INCORRECT_STATE);

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    watch->DisableAndClear();
#else
    watch->Clear();

    // Wake the thread calling select so that it stops selecting on the socket.
    Signal();
#endif

    return CHIP_NO_ERROR;
}

/**
 *  Set the read, write or exception bit flags for the specified socket based on its status in
 *  the corresponding file descriptor sets.
 *
 *  @param[in]    socket    The file descriptor for which the bit flags are being set.
 *
 *  @param[in]    readfds   A pointer to the set of readable file descriptors.
 *
 *  @param[in]    writefds  A pointer to the set of writable file descriptors.
 *
 *  @param[in]    exceptfds  A pointer to the set of file descriptors with errors.
 */
SocketEvents LayerImplSelect::SocketEventsFromFDs(int socket, const fd_set & readfds, const fd_set & writefds,
                                                  const fd_set & exceptfds)
{
    SocketEvents res;

    if (socket >= 0)
    {
        // POSIX does not define the fd_set parameter of FD_ISSET() as const, even though it isn't modified.
        if (FD_ISSET(socket, const_cast<fd_set *>(&readfds)))
            res.Set(SocketEventFlags::kRead);
        if (FD_ISSET(socket, const_cast<fd_set *>(&writefds)))
            res.Set(SocketEventFlags::kWrite);
        if (FD_ISSET(socket, const_cast<fd_set *>(&exceptfds)))
            res.Set(SocketEventFlags::kExcept);
    }

    return res;
}
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

enum : intptr_t
{
    kLoopHandlerInactive = 0, // default value for EventLoopHandler::mState
    kLoopHandlerPending,
    kLoopHandlerActive,
};

void LayerImplSelect::AddLoopHandler(EventLoopHandler & handler)
{
    // Add the handler as pending because this method can be called at any point
    // in a PrepareEvents() / WaitForEvents() / HandleEvents() sequence.
    // It will be marked active when we call PrepareEvents() on it for the first time.
    auto & state = LoopHandlerState(handler);
    VerifyOrDie(state == kLoopHandlerInactive);
    state = kLoopHandlerPending;
    mLoopHandlers.PushBack(&handler);
}

void LayerImplSelect::RemoveLoopHandler(EventLoopHandler & handler)
{
    mLoopHandlers.Remove(&handler);
    LoopHandlerState(handler) = kLoopHandlerInactive;
}

void LayerImplSelect::EventSourceAdd(EventSource * source)
{
    assertChipStackLockedByCurrentThread();
    if (mSources.Contains(source))
    {
        ChipLogDetail(DeviceLayer, "Warning: the EventSource is already added");
        return;
    }
    mSources.PushBack(source);
}

void LayerImplSelect::EventSourceRemove(EventSource * source)
{
    assertChipStackLockedByCurrentThread();
    if (mSources.Contains(source))
    {
        mSources.Remove(source);
    }
}

void LayerImplSelect::EventSourceClear()
{
    assertChipStackLockedByCurrentThread();
    mSources.Clear();
}

void LayerImplSelect::PrepareEvents()
{
    assertChipStackLockedByCurrentThread();

    const Clock::Timestamp currentTime = SystemClock().GetMonotonicTimestamp();
    Clock::Timestamp awakenTime        = currentTime + kDefaultMinSleepPeriod;

    TimerList::Node * timer = mTimerList.Earliest();
    if (timer)
    {
        awakenTime = std::min(awakenTime, timer->AwakenTime());
    }

    // Activate added EventLoopHandlers and call PrepareEvents on active handlers.
    auto loopIter = mLoopHandlers.begin();
    while (loopIter != mLoopHandlers.end())
    {
        auto & loop = *loopIter++; // advance before calling out, in case a list modification clobbers the `next` pointer
        switch (auto & state = LoopHandlerState(loop))
        {
        case kLoopHandlerPending:
            state = kLoopHandlerActive;
            [[fallthrough]];
        case kLoopHandlerActive:
            awakenTime = std::min(awakenTime, loop.PrepareEvents(currentTime));
            break;
        }
    }

    const Clock::Timestamp sleepTime = (awakenTime > currentTime) ? (awakenTime - currentTime) : Clock::kZero;
    Clock::ToTimeval(sleepTime, mNextTimeout);

    mMaxFd = -1;

    // NOLINTBEGIN(clang-analyzer-security.insecureAPI.bzero)
    //
    // NOTE: darwin uses bzero to clear out FD sets. This is not a security concern.
    FD_ZERO(&mSelected.mReadSet);
    FD_ZERO(&mSelected.mWriteSet);
    FD_ZERO(&mSelected.mErrorSet);
    // NOLINTEND(clang-analyzer-security.insecureAPI.bzero)

#if !CHIP_SYSTEM_CONFIG_USE_LIBEV
    FD_SET(mWakeEvent.GetReadFD(), &mSelected.mReadSet);
    mMaxFd = mWakeEvent.GetReadFD();
#endif

    for (auto & source : mSources)
    {
        source.PrepareEvents(mMaxFd, mSelected.mReadSet, mSelected.mWriteSet, mSelected.mErrorSet, mNextTimeout);
    }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    for (auto & w : mSocketWatchPool)
    {
        if (w.mFD != kInvalidFd)
        {
            if (mMaxFd < w.mFD)
            {
                mMaxFd = w.mFD;
            }
            if (w.mPendingIO.Has(SocketEventFlags::kRead))
            {
                FD_SET(w.mFD, &mSelected.mReadSet);
            }
            if (w.mPendingIO.Has(SocketEventFlags::kWrite))
            {
                FD_SET(w.mFD, &mSelected.mWriteSet);
            }
        }
    }
#endif
}

void LayerImplSelect::WaitForEvents()
{
    mSelectResult = select(mMaxFd + 1, &mSelected.mReadSet, &mSelected.mWriteSet, &mSelected.mErrorSet, &mNextTimeout);
}

void LayerImplSelect::HandleEvents()
{
    assertChipStackLockedByCurrentThread();

    if (!IsSelectResultValid())
    {
        VerifyOrReturn(errno != EINTR); // EINTR is not really an error (and we don't use it for signal handling)
        ChipLogError(DeviceLayer, "Select failed: %" CHIP_ERROR_FORMAT, CHIP_ERROR_POSIX(errno).Format());
        return;
    }

#if !CHIP_SYSTEM_CONFIG_USE_LIBEV
    if (mSelectResult > 0 && FD_ISSET(mWakeEvent.GetReadFD(), &mSelected.mReadSet))
    {
        mWakeEvent.Confirm();
    }
#endif

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    mHandleSelectThread = pthread_self();
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING

    // Obtain the list of currently expired timers. Any new timers added by timer callback are NOT handled on this pass,
    // since that could result in infinite handling of new timers blocking any other progress.
    VerifyOrDieWithMsg(mExpiredTimers.Empty(), DeviceLayer, "Re-entry into HandleEvents from a timer callback?");
    mExpiredTimers          = mTimerList.ExtractEarlier(Clock::Timeout(1) + SystemClock().GetMonotonicTimestamp());
    TimerList::Node * timer = nullptr;
    while ((timer = mExpiredTimers.PopEarliest()) != nullptr)
    {
        mTimerPool.Invoke(timer);
    }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
    // Process socket events, if any
    if (mSelectResult > 0)
    {
        for (auto & w : mSocketWatchPool)
        {
            if (w.mFD != kInvalidFd && w.mCallback != nullptr)
            {
                SocketEvents events = SocketEventsFromFDs(w.mFD, mSelected.mReadSet, mSelected.mWriteSet, mSelected.mErrorSet);
                if (events.HasAny())
                {
                    w.mCallback(events, w.mCallbackData);
                }
            }
        }
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

    if (mSelectResult >= 0)
    {
        for (auto & source : mSources)
        {
            source.ProcessEvents(mSelected.mReadSet, mSelected.mWriteSet, mSelected.mErrorSet);
        }
    }

    // Call HandleEvents for active loop handlers
    auto loopIter = mLoopHandlers.begin();
    while (loopIter != mLoopHandlers.end())
    {
        auto & loop = *loopIter++; // advance before calling out, in case a list modification clobbers the `next` pointer
        if (LoopHandlerState(loop) == kLoopHandlerActive)
        {
            loop.HandleEvents();
        }
    }

#if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
    mHandleSelectThread = PTHREAD_NULL;
#endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
}

#if CHIP_SYSTEM_CONFIG_USE_LIBEV

void LayerImplSelect::HandleLibEvTimer(EV_P_ struct ev_timer * t, int revents)
{
    TimerList::Node * timer = static_cast<TimerList::Node *>(t->data);
    VerifyOrDie(timer != nullptr);
    LayerImplSelect * layerP = dynamic_cast<LayerImplSelect *>(timer->mCallback.mSystemLayer);
    VerifyOrDie(layerP != nullptr);
    layerP->mTimerList.Remove(timer);
    layerP->mTimerPool.Invoke(timer);
}

void LayerImplSelect::HandleLibEvIoWatcher(EV_P_ struct ev_io * i, int revents)
{
    SocketWatch * watch = static_cast<SocketWatch *>(i->data);
    if (watch != nullptr && watch->mCallback != nullptr && watch->mLayerImplSelectP != nullptr)
    {
        SocketEvents events;
        if (revents & EV_READ)
        {
            events.Set(SocketEventFlags::kRead);
        }
        if (revents & EV_WRITE)
        {
            events.Set(SocketEventFlags::kWrite);
        }
        if (events.HasAny())
        {
            watch->mCallback(events, watch->mCallbackData);
        }
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
void LayerImplSelect::SocketWatch::Clear()
{
    mFD = kInvalidFd;
    mPendingIO.ClearAll();
    mCallback     = nullptr;
    mCallbackData = 0;
#if CHIP_SYSTEM_CONFIG_USE_LIBEV
    mLayerImplSelectP = nullptr;
#endif
}

#if CHIP_SYSTEM_CONFIG_USE_LIBEV
void LayerImplSelect::SocketWatch::DisableAndClear()
{
    if (mLayerImplSelectP != nullptr && mLayerImplSelectP->mLibEvLoopP != nullptr)
    {
        ev_io_stop(mLayerImplSelectP->mLibEvLoopP, &mIoWatcher);
    }
    Clear();
}
#endif // CHIP_SYSTEM_CONFIG_USE_LIBEV
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

} // namespace System
} // namespace chip
