aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java
diff options
context:
space:
mode:
authorGravatar Janak Ramakrishnan <janakr@google.com>2015-12-09 22:55:16 +0000
committerGravatar Lukacs Berki <lberki@google.com>2015-12-10 12:38:07 +0000
commit7737024e10de2ebb825be2052c4f22d42a7005a4 (patch)
tree4e36f98affac966e76001aa4ecdef2741889a53d /src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java
parent0ef6691b6dae09ea13592ecf55923d6f401646c4 (diff)
Distinguish between read and write locks for KeyedLocker.
-- MOS_MIGRATED_REVID=109835697
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/concurrent/KeyedLocker.java48
1 files changed, 31 insertions, 17 deletions
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 1d75f38b25..907237db19 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
@@ -18,7 +18,9 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
/** A keyed store of locks. */
@ThreadSafe
public interface KeyedLocker<K> {
- /** Used to yield access to the implicit lock granted by {@link #lock}. */
+ /**
+ * Used to yield access to the implicit locks granted by {@link #writeLock} or {@link #readLock}.
+ */
@ThreadSafe
interface AutoUnlocker extends AutoCloseable {
/** Exception used to indicate illegal use of {@link AutoUnlocker#close}. */
@@ -30,12 +32,14 @@ public interface KeyedLocker<K> {
/**
* Closes the {@link AutoUnlocker} instance. If this instance was the last unclosed one
- * returned by {@code lock(k)} owned by then the current thread, then exclusive access to
- * {@code k} is yielded.
+ * returned by {@link #writeLock} with argument {@code k} owned by the current
+ * thread, then exclusive access to {@code k} is yielded. If this instance was the last unclosed
+ * one returned by {@link #readLock} with argument {@code k}, then a thread can request
+ * exclusive write access using {@link #writeLock} with argument {@code k}.
*
* <p>This method may only be called at most once per {@link AutoUnlocker} instance and must
- * be called by the same thread that acquired the {@link AutoUnlocker} via {@link #lock}.
- * Otherwise, an {@link IllegalUnlockException} is thrown.
+ * be called by the same thread that acquired the {@link AutoUnlocker} via {@link #writeLock}
+ * or {@link #readLock}. Otherwise, an {@link IllegalUnlockException} is thrown.
*/
@Override
void close();
@@ -45,15 +49,15 @@ public interface KeyedLocker<K> {
* Blocks the current thread until it has exclusive access to do things with {@code k} and
* returns a {@link AutoUnlocker} instance for yielding the implicit lock.
*
- * <p>Notably, this means that a thread is allowed to call {@code lock(k)} again before calling
- * {@link AutoUnlocker#close} for the first call to {@code lock(k)}. Each call to {@link #lock}
- * will return a different {@link AutoUnlocker} instance.
+ * <p>Notably, this means that a thread is allowed to call {@code writeLock(k)} again before
+ * calling {@link AutoUnlocker#close} for the first call to {@code writeLock(k)}. Each call to
+ * {@code #writeLock} will return a different {@link AutoUnlocker} instance.
*
* <p>The intended usage is:
*
* <pre>
* {@code
- * try (AutoUnlocker unlocker = locker.lock(k)) {
+ * try (AutoUnlocker unlocker = locker.writeLock(k)) {
* // Your code here.
* }
* }
@@ -64,22 +68,32 @@ public interface KeyedLocker<K> {
* <pre>
* {@code
* // Thread A
- * try (AutoUnlocker unlocker = locker.lock(k1)) {
- * // This will deadlock if Thread A already acquired a lock for k2.
- * try (AutoUnlocker unlocker = locker.lock(k2)) {
+ * try (AutoUnlocker unlocker = locker.writeLock(k1)) {
+ * // This will deadlock if Thread B already acquired a writeLock for k2.
+ * try (AutoUnlocker unlocker = locker.writeLock(k2)) {
* }
* }
* // end Thread A
*
* // Thread B
- * try (AutoUnlocker unlocker = locker.lock(k2)) {
- * // This will deadlock if Thread A already acquired a lock for k1.
- * try (AutoUnlocker unlocker = locker.lock(k1)) {
+ * try (AutoUnlocker unlocker = locker.writeLock(k2)) {
+ * // This will deadlock if Thread A already acquired a writeLock for k1.
+ * try (AutoUnlocker unlocker = locker.writeLock(k1)) {
* }
* }
* // end Thread B
* }
* </pre>
*/
- AutoUnlocker lock(K key);
-} \ No newline at end of file
+ AutoUnlocker writeLock(K key);
+
+ /**
+ * Blocks the current thread until it has access to read things that have to do with {@code k}.
+ * Multiple threads may acquire simultaneous read locks, so long as there is no thread with a
+ * write lock.
+ *
+ * <p>As with {@link #writeLock}, the same thread can call {@code readLock(k)} multiple times for
+ * the same k before closing the lock.
+ */
+ AutoUnlocker readLock(K key);
+}