1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.concurrent;
33
34 import java.util.concurrent.TimeUnit;
35 import java.util.concurrent.TimeoutException;
36 import javax.annotation.CheckReturnValue;
37 import javax.annotation.Nonnegative;
38 import javax.annotation.ParametersAreNonnullByDefault;
39 import javax.annotation.concurrent.ThreadSafe;
40 import org.spf4j.base.ExecutionContexts;
41
42
43
44
45
46 @ThreadSafe
47 @ParametersAreNonnullByDefault
48 public interface PermitSupplier {
49
50 PermitSupplier UNLIMITED = new PermitSupplier() {
51 @Override
52 public boolean tryAcquire(final int nrPermits, final long deadlineNanos) {
53 return true;
54 }
55
56 @Override
57 public String toString() {
58 return "Unlimited";
59 }
60
61
62
63 };
64
65 PermitSupplier EMPTY = new PermitSupplier() {
66 @Override
67 public boolean tryAcquire(final int nrPermits, final long deadlineNanos) {
68 return false;
69 }
70
71 @Override
72 public String toString() {
73 return "Empty";
74 }
75
76 };
77
78 public interface Acquisition {
79
80 Acquisition SUCCESS = new Acquisition() {
81 @Override
82 public boolean isSuccess() {
83 return true;
84 }
85
86 @Override
87 public long permitAvailableEstimateInNanos() {
88 return 0L;
89 }
90 };
91
92 static Acquisition failed(final long nanosUntilAvailable) {
93 return new Acquisition() {
94 @Override
95 public boolean isSuccess() {
96 return false;
97 }
98
99 @Override
100 public long permitAvailableEstimateInNanos() {
101 return nanosUntilAvailable;
102 }
103 };
104 }
105
106
107
108
109 boolean isSuccess();
110
111
112
113
114 long permitAvailableEstimateInNanos();
115 }
116
117
118
119
120
121
122
123
124
125 default void acquire(final long timeout, final TimeUnit unit)
126 throws InterruptedException, TimeoutException {
127 acquire(1, timeout, unit);
128 }
129
130
131
132
133
134
135
136
137
138
139 default void acquire(final int nrPermits, @Nonnegative final long timeout, final TimeUnit unit)
140 throws InterruptedException, TimeoutException {
141 if (!tryAcquire(nrPermits, timeout, unit)) {
142 throw new TimeoutException("Cannot acquire timeout after " + timeout + " " + unit);
143 }
144 }
145
146
147
148
149
150
151
152
153
154 @CheckReturnValue
155 default boolean tryAcquire(@Nonnegative final long timeout, final TimeUnit unit)
156 throws InterruptedException {
157 return tryAcquire(1, timeout, unit);
158 }
159
160
161
162
163
164
165
166
167
168
169 @CheckReturnValue
170 default boolean tryAcquire(@Nonnegative final int nrPermits, @Nonnegative final long timeout, final TimeUnit unit)
171 throws InterruptedException {
172 if (timeout < 0) {
173 throw new IllegalArgumentException("Invalid timeout " + timeout + ' ' + unit);
174 }
175 return tryAcquire(nrPermits, ExecutionContexts.computeDeadline(timeout, unit));
176 }
177
178 @CheckReturnValue
179 boolean tryAcquire(@Nonnegative int nrPermits, long deadlineNanos) throws InterruptedException;
180
181
182 @CheckReturnValue
183 default Acquisition tryAcquireEx(@Nonnegative final int nrPermits,
184 @Nonnegative final long timeout, final TimeUnit unit)
185 throws InterruptedException {
186 if (timeout < 0) {
187 throw new IllegalArgumentException("Invalid timeout " + timeout + ' ' + unit);
188 }
189 return tryAcquireEx(nrPermits, ExecutionContexts.computeDeadline(timeout, unit));
190 }
191
192 @CheckReturnValue
193 default Acquisition tryAcquireEx(@Nonnegative final int nrPermits, final long deadlineNanos)
194 throws InterruptedException {
195 boolean res = tryAcquire(nrPermits, deadlineNanos);
196 if (res) {
197 return Acquisition.SUCCESS;
198 } else {
199 return Acquisition.failed(-1L);
200 }
201 }
202
203
204
205
206
207
208 default boolean addPermits(final int nrPermits) {
209 return false;
210 }
211
212 default Semaphore toSemaphore() {
213 return new Semaphore() {
214 @Override
215 public void release(final int nrPermits) {
216
217 }
218
219 @Override
220 public boolean tryAcquire(final int nrPermits, final long timeout, final TimeUnit unit)
221 throws InterruptedException {
222 return PermitSupplier.this.tryAcquire(nrPermits, timeout, unit);
223 }
224
225 @Override
226 public boolean tryAcquire(final long timeout, final TimeUnit unit) throws InterruptedException {
227 return PermitSupplier.this.tryAcquire(timeout, unit);
228 }
229
230 @Override
231 public void acquire(final int nrPermits, final long timeout, final TimeUnit unit)
232 throws InterruptedException, TimeoutException {
233 PermitSupplier.this.acquire(nrPermits, timeout, unit);
234 }
235
236 @Override
237 public void acquire(final long timeout, final TimeUnit unit) throws InterruptedException, TimeoutException {
238 PermitSupplier.this.acquire(timeout, unit);
239 }
240
241 @Override
242 public boolean tryAcquire(final int nrPermits, final long deadlineNanos) throws InterruptedException {
243 return PermitSupplier.this.tryAcquire(nrPermits, deadlineNanos);
244 }
245
246 };
247 }
248
249 }