summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Bartel <joshua.bartel@gmail.com>2009-10-05 12:44:46 -0400
committerJoshua Bartel <joshua.bartel@gmail.com>2009-10-05 12:44:46 -0400
commit9ff67a5f9b0bca15ad6933eac90a65b11b29eb2e (patch)
treebe6b8a4728f94454eee79e5601dec7887dd7e752
parent5550ef48739a7bb16f80aa6b10e9c151b1438163 (diff)
downloadbase-9ff67a5f9b0bca15ad6933eac90a65b11b29eb2e.tar.gz
LocationManagerService: Fix race when removing LocationListener
In LocationManagerService if a LocationListener is removed while it has a pending broadcast the wake lock held while pending broadcasts are outstanding do not get cleared properly. There are 2 cases of this race that are fixed: 1. locationCallbackFinished was changed to check the mReceivers HashMap directly instead of calling getReceiver. getReceiver would add the ILocationListener as a new Receiver if it did not exist which caused a receiver that was removed when it still had a broadcast pending to be added back in a bad state when the pending broadcast completed. 2. removeUpdatesLocked was changed to decrement the pending broadcasts when a Receiver is removed that has pending broadcasts.
-rw-r--r--services/java/com/android/server/LocationManagerService.java13
1 files changed, 12 insertions, 1 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 9866ccea8732..4a4d5abb3371 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -394,7 +394,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
public void locationCallbackFinished(ILocationListener listener) {
- Receiver receiver = getReceiver(listener);
+ //Do not use getReceiver here as that will add the ILocationListener to
+ //the receiver list if it is not found. If it is not found then the
+ //LocationListener was removed when it had a pending broadcast and should
+ //not be added back.
+ IBinder binder = listener.asBinder();
+ Receiver receiver = mReceivers.get(binder);
if (receiver != null) {
synchronized (receiver) {
// so wakelock calls will succeed
@@ -1030,6 +1035,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
try {
if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+ synchronized(receiver) {
+ if(receiver.mPendingBroadcasts > 0) {
+ decrementPendingBroadcasts();
+ receiver.mPendingBroadcasts = 0;
+ }
+ }
}
// Record which providers were associated with this listener