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

Commit 8456f175 authored by Leon Scroggins's avatar Leon Scroggins Committed by Automerger Merge Worker
Browse files

Merge changes from topic "VSyncDispatch_unregisterCallback" into udc-dev am: 6b567cad

parents de8285ea 6b567cad
Loading
Loading
Loading
Loading
+13 −3
Original line number Original line Diff line number Diff line
@@ -692,17 +692,27 @@ const char* EventThread::toCString(State state) {
}
}


void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) {
void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) {
    // Hold onto the old registration until after releasing the mutex to avoid deadlock.
    scheduler::VSyncCallbackRegistration oldRegistration =
            onNewVsyncScheduleInternal(std::move(schedule));
}

scheduler::VSyncCallbackRegistration EventThread::onNewVsyncScheduleInternal(
        std::shared_ptr<scheduler::VsyncSchedule> schedule) {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled;
    const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled;
    mVsyncSchedule = std::move(schedule);
    mVsyncSchedule = std::move(schedule);
    mVsyncRegistration =
    auto oldRegistration =
            std::exchange(mVsyncRegistration,
                          scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(),
                          scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(),
                                                 createDispatchCallback(), mThreadName);
                                                               createDispatchCallback(),
                                                               mThreadName));
    if (reschedule) {
    if (reschedule) {
        mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
        mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
                                     .readyDuration = mReadyDuration.count(),
                                     .readyDuration = mReadyDuration.count(),
                                     .earliestVsync = mLastVsyncCallbackTime.ns()});
                                     .earliestVsync = mLastVsyncCallbackTime.ns()});
    }
    }
    return oldRegistration;
}
}


scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
+6 −1
Original line number Original line Diff line number Diff line
@@ -174,7 +174,7 @@ public:


    size_t getEventThreadConnectionCount() override;
    size_t getEventThreadConnectionCount() override;


    void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override;
    void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex);


private:
private:
    friend EventThreadTest;
    friend EventThreadTest;
@@ -201,6 +201,11 @@ private:


    scheduler::VSyncDispatch::Callback createDispatchCallback();
    scheduler::VSyncDispatch::Callback createDispatchCallback();


    // Returns the old registration so it can be destructed outside the lock to
    // avoid deadlock.
    scheduler::VSyncCallbackRegistration onNewVsyncScheduleInternal(
            std::shared_ptr<scheduler::VsyncSchedule>) EXCLUDES(mMutex);

    const char* const mThreadName;
    const char* const mThreadName;
    TracedOrdinal<int> mVsyncTracer;
    TracedOrdinal<int> mVsyncTracer;
    TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
    TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
+3 −6
Original line number Original line Diff line number Diff line
@@ -155,10 +155,6 @@ protected:
    VSyncDispatch& operator=(const VSyncDispatch&) = delete;
    VSyncDispatch& operator=(const VSyncDispatch&) = delete;
};
};


/*
 * Helper class to operate on registered callbacks. It is up to user of the class to ensure
 * that VsyncDispatch lifetime exceeds the lifetime of VSyncCallbackRegistation.
 */
class VSyncCallbackRegistration {
class VSyncCallbackRegistration {
public:
public:
    VSyncCallbackRegistration(std::shared_ptr<VSyncDispatch>, VSyncDispatch::Callback,
    VSyncCallbackRegistration(std::shared_ptr<VSyncDispatch>, VSyncDispatch::Callback,
@@ -178,9 +174,10 @@ public:
    CancelResult cancel();
    CancelResult cancel();


private:
private:
    friend class VSyncCallbackRegistrationTest;

    std::shared_ptr<VSyncDispatch> mDispatch;
    std::shared_ptr<VSyncDispatch> mDispatch;
    VSyncDispatch::CallbackToken mToken;
    std::optional<VSyncDispatch::CallbackToken> mToken;
    bool mValidToken;
};
};


} // namespace android::scheduler
} // namespace android::scheduler
+22 −17
Original line number Original line Diff line number Diff line
@@ -21,12 +21,16 @@
#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <ftl/concat.h>
#include <ftl/concat.h>
#include <utils/Trace.h>
#include <utils/Trace.h>
#include <log/log_main.h>


#include <scheduler/TimeKeeper.h>
#include <scheduler/TimeKeeper.h>


#include "VSyncDispatchTimerQueue.h"
#include "VSyncDispatchTimerQueue.h"
#include "VSyncTracker.h"
#include "VSyncTracker.h"


#undef LOG_TAG
#define LOG_TAG "VSyncDispatch"

