Declare mCommitted as AtomicBoolean in PackageInstallerSession

mCommitted is declared as boolean and is accessed with holding mLock.
mCommitted is set to be true only in streamValidateAndCommit(). After
that, the value of mCommitted shouldn't set back to false.

In order to reduce the chance to make a deadlock situation happen,
this patch changes mCommitted declaration from boolean to
AtomicBoolean.

Test: atest \
                CtsStagedInstallHostTestCases \
                CtsPackageInstallTestCases \
                CtsAtomicInstallTestCases
Test: Presubmit Treehugger

Fix: 197088926
Change-Id: I7e7e952e26c07518539a3e3f587f699c7ecef782
This commit is contained in:
Felka Chang
2021-08-20 17:48:22 +08:00
parent b103b8b3e2
commit 95c129e505

View File

@@ -348,8 +348,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private boolean mSealed = false;
@GuardedBy("mLock")
private boolean mShouldBeSealed = false;
@GuardedBy("mLock")
private boolean mCommitted = false;
private final AtomicBoolean mCommitted = new AtomicBoolean(false);
@GuardedBy("mLock")
private boolean mRelinquished = false;
@@ -692,11 +693,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return;
}
mDestroyed = true;
boolean isCommitted = mCommitted;
List<PackageInstallerSession> childSessions = getChildSessionsLocked();
r = () -> {
assertNotLocked("abandonStaged");
if (isCommitted) {
if (mCommitted.get()) {
mStagingManager.abortCommittedSession(this);
}
cleanStageDir(childSessions);
@@ -1069,7 +1069,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
mPrepared = prepared;
mCommitted = committed;
mCommitted.set(committed);
mDestroyed = destroyed;
mStagedSession = params.isStaged ? new StagedSession(isReady, isApplied, isFailed,
stagedSessionErrorCode, stagedSessionErrorMessage) : null;
@@ -1139,7 +1139,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mResolvedBaseFile.getAbsolutePath() : null;
info.progress = mProgress;
info.sealed = mSealed;
info.isCommitted = mCommitted;
info.isCommitted = mCommitted.get();
info.active = mActiveCount.get() > 0;
info.mode = params.mode;
@@ -1195,9 +1195,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
/** {@hide} */
boolean isCommitted() {
synchronized (mLock) {
return mCommitted;
}
return mCommitted.get();
}
/** {@hide} */
@@ -1235,7 +1233,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private void assertPreparedAndNotCommittedOrDestroyedLocked(String cookie) {
assertPreparedAndNotDestroyedLocked(cookie);
if (mCommitted) {
if (mCommitted.get()) {
throw new SecurityException(cookie + " not allowed after commit");
}
}
@@ -1276,7 +1274,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mProgressLock")
private void computeProgressLocked(boolean forcePublish) {
if (!isIncrementalInstallation() || !mCommitted) {
if (!isIncrementalInstallation() || !mCommitted.get()) {
mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
+ MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f);
} else {
@@ -2004,7 +2002,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// single / child sessions.
try {
synchronized (mLock) {
if (mCommitted) {
if (mCommitted.get()) {
return true;
}
// Read transfers from the original owner stay open, but as the session's data
@@ -2037,7 +2035,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// will probably close their end.
mActiveCount.incrementAndGet();
mCommitted = true;
if (!mCommitted.compareAndSet(false /*expect*/, true /*update*/)) {
throw new PackageManagerException(
INSTALL_FAILED_INTERNAL_ERROR,
TextUtils.formatSimple(
"The mCommitted of session %d should be false originally",
sessionId));
}
committedMillis = System.currentTimeMillis();
}
return true;
@@ -4097,7 +4101,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private boolean canBeAddedAsChild(int parentCandidate) {
synchronized (mLock) {
return (!hasParentSessionId() || mParentSessionId == parentCandidate)
&& !mCommitted && !mDestroyed;
&& !mCommitted.get()
&& !mDestroyed;
}
}
@@ -4541,7 +4546,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
writeStringAttribute(out, ATTR_SESSION_STAGE_CID, stageCid);
}
writeBooleanAttribute(out, ATTR_PREPARED, mPrepared);
writeBooleanAttribute(out, ATTR_COMMITTED, mCommitted);
writeBooleanAttribute(out, ATTR_COMMITTED, mCommitted.get());
writeBooleanAttribute(out, ATTR_DESTROYED, mDestroyed);
writeBooleanAttribute(out, ATTR_SEALED, mSealed);