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

Commit 7d21c7df authored by Yu-Han Yang's avatar Yu-Han Yang Committed by Android (Google) Code Review
Browse files

Merge "Fix a deadlock in emulator HAL implementation" into main

parents 6e63f314 e28dd790
Loading
Loading
Loading
Loading
+17 −8
Original line number Original line Diff line number Diff line
@@ -35,7 +35,9 @@ using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;


GnssMeasurementInterface::GnssMeasurementInterface()
GnssMeasurementInterface::GnssMeasurementInterface()
    : mIntervalMs(1000), mLocationIntervalMs(1000), mFutures(std::vector<std::future<void>>()) {}
    : mIntervalMs(1000), mLocationIntervalMs(1000) {
    mThreads.reserve(2);
}


GnssMeasurementInterface::~GnssMeasurementInterface() {
GnssMeasurementInterface::~GnssMeasurementInterface() {
    waitForStoppingThreads();
    waitForStoppingThreads();
@@ -100,12 +102,12 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
        ALOGD("restarting since measurement has started");
        ALOGD("restarting since measurement has started");
        stop();
        stop();
    }
    }
    // Wait for stopping previous thread.
    waitForStoppingThreads();


    mIsActive = true;
    mIsActive = true;
    mThreads.emplace_back(std::thread([this, enableCorrVecOutputs, enableFullTracking]() {
        waitForStoppingThreads();
        mThreadBlocker.reset();
        mThreadBlocker.reset();
    mThread = std::thread([this, enableCorrVecOutputs, enableFullTracking]() {

        int intervalMs;
        int intervalMs;
        do {
        do {
            if (!mIsActive) {
            if (!mIsActive) {
@@ -134,15 +136,22 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
            intervalMs =
            intervalMs =
                    (mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
                    (mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
        } while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(intervalMs)));
        } while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(intervalMs)));
    });
    }));
}
}


void GnssMeasurementInterface::stop() {
void GnssMeasurementInterface::stop() {
    ALOGD("stop");
    ALOGD("stop");
    mIsActive = false;
    mIsActive = false;
    mThreadBlocker.notify();
    mThreadBlocker.notify();
    if (mThread.joinable()) {
    for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
        mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
        if (iter->joinable()) {
            mFutures.push_back(std::async(std::launch::async, [this, iter] {
                iter->join();
                mThreads.erase(iter);
            }));
        } else {
            mThreads.erase(iter);
        }
    }
    }
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
    std::atomic<long> mLocationIntervalMs;
    std::atomic<long> mLocationIntervalMs;
    std::atomic<bool> mIsActive;
    std::atomic<bool> mIsActive;
    std::atomic<bool> mLocationEnabled;
    std::atomic<bool> mLocationEnabled;
    std::thread mThread;
    std::vector<std::thread> mThreads;
    std::vector<std::future<void>> mFutures;
    std::vector<std::future<void>> mFutures;
    ::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
    ::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;


+16 −7
Original line number Original line Diff line number Diff line
@@ -29,7 +29,9 @@ using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageTy


std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;


GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {
    mThreads.reserve(2);
}


GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
    waitForStoppingThreads();
    waitForStoppingThreads();
@@ -61,11 +63,11 @@ void GnssNavigationMessageInterface::start() {
        ALOGD("restarting since nav msg has started");
        ALOGD("restarting since nav msg has started");
        stop();
        stop();
    }
    }
    // Wait for stopping previous thread.
    waitForStoppingThreads();


    mIsActive = true;
    mIsActive = true;
    mThread = std::thread([this]() {
    mThreads.emplace_back(std::thread([this]() {
        waitForStoppingThreads();
        mThreadBlocker.reset();
        do {
        do {
            if (!mIsActive) {
            if (!mIsActive) {
                break;
                break;
@@ -81,15 +83,22 @@ void GnssNavigationMessageInterface::start() {
            this->reportMessage(message);
            this->reportMessage(message);
        } while (mIsActive &&
        } while (mIsActive &&
                 mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMillis)));
                 mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMillis)));
    });
    }));
}
}


void GnssNavigationMessageInterface::stop() {
void GnssNavigationMessageInterface::stop() {
    ALOGD("stop");
    ALOGD("stop");
    mIsActive = false;
    mIsActive = false;
    mThreadBlocker.notify();
    mThreadBlocker.notify();
    if (mThread.joinable()) {
    for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
        mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
        if (iter->joinable()) {
            mFutures.push_back(std::async(std::launch::async, [this, iter] {
                iter->join();
                mThreads.erase(iter);
            }));
        } else {
            mThreads.erase(iter);
        }
    }
    }
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -40,7 +40,7 @@ struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface


    std::atomic<long> mMinIntervalMillis;
    std::atomic<long> mMinIntervalMillis;
    std::atomic<bool> mIsActive;
    std::atomic<bool> mIsActive;
    std::thread mThread;
    std::vector<std::thread> mThreads;
    std::vector<std::future<void>> mFutures;
    std::vector<std::future<void>> mFutures;
    ::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
    ::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;