namespace android::scheduler {
namespace android::scheduler {


using base::StringAppendF;
using base::StringAppendF;
@@ -225,6 +229,10 @@ VSyncDispatchTimerQueue::VSyncDispatchTimerQueue(std::unique_ptr<TimeKeeper> tk,
VSyncDispatchTimerQueue::~VSyncDispatchTimerQueue() {
VSyncDispatchTimerQueue::~VSyncDispatchTimerQueue() {
    std::lock_guard lock(mMutex);
    std::lock_guard lock(mMutex);
    cancelTimer();
    cancelTimer();
    for (auto& [_, entry] : mCallbacks) {
        ALOGE("Forgot to unregister a callback on VSyncDispatch!");
        entry->ensureNotRunning();
    }
}
}


void VSyncDispatchTimerQueue::cancelTimer() {
void VSyncDispatchTimerQueue::cancelTimer() {
@@ -438,47 +446,44 @@ VSyncCallbackRegistration::VSyncCallbackRegistration(std::shared_ptr<VSyncDispat
                                                     VSyncDispatch::Callback callback,
                                                     VSyncDispatch::Callback callback,
                                                     std::string callbackName)
                                                     std::string callbackName)
      : mDispatch(std::move(dispatch)),
      : mDispatch(std::move(dispatch)),
        mToken(mDispatch->registerCallback(std::move(callback), std::move(callbackName))),
        mToken(mDispatch->registerCallback(std::move(callback), std::move(callbackName))) {}
        mValidToken(true) {}


VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncCallbackRegistration&& other)
VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncCallbackRegistration&& other)
      : mDispatch(std::move(other.mDispatch)),
      : mDispatch(std::move(other.mDispatch)), mToken(std::exchange(other.mToken, std::nullopt)) {}
        mToken(std::move(other.mToken)),
        mValidToken(std::move(other.mValidToken)) {
    other.mValidToken = false;
}


VSyncCallbackRegistration& VSyncCallbackRegistration::operator=(VSyncCallbackRegistration&& other) {
VSyncCallbackRegistration& VSyncCallbackRegistration::operator=(VSyncCallbackRegistration&& other) {
    if (this == &other) return *this;
    if (mToken) {
        mDispatch->unregisterCallback(*mToken);
    }
    mDispatch = std::move(other.mDispatch);
    mDispatch = std::move(other.mDispatch);
    mToken = std::move(other.mToken);
    mToken = std::exchange(other.mToken, std::nullopt);
    mValidToken = std::move(other.mValidToken);
    other.mValidToken = false;
    return *this;
    return *this;
}
}


VSyncCallbackRegistration::~VSyncCallbackRegistration() {
VSyncCallbackRegistration::~VSyncCallbackRegistration() {
    if (mValidToken) mDispatch->unregisterCallback(mToken);
    if (mToken) mDispatch->unregisterCallback(*mToken);
}
}


ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
    if (!mValidToken) {
    if (!mToken) {
        return std::nullopt;
        return std::nullopt;
    }
    }
    return mDispatch->schedule(mToken, scheduleTiming);
    return mDispatch->schedule(*mToken, scheduleTiming);
}
}


ScheduleResult VSyncCallbackRegistration::update(VSyncDispatch::ScheduleTiming scheduleTiming) {
ScheduleResult VSyncCallbackRegistration::update(VSyncDispatch::ScheduleTiming scheduleTiming) {
    if (!mValidToken) {
    if (!mToken) {
        return std::nullopt;
        return std::nullopt;
    }
    }
    return mDispatch->update(mToken, scheduleTiming);
    return mDispatch->update(*mToken, scheduleTiming);
}
}


CancelResult VSyncCallbackRegistration::cancel() {
CancelResult VSyncCallbackRegistration::cancel() {
    if (!mValidToken) {
    if (!mToken) {
        return CancelResult::Error;
        return CancelResult::Error;
    }
    }
    return mDispatch->cancel(mToken);
    return mDispatch->cancel(*mToken);
}
}


} // namespace android::scheduler
} // namespace android::scheduler
+1 −0
Original line number Original line Diff line number Diff line
@@ -128,6 +128,7 @@ cc_test {
        "TransactionTracingTest.cpp",
        "TransactionTracingTest.cpp",
        "TunnelModeEnabledReporterTest.cpp",
        "TunnelModeEnabledReporterTest.cpp",
        "StrongTypingTest.cpp",
        "StrongTypingTest.cpp",
        "VSyncCallbackRegistrationTest.cpp",
        "VSyncDispatchTimerQueueTest.cpp",
        "VSyncDispatchTimerQueueTest.cpp",
        "VSyncDispatchRealtimeTest.cpp",
        "VSyncDispatchRealtimeTest.cpp",
        "VsyncModulatorTest.cpp",
        "VsyncModulatorTest.cpp",
Loading