1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.buffer.api.internal;
17
18 import io.netty5.buffer.api.Drop;
19 import io.netty5.buffer.api.Owned;
20 import io.netty5.util.Resource;
21 import io.netty5.util.Send;
22
23 import java.lang.invoke.VarHandle;
24
25 import static io.netty5.buffer.api.internal.Statics.findVarHandle;
26 import static java.lang.invoke.MethodHandles.lookup;
27
28 public class SendFromOwned<I extends Resource<I>, T extends ResourceSupport<I, T>> implements Send<I> {
29 private static final VarHandle RECEIVED = findVarHandle(lookup(), SendFromOwned.class, "received", boolean.class);
30 private final Owned<T> outgoing;
31 private final Drop<T> drop;
32 private final Class<?> concreteType;
33 @SuppressWarnings("unused")
34 private volatile boolean received;
35
36 public SendFromOwned(Owned<T> outgoing, Drop<T> drop, Class<?> concreteType) {
37 this.outgoing = outgoing;
38 this.drop = drop;
39 this.concreteType = concreteType;
40 }
41
42 @SuppressWarnings("unchecked")
43 @Override
44 public I receive() {
45 gateReception();
46 var copy = outgoing.transferOwnership(drop);
47 drop.attach(copy);
48 return (I) copy;
49 }
50
51 private void gateReception() {
52 if ((boolean) RECEIVED.getAndSet(this, true)) {
53 throw new IllegalStateException("This object has already been received.");
54 }
55 }
56
57 @Override
58 public boolean referentIsInstanceOf(Class<?> cls) {
59 return cls.isAssignableFrom(concreteType);
60 }
61
62 @Override
63 public void close() {
64 if (!(boolean) RECEIVED.getAndSet(this, true)) {
65 var copy = outgoing.transferOwnership(drop);
66 drop.attach(copy);
67 copy.close();
68 }
69 }
70 }