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

Commit a0a7a744 authored by Jason Monk's avatar Jason Monk
Browse files

Add synchronization to DeferredBindRunnables

Seems that on occasion the list is being iterated on while being
modified.  To fix this added synchronization to all modifications
to the list as well as iterating on a copy of the list to cut
down on time holding the lock.

Bug: 12885709
Change-Id: I4287bdedbeb8e438b49c1f79b44819a752c28a69
parent f2a791a7
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -498,7 +498,9 @@ public class LauncherModel extends BroadcastReceiver {
        }

        // Clear any deferred bind runnables
        synchronized (mDeferredBindRunnables) {
            mDeferredBindRunnables.clear();
        }
        // Remove any queued bind runnables
        mHandler.cancelAllRunnablesOfType(MAIN_THREAD_BINDING_RUNNABLE);
        // Unbind all the workspace items
@@ -1315,7 +1317,9 @@ public class LauncherModel extends BroadcastReceiver {

            // Clear any deferred bind-runnables from the synchronized load process
            // We must do this before any loading/binding is scheduled below.
            synchronized (mDeferredBindRunnables) {
                mDeferredBindRunnables.clear();
            }

            // Don't bother to start the thread if we know it's not going to do anything
            if (mCallbacks != null && mCallbacks.get() != null) {
@@ -1337,10 +1341,15 @@ public class LauncherModel extends BroadcastReceiver {
    void bindRemainingSynchronousPages() {
        // Post the remaining side pages to be loaded
        if (!mDeferredBindRunnables.isEmpty()) {
            for (final Runnable r : mDeferredBindRunnables) {
            Runnable[] deferredBindRunnables = null;
            synchronized (mDeferredBindRunnables) {
                deferredBindRunnables = mDeferredBindRunnables.toArray(
                        new Runnable[mDeferredBindRunnables.size()]);
                mDeferredBindRunnables.clear();
            }
            for (final Runnable r : deferredBindRunnables) {
                mHandler.post(r, MAIN_THREAD_BINDING_RUNNABLE);
            }
            mDeferredBindRunnables.clear();
        }
    }

@@ -2367,7 +2376,9 @@ public class LauncherModel extends BroadcastReceiver {
                    }
                };
                if (postOnMainThread) {
                    synchronized (deferredBindRunnables) {
                        deferredBindRunnables.add(r);
                    }
                } else {
                    runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
                }
@@ -2384,7 +2395,9 @@ public class LauncherModel extends BroadcastReceiver {
                    }
                };
                if (postOnMainThread) {
                    synchronized (deferredBindRunnables) {
                        deferredBindRunnables.add(r);
                    }
                } else {
                    runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
                }
@@ -2506,7 +2519,9 @@ public class LauncherModel extends BroadcastReceiver {

            // Load all the remaining pages (if we are loading synchronously, we want to defer this
            // work until after the first render)
            synchronized (mDeferredBindRunnables) {
                mDeferredBindRunnables.clear();
            }
            bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders,
                    (isLoadingSynchronously ? mDeferredBindRunnables : null));

@@ -2528,7 +2543,9 @@ public class LauncherModel extends BroadcastReceiver {
                }
            };
            if (isLoadingSynchronously) {
                synchronized (mDeferredBindRunnables) {
                    mDeferredBindRunnables.add(r);
                }
            } else {
                runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
            }