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

Commit 1a948dde authored by Lais Andrade's avatar Lais Andrade Committed by Android (Google) Code Review
Browse files

Merge "Fix flaky VibratorCallbackSchedulerTest" into main

parents d7f3f3a2 261ce7a3
Loading
Loading
Loading
Loading
+8 −3
Original line number Original line Diff line number Diff line
@@ -29,8 +29,11 @@ bool DelayedCallback::isExpired() const {
    return mExpiration <= std::chrono::steady_clock::now();
    return mExpiration <= std::chrono::steady_clock::now();
}
}


DelayedCallback::Timestamp DelayedCallback::getExpiration() const {
std::chrono::milliseconds DelayedCallback::getWaitForExpirationDuration() const {
    return mExpiration;
    std::chrono::milliseconds delta = std::chrono::duration_cast<std::chrono::milliseconds>(
            mExpiration - std::chrono::steady_clock::now());
    // Return zero if this is already expired.
    return delta > delta.zero() ? delta : delta.zero();
}
}


void DelayedCallback::run() const {
void DelayedCallback::run() const {
@@ -88,7 +91,9 @@ void CallbackScheduler::loop() {
            mCondition.wait(mMutex);
            mCondition.wait(mMutex);
        } else {
        } else {
            // Wait until next callback expires, or a new one is scheduled.
            // Wait until next callback expires, or a new one is scheduled.
            mCondition.wait_until(mMutex, mQueue.top().getExpiration());
            // Use the monotonic steady clock to wait for the measured delay interval via wait_for
            // instead of using a wall clock via wait_until.
            mCondition.wait_for(mMutex, mQueue.top().getWaitForExpirationDuration());
        }
        }
    }
    }
}
}
+4 −4
Original line number Original line Diff line number Diff line
@@ -30,15 +30,13 @@ namespace vibrator {
// Wrapper for a callback to be executed after a delay.
// Wrapper for a callback to be executed after a delay.
class DelayedCallback {
class DelayedCallback {
public:
public:
    using Timestamp = std::chrono::time_point<std::chrono::steady_clock>;

    DelayedCallback(std::function<void()> callback, std::chrono::milliseconds delay)
    DelayedCallback(std::function<void()> callback, std::chrono::milliseconds delay)
          : mCallback(callback), mExpiration(std::chrono::steady_clock::now() + delay) {}
          : mCallback(callback), mExpiration(std::chrono::steady_clock::now() + delay) {}
    ~DelayedCallback() = default;
    ~DelayedCallback() = default;


    void run() const;
    void run() const;
    bool isExpired() const;
    bool isExpired() const;
    Timestamp getExpiration() const;
    std::chrono::milliseconds getWaitForExpirationDuration() const;


    // Compare by expiration time, where A < B when A expires first.
    // Compare by expiration time, where A < B when A expires first.
    bool operator<(const DelayedCallback& other) const;
    bool operator<(const DelayedCallback& other) const;
@@ -46,7 +44,9 @@ public:


private:
private:
    std::function<void()> mCallback;
    std::function<void()> mCallback;
    Timestamp mExpiration;
    // Use a steady monotonic clock to calculate the duration until expiration.
    // This clock is not related to wall clock time and is most suitable for measuring intervals.
    std::chrono::time_point<std::chrono::steady_clock> mExpiration;
};
};


// Schedules callbacks to be executed after a delay.
// Schedules callbacks to be executed after a delay.
+9 −3
Original line number Original line Diff line number Diff line
@@ -71,15 +71,21 @@ protected:
    }
    }


    int32_t waitForCallbacks(int32_t callbackCount, milliseconds timeout) {
    int32_t waitForCallbacks(int32_t callbackCount, milliseconds timeout) {
        time_point<steady_clock> expiration = steady_clock::now() + timeout + TEST_TIMEOUT;
        time_point<steady_clock> expirationTime = steady_clock::now() + timeout + TEST_TIMEOUT;
        int32_t expiredCallbackCount = 0;
        int32_t expiredCallbackCount = 0;
        while (steady_clock::now() < expiration) {
        while (steady_clock::now() < expirationTime) {
            std::lock_guard<std::mutex> lock(mMutex);
            std::lock_guard<std::mutex> lock(mMutex);
            expiredCallbackCount = mExpiredCallbacks.size();
            expiredCallbackCount = mExpiredCallbacks.size();
            if (callbackCount <= expiredCallbackCount) {
            if (callbackCount <= expiredCallbackCount) {
                return expiredCallbackCount;
                return expiredCallbackCount;
            }
            }
            mCondition.wait_until(mMutex, expiration);
            auto currentTimeout = std::chrono::duration_cast<std::chrono::milliseconds>(
                    expirationTime - steady_clock::now());
            if (currentTimeout > currentTimeout.zero()) {
                // Use the monotonic steady clock to wait for the requested timeout via wait_for
                // instead of using a wall clock via wait_until.
                mCondition.wait_for(mMutex, currentTimeout);
            }
        }
        }
        return expiredCallbackCount;
        return expiredCallbackCount;
    }
    }