No longer use a lock for RecipientCache.getSelf()

First, the only lock we can use for the time being is the database lock,
because if we use some other lock we could deadlock.

That said, it seems like we could avoid using a lock at all. The purpose
of the lock was to eliminate double-lookups, but if we have to acquire
the database lock to check if we need to do the lookup, we've lost the
advantage of doing so at all.

We *could* just do a traditional check-lock-check pattern to get the
lock far less often, but given that we're likely going to acquire it
during startup, even a single access has the possibility of really
gumming up the works.
This commit is contained in:
Greyson Parrelli 2021-03-08 09:48:28 -05:00 committed by GitHub
parent faf6b5a4e4
commit 5ed6407ea3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -37,8 +37,9 @@ public final class LiveRecipientCache {
private final Map<RecipientId, LiveRecipient> recipients; private final Map<RecipientId, LiveRecipient> recipients;
private final LiveRecipient unknown; private final LiveRecipient unknown;
private RecipientId localRecipientId; private volatile RecipientId localRecipientId;
private boolean warmedUp;
private boolean warmedUp;
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
public LiveRecipientCache(@NonNull Context context) { public LiveRecipientCache(@NonNull Context context) {
@ -110,22 +111,20 @@ public final class LiveRecipientCache {
} }
@NonNull Recipient getSelf() { @NonNull Recipient getSelf() {
try (SignalSessionLock.Lock unused = DatabaseSessionLock.INSTANCE.acquire()) { if (localRecipientId == null) {
UUID localUuid = TextSecurePreferences.getLocalUuid(context);
String localE164 = TextSecurePreferences.getLocalNumber(context);
if (localUuid != null) {
localRecipientId = recipientDatabase.getByUuid(localUuid).or(recipientDatabase.getByE164(localE164)).orNull();
} else if (localE164 != null) {
localRecipientId = recipientDatabase.getByE164(localE164).orNull();
} else {
throw new IllegalStateException("Tried to call getSelf() before local data was set!");
}
if (localRecipientId == null) { if (localRecipientId == null) {
UUID localUuid = TextSecurePreferences.getLocalUuid(context); throw new MissingRecipientException(null);
String localE164 = TextSecurePreferences.getLocalNumber(context);
if (localUuid != null) {
localRecipientId = recipientDatabase.getByUuid(localUuid).or(recipientDatabase.getByE164(localE164)).orNull();
} else if (localE164 != null) {
localRecipientId = recipientDatabase.getByE164(localE164).orNull();
} else {
throw new IllegalStateException("Tried to call getSelf() before local data was set!");
}
if (localRecipientId == null) {
throw new MissingRecipientException(localRecipientId);
}
} }
} }