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.util.internal.logging.InternalLogger;
19 import io.netty5.util.internal.logging.InternalLoggerFactory;
20
21 import java.lang.invoke.MethodHandle;
22 import java.lang.invoke.MethodHandles;
23 import java.lang.invoke.MethodHandles.Lookup;
24 import java.lang.invoke.MethodType;
25 import java.nio.ByteBuffer;
26
27 final class JniBufferAccess {
28 static final boolean IS_AVAILABLE;
29 static final MethodHandle MEMORY_ADDRESS;
30
31 private static final InternalLogger logger = InternalLoggerFactory.getInstance(JniBufferAccess.class);
32
33 static {
34 boolean isAvailable = false;
35 MethodHandle memoryAddress = null;
36 try {
37 Class<?> bufferAccess = Class.forName("io.netty5.channel.unix.Buffer");
38 Lookup lookup = MethodHandles.lookup();
39 bufferAccess = lookup.accessClass(bufferAccess);
40 MethodType type = MethodType.methodType(long.class, ByteBuffer.class);
41 memoryAddress = lookup.findStatic(bufferAccess, "memoryAddress", type);
42 isAvailable = true;
43 } catch (Throwable e) {
44 logger.debug("JNI unix bypass for accessing native address of DirectByteBuffer is unavailable.", e);
45 }
46 if (!isAvailable) {
47 try {
48 Class<?> bufferAccess = Class.forName("io.netty.internal.tcnative.Buffer");
49 Lookup lookup = MethodHandles.lookup();
50 bufferAccess = lookup.accessClass(bufferAccess);
51 MethodType type = MethodType.methodType(long.class, ByteBuffer.class);
52 memoryAddress = lookup.findStatic(bufferAccess, "address", type);
53 isAvailable = true;
54 } catch (Throwable e) {
55 logger.debug("JNI tcnative bypass for accessing native address of DirectByteBuffer is unavailable.", e);
56 }
57 }
58 IS_AVAILABLE = isAvailable;
59 MEMORY_ADDRESS = memoryAddress;
60 }
61
62 private JniBufferAccess() {
63 }
64 }