summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Staats <estaats@google.com>2022-04-06 12:57:20 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-04-06 12:57:20 +0000
commitfb93d2f677bb2b4ca3384ada9d7a519e19228e8d (patch)
treeac491505b1efb8dbd98cbffc486c3ae573b79397
parente8e241d099d80ca48ca5473bc2bdbea366f3fbea (diff)
parent9b8bc0f7c1fd4565572a894d4f5380e9ae0905b9 (diff)
downloadlibhardware-fb93d2f677bb2b4ca3384ada9d7a519e19228e8d.tar.gz
dynamic_sensor: Support timing out sensor operations. am: 9b8bc0f7c1
Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/libhardware/+/17542700 Change-Id: I1569d6a89f8367de8acdd4863b78818bd2d29532 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.cpp85
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.h35
2 files changed, 100 insertions, 20 deletions
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
index be1a0044..efac5e95 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -87,7 +87,7 @@ int DynamicSensorManager::activate(int handle, bool enable) {
}
return operateSensor(handle,
- [&enable] (sp<BaseSensorObject> s)->int {
+ [=] (sp<BaseSensorObject> s)->int {
return s->enable(enable);
});
}
@@ -98,7 +98,7 @@ int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch
return 0;
}
return operateSensor(handle,
- [&sample_period, &batch_period] (sp<BaseSensorObject> s)->int {
+ [=] (sp<BaseSensorObject> s)->int {
return s->batch(sample_period, batch_period);
});
}
@@ -239,6 +239,87 @@ const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
return mMetaSensor;
}
+int DynamicSensorManager::operateSensor(
+ int handle, OperateSensorFunc sensorFunc) {
+ std::shared_future<int> sensorOp;
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+
+ // Invoke the function asynchronously.
+ sensorOp = std::async(
+ [this, handle = handle, sensorFunc = sensorFunc,
+ sensorOpIndex = mNextSensorOpIndex] ()->int {
+ return operateSensor(handle, sensorFunc, sensorOpIndex);
+ }).share();
+
+ // Add sensor operation to the queue.
+ mSensorOpQueue.push({mNextSensorOpIndex, sensorOp});
+ mNextSensorOpIndex++;
+ }
+
+ // Wait for the sensor operation to complete.
+ if (sensorOp.wait_for(kSensorOpTimeout) != std::future_status::ready) {
+ ALOGE("sensor operation timed out");
+ return TIMED_OUT;
+ }
+
+ return sensorOp.get();
+}
+
+int DynamicSensorManager::operateSensor(
+ int handle, OperateSensorFunc sensorFunc, uint64_t sensorOpIndex) {
+ int rv = 0;
+
+ // Wait until this sensor operation is at the head of the queue.
+ while (1) {
+ std::shared_future<int> headSensorOp;
+
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+
+ if (mSensorOpQueue.front().first == sensorOpIndex) {
+ break;
+ }
+ headSensorOp = mSensorOpQueue.front().second;
+ }
+ headSensorOp.wait();
+ }
+
+ // Perform sensor operation.
+ sp<BaseSensorObject> sensor;
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ const auto i = mMap.find(handle);
+ if (i == mMap.end()) {
+ rv = BAD_VALUE;
+ }
+ if (rv == 0) {
+ sensor = i->second.promote();
+ if (sensor == nullptr) {
+ // sensor object is already gone
+ rv = BAD_VALUE;
+ }
+ }
+ }
+ if (rv == 0) {
+ rv = sensorFunc(sensor);
+ }
+
+ // Remove sensor operation from queue. When the operation's shared state is
+ // destroyed, execution of this function ceases. Thus, if the state is
+ // destroyed when the operation is removed from the queue, the lock will
+ // never be released. To prevent that, the state is shared locally, so it
+ // isn't destroyed until this function completes.
+ std::shared_future<int> sensorOp;
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+ sensorOp = mSensorOpQueue.front().second;
+ mSensorOpQueue.pop();
+ }
+
+ return rv;
+}
+
DynamicSensorManager::ConnectionReport::ConnectionReport(
int handle, sp<BaseSensorObject> sensor) :
mSensor(*(sensor->getSensor())),
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
index 264582ec..b8a73203 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -22,7 +22,9 @@
#include <hardware/sensors.h>
#include <utils/RefBase.h>
+#include <future>
#include <mutex>
+#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
@@ -92,24 +94,13 @@ private:
// returns next available handle to use upon a new sensor connection, or -1 if we run out.
int getNextAvailableHandle();
- // TF: int foo(sp<BaseSensorObject> obj);
- template <typename TF>
- int operateSensor(int handle, TF f) const {
- sp<BaseSensorObject> s;
- {
- std::lock_guard<std::mutex> lk(mLock);
- const auto i = mMap.find(handle);
- if (i == mMap.end()) {
- return BAD_VALUE;
- }
- s = i->second.promote();
- if (s == nullptr) {
- // sensor object is already gone
- return BAD_VALUE;
- }
- }
- return f(s);
- }
+ // Runs a sensor function with a timeout. On timeout, function could still
+ // be running, so any function parameter or closure lifetimes should match
+ // the function's lifetime.
+ using OperateSensorFunc = std::function<int(sp<BaseSensorObject>)>;
+ int operateSensor(int handle, OperateSensorFunc sensorFunc);
+ int operateSensor(int handle, OperateSensorFunc sensorFunc,
+ uint64_t sensorOpIndex);
// available sensor handle space
const std::pair<int, int> mHandleRange;
@@ -133,6 +124,14 @@ private:
// daemons
std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector;
+
+ // Sensor operation queue. Calls to the sensor HAL must complete within 1
+ // second.
+ static constexpr std::chrono::milliseconds
+ kSensorOpTimeout = std::chrono::milliseconds(900);
+ std::mutex mSensorOpQueueLock;
+ std::queue<std::pair<uint64_t, std::shared_future<int>>> mSensorOpQueue;
+ uint64_t mNextSensorOpIndex = 0;
};
} // namespace SensorHalExt