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

This commit is contained in:
Yu-Han Yang 2023-10-24 16:26:36 +00:00 committed by Android (Google) Code Review
commit 7d21c7df17
4 changed files with 35 additions and 17 deletions

View file

@ -35,7 +35,9 @@ using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
GnssMeasurementInterface::GnssMeasurementInterface()
: mIntervalMs(1000), mLocationIntervalMs(1000), mFutures(std::vector<std::future<void>>()) {}
: mIntervalMs(1000), mLocationIntervalMs(1000) {
mThreads.reserve(2);
}
GnssMeasurementInterface::~GnssMeasurementInterface() {
waitForStoppingThreads();
@ -100,12 +102,12 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
ALOGD("restarting since measurement has started");
stop();
}
// Wait for stopping previous thread.
waitForStoppingThreads();
mIsActive = true;
mThreadBlocker.reset();
mThread = std::thread([this, enableCorrVecOutputs, enableFullTracking]() {
mThreads.emplace_back(std::thread([this, enableCorrVecOutputs, enableFullTracking]() {
waitForStoppingThreads();
mThreadBlocker.reset();
int intervalMs;
do {
if (!mIsActive) {
@ -134,15 +136,22 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
intervalMs =
(mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
} while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(intervalMs)));
});
}));
}
void GnssMeasurementInterface::stop() {
ALOGD("stop");
mIsActive = false;
mThreadBlocker.notify();
if (mThread.joinable()) {
mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
if (iter->joinable()) {
mFutures.push_back(std::async(std::launch::async, [this, iter] {
iter->join();
mThreads.erase(iter);
}));
} else {
mThreads.erase(iter);
}
}
}

View file

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

View file

@ -29,7 +29,9 @@ using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageTy
std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {
mThreads.reserve(2);
}
GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
waitForStoppingThreads();
@ -61,11 +63,11 @@ void GnssNavigationMessageInterface::start() {
ALOGD("restarting since nav msg has started");
stop();
}
// Wait for stopping previous thread.
waitForStoppingThreads();
mIsActive = true;
mThread = std::thread([this]() {
mThreads.emplace_back(std::thread([this]() {
waitForStoppingThreads();
mThreadBlocker.reset();
do {
if (!mIsActive) {
break;
@ -81,15 +83,22 @@ void GnssNavigationMessageInterface::start() {
this->reportMessage(message);
} while (mIsActive &&
mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMillis)));
});
}));
}
void GnssNavigationMessageInterface::stop() {
ALOGD("stop");
mIsActive = false;
mThreadBlocker.notify();
if (mThread.joinable()) {
mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
if (iter->joinable()) {
mFutures.push_back(std::async(std::launch::async, [this, iter] {
iter->join();
mThreads.erase(iter);
}));
} else {
mThreads.erase(iter);
}
}
}

View file

@ -40,7 +40,7 @@ struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface
std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive;
std::thread mThread;
std::vector<std::thread> mThreads;
std::vector<std::future<void>> mFutures;
::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;