Merge "Fix a deadlock in emulator HAL implementation" into main
This commit is contained in:
commit
7d21c7df17
4 changed files with 35 additions and 17 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue