diff options
author | Aravind Akella | 2014-09-28 19:49:24 -0500 |
---|---|---|
committer | Android (Google) Code Review | 2014-09-28 19:49:26 -0500 |
commit | deb71b2812702318900c36b7bcfa9759525ea7cc (patch) | |
tree | 502b293fa2663dd0d11a83c3aeb7a4dd02dee176 /services/sensorservice | |
parent | bacc28ef1df329f4dc21bae44b09a6c5018af908 (diff) | |
parent | e148bc29c27ae7a346fa686fdda6425ba202d97a (diff) | |
download | frameworks-native-deb71b2812702318900c36b7bcfa9759525ea7cc.tar.gz frameworks-native-deb71b2812702318900c36b7bcfa9759525ea7cc.tar.xz frameworks-native-deb71b2812702318900c36b7bcfa9759525ea7cc.zip |
Merge "Fix a possible SensorService deadlock." into lmp-dev
Diffstat (limited to 'services/sensorservice')
-rw-r--r-- | services/sensorservice/SensorService.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index f953a960a..7c5795707 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp | |||
@@ -398,6 +398,24 @@ bool SensorService::threadLoop() | |||
398 | for (int i = 0; i < count; i++) { | 398 | for (int i = 0; i < count; i++) { |
399 | mSensorEventBuffer[i].flags = 0; | 399 | mSensorEventBuffer[i].flags = 0; |
400 | } | 400 | } |
401 | |||
402 | // Make a copy of the connection vector as some connections may be removed during the | ||
403 | // course of this loop (especially when one-shot sensor events are present in the | ||
404 | // sensor_event buffer). Promote all connections to StrongPointers before the lock is | ||
405 | // acquired. If the destructor of the sp gets called when the lock is acquired, it may | ||
406 | // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for | ||
407 | // cleanup. So copy all the strongPointers to a vector before the lock is acquired. | ||
408 | SortedVector< sp<SensorEventConnection> > activeConnections; | ||
409 | { | ||
410 | Mutex::Autolock _l(mLock); | ||
411 | for (size_t i=0 ; i < mActiveConnections.size(); ++i) { | ||
412 | sp<SensorEventConnection> connection(mActiveConnections[i].promote()); | ||
413 | if (connection != 0) { | ||
414 | activeConnections.add(connection); | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | |||
401 | Mutex::Autolock _l(mLock); | 419 | Mutex::Autolock _l(mLock); |
402 | // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The | 420 | // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The |
403 | // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, | 421 | // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, |
@@ -487,21 +505,17 @@ bool SensorService::threadLoop() | |||
487 | // Send our events to clients. Check the state of wake lock for each client and release the | 505 | // Send our events to clients. Check the state of wake lock for each client and release the |
488 | // lock if none of the clients need it. | 506 | // lock if none of the clients need it. |
489 | bool needsWakeLock = false; | 507 | bool needsWakeLock = false; |
490 | // Make a copy of the connection vector as some connections may be removed during the | ||
491 | // course of this loop (especially when one-shot sensor events are present in the | ||
492 | // sensor_event buffer). | ||
493 | const SortedVector< wp<SensorEventConnection> > activeConnections(mActiveConnections); | ||
494 | size_t numConnections = activeConnections.size(); | 508 | size_t numConnections = activeConnections.size(); |
495 | for (size_t i=0 ; i < numConnections; ++i) { | 509 | for (size_t i=0 ; i < numConnections; ++i) { |
496 | sp<SensorEventConnection> connection(activeConnections[i].promote()); | 510 | if (activeConnections[i] != 0) { |
497 | if (connection != 0) { | 511 | activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, |
498 | connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, | ||
499 | mMapFlushEventsToConnections); | 512 | mMapFlushEventsToConnections); |
500 | needsWakeLock |= connection->needsWakeLock(); | 513 | needsWakeLock |= activeConnections[i]->needsWakeLock(); |
501 | // If the connection has one-shot sensors, it may be cleaned up after first trigger. | 514 | // If the connection has one-shot sensors, it may be cleaned up after first trigger. |
502 | // Early check for one-shot sensors. | 515 | // Early check for one-shot sensors. |
503 | if (connection->hasOneShotSensors()) { | 516 | if (activeConnections[i]->hasOneShotSensors()) { |
504 | cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count); | 517 | cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, |
518 | count); | ||
505 | } | 519 | } |
506 | } | 520 | } |
507 | } | 521 | } |
@@ -985,10 +999,10 @@ SensorService::SensorEventConnection::SensorEventConnection( | |||
985 | 999 | ||
986 | SensorService::SensorEventConnection::~SensorEventConnection() { | 1000 | SensorService::SensorEventConnection::~SensorEventConnection() { |
987 | ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); | 1001 | ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); |
1002 | mService->cleanupConnection(this); | ||
988 | if (mEventCache != NULL) { | 1003 | if (mEventCache != NULL) { |
989 | delete mEventCache; | 1004 | delete mEventCache; |
990 | } | 1005 | } |
991 | mService->cleanupConnection(this); | ||
992 | } | 1006 | } |
993 | 1007 | ||
994 | void SensorService::SensorEventConnection::onFirstRef() { | 1008 | void SensorService::SensorEventConnection::onFirstRef() { |