diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-09-12 19:19:31 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-09-12 19:19:31 +0000 |
commit | 5f49e915f94bc77552ed7ad6262365e59b843bd6 (patch) | |
tree | e6086848ca51740b207e32f1b603ee605954eb39 /services | |
parent | ce1dd5bee6bf1eb1eece6fa5088fef772141e3aa (diff) | |
parent | 66028fc88f272085b11c9398458e53c4abd3c72b (diff) | |
download | frameworks_base-5f49e915f94bc77552ed7ad6262365e59b843bd6.zip frameworks_base-5f49e915f94bc77552ed7ad6262365e59b843bd6.tar.gz frameworks_base-5f49e915f94bc77552ed7ad6262365e59b843bd6.tar.bz2 |
am df843862: am 05c1f749: Merge "Fix lock inversion in PackageInstaller." into lmp-dev
* commit 'df8438627733ce2f19f1735df535ed52be60d396':
Fix lock inversion in PackageInstaller.
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/pm/PackageInstallerService.java | 27 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageInstallerSession.java | 19 |
2 files changed, 31 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index fa09d48..c106546 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -144,6 +144,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private final File mStagingDir; private final HandlerThread mInstallThread; + private final Handler mInstallHandler; private final Callbacks mCallbacks; @@ -188,6 +189,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mInstallThread = new HandlerThread(TAG); mInstallThread.start(); + mInstallHandler = new Handler(mInstallThread.getLooper()); + mCallbacks = new Callbacks(mInstallThread.getLooper()); mSessionsFile = new AtomicFile( @@ -961,13 +964,19 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, progress); } - public void onSessionFinished(PackageInstallerSession session, boolean success) { + public void onSessionFinished(final PackageInstallerSession session, boolean success) { mCallbacks.notifySessionFinished(session.sessionId, session.userId, success); - synchronized (mSessions) { - mSessions.remove(session.sessionId); - mHistoricalSessions.put(session.sessionId, session); - } - writeSessionsAsync(); + + mInstallHandler.post(new Runnable() { + @Override + public void run() { + synchronized (mSessions) { + mSessions.remove(session.sessionId); + mHistoricalSessions.put(session.sessionId, session); + writeSessionsLocked(); + } + } + }); } public void onSessionPrepared(PackageInstallerSession session) { @@ -976,11 +985,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub { writeSessionsAsync(); } - public void onSessionSealed(PackageInstallerSession session) { + public void onSessionSealedBlocking(PackageInstallerSession session) { // It's very important that we block until we've recorded the // session as being sealed, since we never want to allow mutation // after sealing. - writeSessionsLocked(); + synchronized (mSessions) { + writeSessionsLocked(); + } } } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 4cbc1c4..fb0e357 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -410,7 +410,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public void commit(IntentSender statusReceiver) { Preconditions.checkNotNull(statusReceiver); + final boolean wasSealed; synchronized (mLock) { + wasSealed = mSealed; if (!mSealed) { // Verify that all writers are hands-off for (FileBridge bridge : mBridges) { @@ -418,17 +420,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new SecurityException("Files still open"); } } - - // Persist the fact that we've sealed ourselves to prevent - // mutations of any hard links we create. mSealed = true; - mCallback.onSessionSealed(this); } + + // Client staging is fully done at this point + mClientProgress = 1f; + computeProgressLocked(true); } - // Client staging is fully done at this point - mClientProgress = 1f; - computeProgressLocked(true); + if (!wasSealed) { + // Persist the fact that we've sealed ourselves to prevent + // mutations of any hard links we create. We do this without holding + // the session lock, since otherwise it's a lock inversion. + mCallback.onSessionSealedBlocking(this); + } // This ongoing commit should keep session active, even though client // will probably close their end. |