1 package com.atlassian.vcache.internal.core.service;
2
3 import java.util.concurrent.TimeUnit;
4 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
5
6
7
8
9
10
11
12
13
14
15 class OneShotLatch {
16 private final Sync sync = new Sync();
17
18 public boolean isHeldByCurrentThread() {
19 return sync.isHeldByCurrentThread();
20 }
21
22 public void release() {
23 sync.release(0);
24 }
25
26 public void await() {
27 sync.acquireShared(0);
28 }
29
30 public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
31 return sync.tryAcquireSharedNanos(0, unit.toNanos(timeout));
32 }
33
34 @Override
35 public String toString() {
36 return "OneShotLatch[sync=" + sync + ']';
37 }
38
39
40 static class Sync extends AbstractQueuedSynchronizer {
41 private static final int STATE_UNAVAILABLE = -1;
42 private static final int STATE_RELEASED = 1;
43
44 Sync() {
45 setState(STATE_UNAVAILABLE);
46 setExclusiveOwnerThread(Thread.currentThread());
47 }
48
49 boolean isHeldByCurrentThread() {
50 return getExclusiveOwnerThread() == Thread.currentThread();
51 }
52
53 @Override
54 protected boolean tryRelease(int ignored) {
55 if (!isHeldByCurrentThread()) {
56 throw new IllegalMonitorStateException(toString());
57 }
58
59 setExclusiveOwnerThread(null);
60 setState(STATE_RELEASED);
61 return true;
62 }
63
64 @Override
65 protected int tryAcquireShared(int ignored) {
66 final int state = getState();
67 if (state == STATE_UNAVAILABLE && isHeldByCurrentThread()) {
68 throw new IllegalMonitorStateException(toString());
69 }
70 return state;
71 }
72
73 @Override
74 public String toString() {
75 return "Sync[state=" + getState() + "; owner=" + getExclusiveOwnerThread() + ']';
76 }
77 }
78 }