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

Commit 76698ea0 authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by android-build-merger
Browse files

Merge "Optimized locking for get/setUserData" into oc-dev am: cfd0e95d

am: 63123a66

Change-Id: I95fd0d23bb717884df4bfbf46e76b7288c48a0d6
parents 3b7ab2a4 63123a66
Loading
Loading
Loading
Loading
+51 −44
Original line number Diff line number Diff line
@@ -1407,14 +1407,10 @@ public class AccountManagerService
        long identityToken = clearCallingIdentity();
        try {
            UserAccounts accounts = getUserAccounts(userId);
            synchronized (accounts.dbLock) {
                synchronized (accounts.cacheLock) {
                    if (!accountExistsCacheLocked(accounts, account)) {
            if (!accountExistsCache(accounts, account)) {
                return null;
            }
                    return readUserDataInternalLocked(accounts, account, key);
                }
            }
            return readUserDataInternal(accounts, account, key);
        } finally {
            restoreCallingIdentity(identityToken);
        }
@@ -2503,20 +2499,17 @@ public class AccountManagerService
        long identityToken = clearCallingIdentity();
        try {
            UserAccounts accounts = getUserAccounts(userId);
            synchronized (accounts.dbLock) {
                synchronized (accounts.cacheLock) {
                    if (!accountExistsCacheLocked(accounts, account)) {
            if (!accountExistsCache(accounts, account)) {
                return;
            }
                    setUserdataInternalLocked(accounts, account, key, value);
                }
            }
            setUserdataInternal(accounts, account, key, value);
        } finally {
            restoreCallingIdentity(identityToken);
        }
    }

    private boolean accountExistsCacheLocked(UserAccounts accounts, Account account) {
    private boolean accountExistsCache(UserAccounts accounts, Account account) {
        synchronized (accounts.cacheLock) {
            if (accounts.accountCache.containsKey(account.type)) {
                for (Account acc : accounts.accountCache.get(account.type)) {
                    if (acc.name.equals(account.name)) {
@@ -2524,14 +2517,13 @@ public class AccountManagerService
                    }
                }
            }
        }
        return false;
    }

    private void setUserdataInternalLocked(UserAccounts accounts, Account account, String key,
    private void setUserdataInternal(UserAccounts accounts, Account account, String key,
            String value) {
        if (account == null || key == null) {
            return;
        }
        synchronized (accounts.dbLock) {
            accounts.accountsDb.beginTransaction();
            try {
                long accountId = accounts.accountsDb.findDeAccountId(account);
@@ -2547,11 +2539,14 @@ public class AccountManagerService
                } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
                    return;
                }
            writeUserDataIntoCacheLocked(accounts, account, key, value);
                accounts.accountsDb.setTransactionSuccessful();
            } finally {
                accounts.accountsDb.endTransaction();
            }
            synchronized (accounts.cacheLock) {
                writeUserDataIntoCacheLocked(accounts, account, key, value);
            }
        }
    }

    private void onResult(IAccountManagerResponse response, Bundle result) {
@@ -5622,6 +5617,7 @@ public class AccountManagerService
        }
    }

    /** protected by the {@code dbLock}, {@code cacheLock} */
    protected void writeUserDataIntoCacheLocked(UserAccounts accounts,
            Account account, String key, String value) {
        Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
@@ -5688,14 +5684,25 @@ public class AccountManagerService
        }
    }

    protected String readUserDataInternalLocked(
            UserAccounts accounts, Account account, String key) {
        Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
    private String readUserDataInternal(UserAccounts accounts, Account account, String key) {
        Map<String, String> userDataForAccount;
        // Fast path - check if data is already cached
        synchronized (accounts.cacheLock) {
            userDataForAccount = accounts.userDataCache.get(account);
        }
        // If not cached yet - do slow path and sync with db if necessary
        if (userDataForAccount == null) {
            synchronized (accounts.dbLock) {
                synchronized (accounts.cacheLock) {
                    userDataForAccount = accounts.userDataCache.get(account);
                    if (userDataForAccount == null) {
                        // need to populate the cache for this account
                        userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
                        accounts.userDataCache.put(account, userDataForAccount);
                    }
                }
            }
        }
        return userDataForAccount.get(key);
    }