Copy retention leases under lock

When adding a retention lease, we make a reference copy of the retention
leases under lock and then make a copy of that collection outside of the
lock. However, since we merely copied a reference to the retention
leases, after leaving a lock the underlying collection could change on
us. Rather, we want to copy these under lock. This commit adds a
dedicated method for doing this, asserts that we hold a lock when we use
this method, and changes adding a retention lease to use this method.

This commit was intended to be included with #37398 but was pushed to
the wrong branch.
This commit is contained in:
Jason Tedor 2019-01-27 08:13:47 -05:00
parent 5fddb631a2
commit 3801925cf0
No known key found for this signature in database
GPG Key ID: FA89F05560F16BC5
1 changed files with 7 additions and 2 deletions

View File

@ -165,6 +165,11 @@ public class ReplicationTracker extends AbstractIndexShardComponent implements L
private final Map<String, RetentionLease> retentionLeases = new HashMap<>();
private Collection<RetentionLease> copyRetentionLeases() {
assert Thread.holdsLock(this);
return Collections.unmodifiableCollection(new ArrayList<>(retentionLeases.values()));
}
/**
* Get all non-expired retention leases tracked on this shard. An unmodifiable copy of the retention leases is returned.
*
@ -208,9 +213,9 @@ public class ReplicationTracker extends AbstractIndexShardComponent implements L
}
retentionLease = new RetentionLease(id, retainingSequenceNumber, currentTimeMillisSupplier.getAsLong(), source);
retentionLeases.put(id, retentionLease);
currentRetentionLeases = retentionLeases.values();
currentRetentionLeases = copyRetentionLeases();
}
onNewRetentionLease.accept(Collections.unmodifiableCollection(new ArrayList<>(currentRetentionLeases)), listener);
onNewRetentionLease.accept(currentRetentionLeases, listener);
return retentionLease;
}