PackageManagerService分析(Android 10)->Pms的兩把鎖

2020-10-13 03:00:20
/**
 * Keep track of all those APKs everywhere.
 * <p>
 * Internally there are two important locks:
 * <ul>
 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
 * and other related state. It is a fine-grained lock that should only be held
 * momentarily, as it's one of the most contended locks in the system.
 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
 * operations typically involve heavy lifting of application data on disk. Since
 * {@code installd} is single-threaded, and it's operations can often be slow,
 * this lock should never be acquired while already holding {@link #mPackages}.
 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
 * holding {@link #mInstallLock}.
 * </ul>
 * Many internal methods rely on the caller to hold the appropriate locks, and
 * this contract is expressed through method name suffixes:
 * <ul>
 * <li>fooLI(): the caller must hold {@link #mInstallLock}
 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
 * being modified must be frozen
 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
 * </ul>
 * <p>
 * Because this class is very central to the platform's security; please run all
 * CTS and unit tests whenever making modifications:
 *
 * <pre>
 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
 * </pre>
 */

註釋裡面說的比較清楚Pms有兩把鎖,一把叫mPackages,是fine-grained lock(細粒度的鎖)。 另一把是mInstallLock,它是一把重量級的鎖。 另外還有四個方法範例表示該方法持有什麼樣的鎖,分別是:

  • fooLI() LI結尾表示呼叫者必須持有mInstallLock這把鎖
  • fooLIF() LIF結尾呼叫者必須持有mInstallLock 這把鎖,並且必須凍結(凍結表示禁止啟動)要修改的軟體包。
  • fooLPr() LPr結尾表示必須持有mPackages才可以呼叫,並且該方法唯讀mPackages鎖保護的資料。
  • fooLPw() LPw結尾表示必須持有mPackages才可以呼叫,並且該方法會修改mPackages鎖保護的資料。

另外由於mPackages為細粒度的鎖, mInstallLock為重量級鎖,所以不應該在持有 mPackages鎖的情況下再去獲取mInstallLock,否則mPackages也會變成重量級。

上述都不是重點, 重點是Pms到底如何使用這兩把鎖, 現在由我來給大家說明。

PackageManagerService主要有兩項工作:
1 應用安裝解除安裝: mInstallLock 主要保證這個流程是序列執行。而這個過程會修改mPackages鎖保護的資料,mPackages保證安裝解除安裝過程中查詢資料正確。
2 應用資訊查詢:mPackages 也是保證查詢資料正確,這個過程不會修改mPackages保護的資料。