diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2021-02-04 19:59:33 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2021-02-04 19:59:33 +0000 |
commit | 5740dbf75f937c4fa9c21fc36c0b5ab868a087f8 (patch) | |
tree | 2b33869ab55bd85fc7e55a3b46caace23eae7a93 | |
parent | dadb9d9200b4db8a96298a560bdc392bf2605e6c (diff) | |
parent | a139ea4e475f8f2d7c8c2ebc90f5f7cf4175c39e (diff) | |
download | interfaces-android11-mainline-media-release.tar.gz |
Snap for 7124398 from a139ea4e475f8f2d7c8c2ebc90f5f7cf4175c39e to mainline-media-releaseandroid-mainline-11.0.0_r39android-mainline-11.0.0_r32android-mainline-11.0.0_r16android11-mainline-media-release
Change-Id: I1c831fc55fa2af6939da77fbdc34c41129472b0c
-rw-r--r-- | sensorservice/libsensorndkbridge/ALooper.cpp | 14 | ||||
-rw-r--r-- | sensorservice/libsensorndkbridge/ALooper.h | 7 | ||||
-rw-r--r-- | sensorservice/libsensorndkbridge/ASensorEventQueue.cpp | 33 | ||||
-rw-r--r-- | sensorservice/libsensorndkbridge/ASensorEventQueue.h | 2 | ||||
-rw-r--r-- | sensorservice/libsensorndkbridge/ASensorManager.h | 2 |
5 files changed, 46 insertions, 12 deletions
diff --git a/sensorservice/libsensorndkbridge/ALooper.cpp b/sensorservice/libsensorndkbridge/ALooper.cpp index 9930ad4..d3ddbff 100644 --- a/sensorservice/libsensorndkbridge/ALooper.cpp +++ b/sensorservice/libsensorndkbridge/ALooper.cpp @@ -23,12 +23,14 @@ #include <android-base/logging.h> using android::Mutex; +using android::sp; +using android::wp; ALooper::ALooper() : mAwoken(false) { } -void ALooper::signalSensorEvents(ASensorEventQueue *queue) { +void ALooper::signalSensorEvents(wp<ASensorEventQueue> queue) { Mutex::Autolock autoLock(mLock); mReadyQueues.insert(queue); mCondition.signal(); @@ -71,8 +73,11 @@ int ALooper::pollOnce( if (!mReadyQueues.empty()) { result = ALOOPER_POLL_CALLBACK; - for (auto queue : mReadyQueues) { - queue->dispatchCallback(); + for (auto& queue : mReadyQueues) { + sp<ASensorEventQueue> promotedQueue = queue.promote(); + if (promotedQueue != nullptr) { + promotedQueue->dispatchCallback(); + } } mReadyQueues.clear(); @@ -86,8 +91,7 @@ int ALooper::pollOnce( return result; } -void ALooper::invalidateSensorQueue(ASensorEventQueue *queue) { +void ALooper::invalidateSensorQueue(wp<ASensorEventQueue> queue) { Mutex::Autolock autoLock(mLock); mReadyQueues.erase(queue); } - diff --git a/sensorservice/libsensorndkbridge/ALooper.h b/sensorservice/libsensorndkbridge/ALooper.h index 601eca9..aa14e03 100644 --- a/sensorservice/libsensorndkbridge/ALooper.h +++ b/sensorservice/libsensorndkbridge/ALooper.h @@ -21,6 +21,7 @@ #include <android-base/macros.h> #include <utils/Condition.h> #include <utils/Mutex.h> +#include <utils/RefBase.h> #include <set> @@ -29,18 +30,18 @@ struct ASensorEventQueue; struct ALooper { ALooper(); - void signalSensorEvents(ASensorEventQueue *queue); + void signalSensorEvents(android::wp<ASensorEventQueue> queue); void wake(); int pollOnce(int timeoutMillis, int *outFd, int *outEvents, void **outData); - void invalidateSensorQueue(ASensorEventQueue *queue); + void invalidateSensorQueue(android::wp<ASensorEventQueue> queue); private: android::Mutex mLock; android::Condition mCondition; - std::set<ASensorEventQueue *> mReadyQueues; + std::set<android::wp<ASensorEventQueue>> mReadyQueues; bool mAwoken; DISALLOW_COPY_AND_ASSIGN(ALooper); diff --git a/sensorservice/libsensorndkbridge/ASensorEventQueue.cpp b/sensorservice/libsensorndkbridge/ASensorEventQueue.cpp index d109426..bf24f68 100644 --- a/sensorservice/libsensorndkbridge/ASensorEventQueue.cpp +++ b/sensorservice/libsensorndkbridge/ASensorEventQueue.cpp @@ -30,7 +30,11 @@ using android::Mutex; using android::hardware::Return; ASensorEventQueue::ASensorEventQueue(ALooper* looper, ALooper_callbackFunc callback, void* data) - : mLooper(looper), mCallback(callback), mData(data), mRequestAdditionalInfo(false) {} + : mLooper(looper), + mCallback(callback), + mData(data), + mRequestAdditionalInfo(false), + mValid(true) {} void ASensorEventQueue::setImpl(const sp<IEventQueue> &queueImpl) { mQueueImpl = queueImpl; @@ -106,17 +110,31 @@ Return<void> ASensorEventQueue::onEvent(const Event &event) { LOG(VERBOSE) << "ASensorEventQueue::onEvent"; if (static_cast<int32_t>(event.sensorType) != ASENSOR_TYPE_ADDITIONAL_INFO || - mRequestAdditionalInfo.load()) { + mRequestAdditionalInfo.load()) { + { + // Only lock the mutex in this block to avoid the following deadlock scenario: + // + // ASensorEventQueue::onEvent is called which grabs ASensorEventQueue::mLock followed + // by ALooper::mLock via ALooper::signalSensorEvents. + // + // Meanwhile + // + // ASensorEventQueue::dispatchCallback is invoked from ALooper::pollOnce which has + // has ALooper::mLock locked and the dispatched callback invokes + // ASensorEventQueue::getEvents which would try to grab ASensorEventQueue::mLock + // resulting in a deadlock. Mutex::Autolock autoLock(mLock); - mQueue.emplace_back(); sensors_event_t* sensorEvent = &mQueue[mQueue.size() - 1]; android::hardware::sensors::V1_0::implementation::convertToSensorEvent(event, sensorEvent); } - mLooper->signalSensorEvents(this); + Mutex::Autolock autoLock(mValidLock); + if (mValid) { + mLooper->signalSensorEvents(this); + } } return android::hardware::Void(); @@ -134,6 +152,13 @@ void ASensorEventQueue::dispatchCallback() { } void ASensorEventQueue::invalidate() { + { + // Only lock within this context to avoid locking while calling invalidateSensorQueue which + // also holds a lock. This is safe to do because mValid can't be made true after it's false + // so onEvent will never signal new sensor events after mValid is false. + Mutex::Autolock autoLock(mValidLock); + mValid = false; + } mLooper->invalidateSensorQueue(this); setImpl(nullptr); } diff --git a/sensorservice/libsensorndkbridge/ASensorEventQueue.h b/sensorservice/libsensorndkbridge/ASensorEventQueue.h index 4937276..7139d34 100644 --- a/sensorservice/libsensorndkbridge/ASensorEventQueue.h +++ b/sensorservice/libsensorndkbridge/ASensorEventQueue.h @@ -73,6 +73,8 @@ private: std::vector<sensors_event_t> mQueue; std::atomic_bool mRequestAdditionalInfo; + android::Mutex mValidLock; + bool mValid; DISALLOW_COPY_AND_ASSIGN(ASensorEventQueue); }; diff --git a/sensorservice/libsensorndkbridge/ASensorManager.h b/sensorservice/libsensorndkbridge/ASensorManager.h index 818429d..4e91122 100644 --- a/sensorservice/libsensorndkbridge/ASensorManager.h +++ b/sensorservice/libsensorndkbridge/ASensorManager.h @@ -44,6 +44,8 @@ struct ASensorManager { ALooper_callbackFunc callback, void *data); + // This must not be called from inside ALooper_callbackFunc to avoid deadlocking inside of the + // ALooper. void destroyEventQueue(ASensorEventQueue *queue); private: |