Ensure that the callback always sees the current-operation state in sync
with the various other bits of internal backup-operation state. Previously
only the current-operation state was managed inside the critical section;
this resulted in a slim race window where a callback could see an ongoing
operation as still valid, but after the internal state on which that
operation depended had already been cleared.
Bug
17931760
Change-Id: Ia032668e7a9d22f1029c57fc98db9e86484d5719
try { if (mSavedState != null) mSavedState.close(); } catch (IOException e) {}
try { if (mBackupData != null) mBackupData.close(); } catch (IOException e) {}
try { if (mNewState != null) mNewState.close(); } catch (IOException e) {}
- mSavedState = mBackupData = mNewState = null;
synchronized (mCurrentOpLock) {
+ // Current-operation callback handling requires the validity of these various
+ // bits of internal state as an invariant of the operation still being live.
+ // This means we make sure to clear all of the state in unison inside the lock.
mCurrentOperations.clear();
+ mSavedState = mBackupData = mNewState = null;
}
// If this was a pseudopackage there's no associated Activity Manager state