aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/concurrent
diff options
context:
space:
mode:
authorGravatar Eric Fellheimer <felly@google.com>2015-08-11 18:43:30 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2015-08-12 15:23:02 +0000
commit6a300778094859857eb95ca56fb81556b0837b25 (patch)
tree9ffa10b3a4ee30856831a20b76e61454c059ad1d /src/main/java/com/google/devtools/build/lib/concurrent
parent6c630794b9a3eea04a2b9de0c00edfec920eff66 (diff)
Delete Batch locking, which is unused as of this CL.
-- MOS_MIGRATED_REVID=100399962
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/concurrent')
-rw-r--r--src/main/java/com/google/devtools/build/lib/concurrent/BatchedKeyedLocker.java43
-rw-r--r--src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/concurrent/RefCountedMultisetKeyedLocker.java88
3 files changed, 11 insertions, 122 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/concurrent/BatchedKeyedLocker.java b/src/main/java/com/google/devtools/build/lib/concurrent/BatchedKeyedLocker.java
deleted file mode 100644
index 748262a6fe..0000000000
--- a/src/main/java/com/google/devtools/build/lib/concurrent/BatchedKeyedLocker.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.concurrent;
-
-import java.util.Comparator;
-
-/** A {@link KeyedLocker} that additionally offers batched locking functionality. */
-public interface BatchedKeyedLocker<K> extends KeyedLocker<K> {
- /** Factory for {@link BatchedKeyedLocker} instances. */
- interface Factory<K> {
- /**
- * Returns a fresh {@link BatchedKeyedLocker} instance.
- *
- * <p>The given {@link Comparator} instance is used to get consistent ordering for
- * {@link BatchedKeyedLocker#lockBatch}.
- */
- BatchedKeyedLocker<K> create(Comparator<K> comparator);
- }
-
- /**
- * Similar to {@link #lock}, blocks the current thread until it has exclusive access to do
- * things with all the keys in {@code keys} and returns a single {@link AutoUnlocker} instance
- * for yielding the implicit locks on all the given keys.
- *
- * <p>If a thread has an unclosed {@link AutoUnlocker} instance returned by a call to
- * {@code lockBatch(keys)}, this is equivalent to having separate, unclosed {@link AutoUnlocker}
- * instances for each {@code k} in {@code keys}.
- *
- * <p>Note that use of this method avoids the concerns described in {@link #lock}.
- */
- AutoUnlocker lockBatch(Iterable<K> keys);
-}
diff --git a/src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java b/src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java
index 720db4d716..697e498a70 100644
--- a/src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java
+++ b/src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java
@@ -22,7 +22,7 @@ public interface KeyedLocker<K> {
@ThreadSafe
interface AutoUnlocker extends AutoCloseable {
/** Exception used to indicate illegal use of {@link AutoUnlocker#close}. */
- public static class IllegalUnlockException extends RuntimeException {
+ class IllegalUnlockException extends RuntimeException {
public IllegalUnlockException(String msg) {
super(msg);
}
diff --git a/src/main/java/com/google/devtools/build/lib/concurrent/RefCountedMultisetKeyedLocker.java b/src/main/java/com/google/devtools/build/lib/concurrent/RefCountedMultisetKeyedLocker.java
index 914e918fe0..ee1c2b5dbc 100644
--- a/src/main/java/com/google/devtools/build/lib/concurrent/RefCountedMultisetKeyedLocker.java
+++ b/src/main/java/com/google/devtools/build/lib/concurrent/RefCountedMultisetKeyedLocker.java
@@ -15,25 +15,19 @@ package com.google.devtools.build.lib.concurrent;
import com.google.common.base.Preconditions;
import com.google.common.collect.ConcurrentHashMultiset;
-import com.google.common.collect.ImmutableSortedSet;
import com.google.common.util.concurrent.Striped;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import javax.annotation.Nullable;
-
/**
* An implementation of {@link KeyedLocker} that uses ref counting to efficiently only store locks
* that are live.
*/
-public class RefCountedMultisetKeyedLocker<K> implements BatchedKeyedLocker<K> {
+public class RefCountedMultisetKeyedLocker<K> implements KeyedLocker<K> {
// Multiset of keys that have threads waiting on a lock or using a lock.
private final ConcurrentHashMultiset<K> waiters = ConcurrentHashMultiset.<K>create();
@@ -45,44 +39,13 @@ public class RefCountedMultisetKeyedLocker<K> implements BatchedKeyedLocker<K> {
// Map of key to current lock, for keys that have at least one waiting or live thread.
private final ConcurrentMap<K, ReentrantLock> locks = new ConcurrentHashMap<>();
- // Used to enforce a consistent ordering in lockBatch.
- @Nullable
- private final Comparator<K> comparator;
-
- private RefCountedMultisetKeyedLocker(Comparator<K> comparator) {
- this.comparator = comparator;
- }
-
- /** Factory for {@link RefCountedMultisetKeyedLocker} instances. */
- public static class Factory<K> implements BatchedKeyedLocker.Factory<K> {
- @Override
- public BatchedKeyedLocker<K> create(Comparator<K> comparator) {
- return new RefCountedMultisetKeyedLocker<>(comparator);
- }
-
- public KeyedLocker<K> create() {
- return new RefCountedMultisetKeyedLocker<>(/*comparator=*/null);
- }
- }
-
- private abstract static class AtMostOnceAutoUnlockerBase<K> implements AutoUnlocker {
- private final AtomicBoolean closeCalled = new AtomicBoolean(false);
-
- @Override
- public final void close() {
- if (closeCalled.getAndSet(true)) {
- String msg = "'close' can be called at most once per AutoUnlocker instance";
- throw new IllegalUnlockException(msg);
- }
- doClose();
- }
-
- protected abstract void doClose();
+ public RefCountedMultisetKeyedLocker() {
}
- private class RefCountedAutoUnlocker extends AtMostOnceAutoUnlockerBase<K> {
+ private class RefCountedAutoUnlocker implements AutoUnlocker {
private final K key;
private final ReentrantLock lock;
+ private final AtomicBoolean closeCalled = new AtomicBoolean(false);
private RefCountedAutoUnlocker(K key, ReentrantLock lock) {
this.key = key;
@@ -90,7 +53,12 @@ public class RefCountedMultisetKeyedLocker<K> implements BatchedKeyedLocker<K> {
}
@Override
- protected void doClose() {
+ public void close() {
+ if (closeCalled.getAndSet(true)) {
+ String msg = String.format("For key %s, 'close' can be called at most once per "
+ + "AutoUnlocker instance", key);
+ throw new IllegalUnlockException(msg);
+ }
if (!lock.isHeldByCurrentThread()) {
String msg = String.format("For key %s, the calling thread to 'close' must be the one "
+ "that acquired the AutoUnlocker", key);
@@ -145,40 +113,4 @@ public class RefCountedMultisetKeyedLocker<K> implements BatchedKeyedLocker<K> {
// We won the race, so the current lock for 'key' is the one we locked and inserted.
return new RefCountedAutoUnlocker(key, newLock);
}
-
- private static void unlockAll(Iterable<KeyedLocker.AutoUnlocker> unlockers) {
- // Note that order doesn't matter here because we always acquire locks in a consistent order.
- for (KeyedLocker.AutoUnlocker unlocker : unlockers) {
- unlocker.close();
- }
- }
-
- @Override
- public AutoUnlocker lockBatch(Iterable<K> keys) {
- // This indicates the client did some unsafe casting - not our problem.
- Preconditions.checkNotNull(comparator);
- // We acquire locks in a consistent order. This prevents a deadlock that would otherwise occur
- // on two concurrent calls to lockBatch(keys(k1, k2)) if the callers acquired the locks in a
- // different order.
- ImmutableSortedSet<K> sortedKeys = ImmutableSortedSet.copyOf(comparator, keys);
- final List<KeyedLocker.AutoUnlocker> unlockers = new ArrayList<>(sortedKeys.size());
- boolean success = false;
- try {
- for (K key : sortedKeys) {
- unlockers.add(lock(key));
- }
- success = true;
- return new AtMostOnceAutoUnlockerBase<K>() {
- @Override
- public void doClose() {
- unlockAll(unlockers);
- }
- };
- } finally {
- // Just in case we encounter a crash, e.g. if there is a bug in #lock.
- if (!success) {
- unlockAll(unlockers);
- }
- }
- }
}