Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84338c45 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

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: I0dee91f09e4056132aaaf0fb0a663148c65db1e4
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent cace13d7
Loading
Loading
Loading
Loading
+32 −17
Original line number Diff line number Diff line
@@ -448,16 +448,32 @@ 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);
                                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);
@@ -474,7 +490,6 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC
                                            VolumeState.Shared);
                                }
                            }
                            }

                            /*
                             * If UMS was connected on boot, send the connected event