1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.util.internal;
17
18 import io.netty5.util.Resource;
19 import io.netty5.util.Send;
20
21 import java.lang.invoke.VarHandle;
22 import java.util.Objects;
23 import java.util.function.Supplier;
24
25 import static java.lang.invoke.MethodHandles.lookup;
26
27 public class SendFromSupplier<T extends Resource<T>> implements Send<T> {
28 private static final VarHandle GATE;
29 static {
30 try {
31 GATE = lookup().findVarHandle(SendFromSupplier.class, "gate", boolean.class);
32 } catch (Exception e) {
33 throw new ExceptionInInitializerError(e);
34 }
35 }
36
37 private final Class<T> concreteObjectType;
38 private final Supplier<? extends T> supplier;
39
40 @SuppressWarnings("unused")
41 private volatile boolean gate;
42
43 public SendFromSupplier(Class<T> concreteObjectType, Supplier<? extends T> supplier) {
44 this.concreteObjectType = Objects.requireNonNull(concreteObjectType, "Concrete type cannot be null.");
45 this.supplier = Objects.requireNonNull(supplier, "Supplier cannot be null.");
46 }
47
48 @Override
49 public T receive() {
50 if (passGate()) {
51 throw new IllegalStateException("This object has already been received.");
52 }
53 return supplier.get();
54 }
55
56 @Override
57 public boolean referentIsInstanceOf(Class<?> cls) {
58 return cls.isAssignableFrom(concreteObjectType);
59 }
60
61 @Override
62 public void close() {
63 if (!passGate()) {
64 supplier.get().close();
65 }
66 }
67
68
69
70
71
72
73
74 private boolean passGate() {
75 return (boolean) GATE.getAndSet(this, true);
76 }
77 }