1 package com.atlassian.cache.impl;
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 public class OneShotLatch
16 {
17 private final Sync sync = new Sync();
18
19 public boolean isHeldByCurrentThread()
20 {
21 return sync.isHeldByCurrentThread();
22 }
23
24 public void release()
25 {
26 sync.release(0);
27 }
28
29 public void await()
30 {
31 sync.acquireShared(0);
32 }
33
34 public boolean await(long timeout, TimeUnit unit) throws InterruptedException
35 {
36 return sync.tryAcquireSharedNanos(0, unit.toNanos(timeout));
37 }
38
39 @Override
40 public String toString()
41 {
42 return "OneShotLatch[sync=" + sync + ']';
43 }
44
45
46
47 static class Sync extends AbstractQueuedSynchronizer
48 {
49 private static final int STATE_UNAVAILABLE = -1;
50 private static final int STATE_RELEASED = 1;
51
52 Sync()
53 {
54 setState(STATE_UNAVAILABLE);
55 setExclusiveOwnerThread(Thread.currentThread());
56 }
57
58 boolean isHeldByCurrentThread()
59 {
60 return getExclusiveOwnerThread() == Thread.currentThread();
61 }
62
63 @Override
64 protected boolean tryRelease(int ignored)
65 {
66 if (!isHeldByCurrentThread())
67 {
68 throw new IllegalMonitorStateException(toString());
69 }
70
71 setExclusiveOwnerThread(null);
72 setState(STATE_RELEASED);
73 return true;
74 }
75
76 @Override
77 protected int tryAcquireShared(int ignored)
78 {
79 final int state = getState();
80 if (state == STATE_UNAVAILABLE && isHeldByCurrentThread())
81 {
82 throw new IllegalMonitorStateException(toString());
83 }
84 return state;
85 }
86
87 @Override
88 public String toString()
89 {
90 return "Sync[state=" + getState() + "; owner=" + getExclusiveOwnerThread() + ']';
91 }
92 }
93 }