summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2021-02-04 19:59:33 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2021-02-04 19:59:33 +0000
commit5740dbf75f937c4fa9c21fc36c0b5ab868a087f8 (patch)
tree2b33869ab55bd85fc7e55a3b46caace23eae7a93
parentdadb9d9200b4db8a96298a560bdc392bf2605e6c (diff)
parenta139ea4e475f8f2d7c8c2ebc90f5f7cf4175c39e (diff)
downloadinterfaces-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.cpp14
-rw-r--r--sensorservice/libsensorndkbridge/ALooper.h7
-rw-r--r--sensorservice/libsensorndkbridge/ASensorEventQueue.cpp33
-rw-r--r--sensorservice/libsensorndkbridge/ASensorEventQueue.h2
-rw-r--r--sensorservice/libsensorndkbridge/ASensorManager.h2
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: