summaryrefslogtreecommitdiff
path: root/sensors/1.0/default/Sensors.cpp
diff options
context:
space:
mode:
authorPeng Xu <pengxu@google.com>2017-03-02 13:36:45 -0800
committerAshutosh Joshi <ashutoshj@google.com>2017-03-02 16:14:57 -0800
commitab7884fcbdee7b419399d71ae302a50c6fa87c84 (patch)
treea4b0abcba40b69c6399f5833421064cb24ee0682 /sensors/1.0/default/Sensors.cpp
parent2c5e21c69c931a90dcb9b4ea893157be17eaf8d5 (diff)
Prevent framework from stucking at communicating with HIDL HAL
Sensor hidl service has two threads quota. One is used for sending commands down to hardware, and the other for retrieving sensor events from hardware. The second is usually blocked on poll(). When system server quits abnormaly, the poll thread may still be blocked in HAL implementation and holding that thread. There won't be enough available threads for framework sensor service to function correctly when system service restarts, resulting in a deadlock at enableSensor() or getService() until the hidl service is restarted. This fix detects a second connection from framework sensor service and kills the hidl service in case that happens. The system will restart the hidl service with clean state and return system to normal operation. Bug: 35727090 Bug: 35843387 Bug: 35702298 Bug: 35919167 Bug: 35848670 Bug: 35903635 Test: Restart device works in normal case. Restart also works with the following scenario (reproducing error) "adb root && adb shell dumpsys sensorservice restrict random && adb shell stop && adb shell start" Change-Id: Ibffa87d93b2d24af2803be9281e7141d0a221e3e
Diffstat (limited to 'sensors/1.0/default/Sensors.cpp')
-rw-r--r--sensors/1.0/default/Sensors.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/sensors/1.0/default/Sensors.cpp b/sensors/1.0/default/Sensors.cpp
index 41eb945167..37e2b81d9b 100644
--- a/sensors/1.0/default/Sensors.cpp
+++ b/sensors/1.0/default/Sensors.cpp
@@ -145,21 +145,40 @@ Return<Result> Sensors::activate(
}
Return<void> Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) {
+
hidl_vec<Event> out;
hidl_vec<SensorInfo> dynamicSensorsAdded;
- if (maxCount <= 0) {
- _hidl_cb(Result::BAD_VALUE, out, dynamicSensorsAdded);
- return Void();
- }
-
- int bufferSize = maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize;
-
- std::unique_ptr<sensors_event_t[]> data(new sensors_event_t[bufferSize]);
+ std::unique_ptr<sensors_event_t[]> data;
+ int err = android::NO_ERROR;
+
+ { // scope of reentry lock
+
+ // This enforces a single client, meaning that a maximum of one client can call poll().
+ // If this function is re-entred, it means that we are stuck in a state that may prevent
+ // the system from proceeding normally.
+ //
+ // Exit and let the system restart the sensor-hal-implementation hidl service.
+ //
+ // This function must not call _hidl_cb(...) or return until there is no risk of blocking.
+ std::unique_lock<std::mutex> lock(mPollLock, std::try_to_lock);
+ if(!lock.owns_lock()){
+ // cannot get the lock, hidl service will go into deadlock if it is not restarted.
+ // This is guaranteed to not trigger in passthrough mode.
+ LOG(FATAL) <<
+ "ISensors::poll() re-entry. I do not know what to do except killing myself.";
+ }
- int err = mSensorDevice->poll(
- reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
- data.get(), bufferSize);
+ if (maxCount <= 0) {
+ err = android::BAD_VALUE;
+ } else {
+ int bufferSize = maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize;
+ data.reset(new sensors_event_t[bufferSize]);
+ err = mSensorDevice->poll(
+ reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
+ data.get(), bufferSize);
+ }
+ }
if (err < 0) {
_hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded);