diff options
author | Todd Poynor | 2017-06-26 16:34:38 -0500 |
---|---|---|
committer | Todd Poynor | 2017-06-27 13:58:17 -0500 |
commit | fd68370074fab549f569d8b9a5bf3d7c535c47bc (patch) | |
tree | 28fe1f14a63d898dbac17b7b1ce7419009c734c8 /healthd | |
parent | 4f5f558d3810348126ff651492849eaf748ccc2a (diff) | |
download | platform-system-core-fd68370074fab549f569d8b9a5bf3d7c535c47bc.tar.gz platform-system-core-fd68370074fab549f569d8b9a5bf3d7c535c47bc.tar.xz platform-system-core-fd68370074fab549f569d8b9a5bf3d7c535c47bc.zip |
healthd: notify listeners using local copy of list, drop lockandroid-vts-8.0_r1
Binder currently may service an incoming oneway transaction whenever
an outbound oneway call is made (if there is already a pending
incoming oneway call waiting). The unexpected nested method call
blocks forever on a recursive mutex acquire because healthd is single-
threaded. The binder behavior is considered a bug and may change in
the future. For now, work around this in healthd.
Make a local copy of the listeners list, then drop the lock and
perform the outbound calls on the local copy of the list.
Bug: 38201220
Test: Marlin with modified client calling scheduleUpdate() repeatedly
Change-Id: If35c2847556245921e2aff808ff747bb60356811
Diffstat (limited to 'healthd')
-rw-r--r-- | healthd/BatteryPropertiesRegistrar.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp index 523e1f136..e51a06d5e 100644 --- a/healthd/BatteryPropertiesRegistrar.cpp +++ b/healthd/BatteryPropertiesRegistrar.cpp | |||
@@ -36,9 +36,19 @@ void BatteryPropertiesRegistrar::publish( | |||
36 | } | 36 | } |
37 | 37 | ||
38 | void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) { | 38 | void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) { |
39 | Mutex::Autolock _l(mRegistrationLock); | 39 | Vector<sp<IBatteryPropertiesListener> > listenersCopy; |
40 | for (size_t i = 0; i < mListeners.size(); i++) { | 40 | |
41 | mListeners[i]->batteryPropertiesChanged(props); | 41 | // Binder currently may service an incoming oneway transaction whenever an |
42 | // outbound oneway call is made (if there is already a pending incoming | ||
43 | // oneway call waiting). This is considered a bug and may change in the | ||
44 | // future. For now, avoid recursive mutex lock while making outbound | ||
45 | // calls by making a local copy of the current list of listeners. | ||
46 | { | ||
47 | Mutex::Autolock _l(mRegistrationLock); | ||
48 | listenersCopy = mListeners; | ||
49 | } | ||
50 | for (size_t i = 0; i < listenersCopy.size(); i++) { | ||
51 | listenersCopy[i]->batteryPropertiesChanged(props); | ||
42 | } | 52 | } |
43 | } | 53 | } |
44 | 54 | ||