diff options
author | Mike Lockwood <lockwood@android.com> | 2011-04-05 10:05:47 -0400 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2011-05-04 10:41:19 -0400 |
commit | 0aa5d7b7f225236ac8461d0b6835b9c6152a2699 (patch) | |
tree | 9bc11ff8ac526d26b59635edf1512ae3cd7afd0c | |
parent | e3b498be0ae05367e9b84f4fac2ac5cf57a6b091 (diff) | |
download | frameworks_base-0aa5d7b7f225236ac8461d0b6835b9c6152a2699.zip frameworks_base-0aa5d7b7f225236ac8461d0b6835b9c6152a2699.tar.gz frameworks_base-0aa5d7b7f225236ac8461d0b6835b9c6152a2699.tar.bz2 |
DO NOT MERGE Fix deadlock in MountService
It is not safe to call into vold with a lock held on mVolumeStates
since we will receive events back from vold on a different thread.
So in the boot completed handler we make a copy of the volume list and
then call vold to mount volumes after releasing the lock
Change-Id: Iaadfb1b8be5567c8e228a8fbc69d4d483c8dc987
Signed-off-by: Mike Lockwood <lockwood@android.com>
-rw-r--r-- | services/java/com/android/server/MountService.java | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index a91b690..ca813fe 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -444,31 +444,46 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC * to make the media scanner run. */ if ("simulator".equals(SystemProperties.get("ro.product.device"))) { - notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, VolumeState.Mounted); + notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, + VolumeState.Mounted); return; } new Thread() { @Override public void run() { try { + // it is not safe to call vold with mVolumeStates locked + // so we make a copy of the paths and states and process them + // outside the lock + String[] paths, states; + int count; synchronized (mVolumeStates) { - for (String path : mVolumeStates.keySet()) { - String state = mVolumeStates.get(path); - - if (state.equals(Environment.MEDIA_UNMOUNTED)) { - int rc = doMountVolume(path); - if (rc != StorageResultCode.OperationSucceeded) { - Slog.e(TAG, String.format("Boot-time mount failed (%d)", - rc)); - } - } else if (state.equals(Environment.MEDIA_SHARED)) { - /* - * Bootstrap UMS enabled state since vold indicates - * the volume is shared (runtime restart while ums enabled) - */ - notifyVolumeStateChange(null, path, VolumeState.NoMedia, - VolumeState.Shared); + Set<String> keys = mVolumeStates.keySet(); + count = keys.size(); + paths = (String[])keys.toArray(new String[count]); + states = new String[count]; + for (int i = 0; i < count; i++) { + states[i] = mVolumeStates.get(paths[i]); + } + } + + for (int i = 0; i < count; i++) { + String path = paths[i]; + String state = states[i]; + + if (state.equals(Environment.MEDIA_UNMOUNTED)) { + int rc = doMountVolume(path); + if (rc != StorageResultCode.OperationSucceeded) { + Slog.e(TAG, String.format("Boot-time mount failed (%d)", + rc)); } + } else if (state.equals(Environment.MEDIA_SHARED)) { + /* + * Bootstrap UMS enabled state since vold indicates + * the volume is shared (runtime restart while ums enabled) + */ + notifyVolumeStateChange(null, path, VolumeState.NoMedia, + VolumeState.Shared); } } |