Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68d6075b authored by Jeff Brown's avatar Jeff Brown Committed by Jeff Brown
Browse files

Refactor how timeouts are calculated. (DO NOT MERGE)

Added a timeout mechanism to EventHub and InputReader so that
InputMappers can request timeouts to perform delayed processing of
input when needed.

Change-Id: I89c1171c9326c6e413042e3ee13aa9f7f1fc0454
parent 5b2b4d9c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -88,6 +88,16 @@ nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
nsecs_t systemTime(int clock);
#endif // def __cplusplus

/**
 * Returns the number of milliseconds to wait between the reference time and the timeout time.
 * If the timeout is in the past relative to the reference time, returns 0.
 * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
 * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
 * Otherwise, returns the difference between the reference time and timeout time
 * rounded up to the next millisecond.
 */
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);

#ifdef __cplusplus
} // extern "C"
#endif
+7 −12
Original line number Diff line number Diff line
@@ -218,14 +218,10 @@ int Looper::pollInner(int timeoutMillis) {
    // Adjust the timeout based on when the next message is due.
    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
        if (mNextMessageUptime <= now) {
            timeoutMillis = 0;
        } else {
            uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL;
            if (delay < INT_MAX
                    && (timeoutMillis < 0 || int(delay) < timeoutMillis)) {
                timeoutMillis = int(delay);
            }
        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
        if (messageTimeoutMillis >= 0
                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
            timeoutMillis = messageTimeoutMillis;
        }
#if DEBUG_POLL_AND_WAKE
        LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
@@ -444,12 +440,11 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat
                return result;
            }

            nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
            if (timeoutNanos <= 0) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
            if (timeoutMillis == 0) {
                return ALOOPER_POLL_TIMEOUT;
            }

            timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL));
        }
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <limits.h>

#ifdef HAVE_WIN32_THREADS
#include <windows.h>
@@ -53,6 +54,23 @@ nsecs_t systemTime(int clock)
#endif
}

int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
{
    int timeoutDelayMillis;
    if (timeoutTime > referenceTime) {
        uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
        if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
            timeoutDelayMillis = -1;
        } else {
            timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
        }
    } else {
        timeoutDelayMillis = 0;
    }
    return timeoutDelayMillis;
}


/*
 * ===========================================================================
 *      DurationTimer
+10 −3
Original line number Diff line number Diff line
@@ -445,7 +445,7 @@ EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
    return NULL;
}

bool EventHub::getEvent(RawEvent* outEvent) {
bool EventHub::getEvent(int timeoutMillis, RawEvent* outEvent) {
    outEvent->deviceId = 0;
    outEvent->type = 0;
    outEvent->scanCode = 0;
@@ -598,13 +598,20 @@ bool EventHub::getEvent(RawEvent* outEvent) {
        // when this happens, the EventHub holds onto its own user wake lock while the client
        // is processing events.  Thus the system can only sleep if there are no events
        // pending or currently being processed.
        //
        // The timeout is advisory only.  If the device is asleep, it will not wake just to
        // service the timeout.
        release_wake_lock(WAKE_LOCK_ID);

        int pollResult = poll(mFds.editArray(), mFds.size(), -1);
        int pollResult = poll(mFds.editArray(), mFds.size(), timeoutMillis);

        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

        if (pollResult <= 0) {
        if (pollResult == 0) {
            // Timed out.
            return false;
        }
        if (pollResult < 0) {
            if (errno != EINTR) {
                LOGW("poll failed (errno=%d)\n", errno);
                usleep(100000);
+7 −2
Original line number Diff line number Diff line
@@ -186,8 +186,13 @@ public:
     * This ensures that the device will not go to sleep while the event is being processed.
     * If the device needs to remain awake longer than that, then the caller is responsible
     * for taking care of it (say, by poking the power manager user activity timer).
     *
     * The timeout is advisory only.  If the device is asleep, it will not wake just to
     * service the timeout.
     *
     * Returns true if an event was obtained, false if the timeout expired.
     */
    virtual bool getEvent(RawEvent* outEvent) = 0;
    virtual bool getEvent(int timeoutMillis, RawEvent* outEvent) = 0;

    /*
     * Query current input state.
@@ -244,7 +249,7 @@ public:
    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
            const int32_t* keyCodes, uint8_t* outFlags) const;

    virtual bool getEvent(RawEvent* outEvent);
    virtual bool getEvent(int timeoutMillis, RawEvent* outEvent);

    virtual bool hasLed(int32_t deviceId, int32_t led) const;
    virtual void setLedState(int32_t deviceId, int32_t led, bool on);
Loading