1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.uring;
17
18 import io.netty.channel.ChannelOption;
19 import io.netty.util.internal.PlatformDependent;
20 import io.netty.util.internal.SystemPropertyUtil;
21 import io.netty.util.internal.logging.InternalLogger;
22 import io.netty.util.internal.logging.InternalLoggerFactory;
23
24 public final class IoUring {
25
26 private static final Throwable UNAVAILABILITY_CAUSE;
27 private static final boolean IORING_CQE_F_SOCK_NONEMPTY_SUPPORTED;
28 private static final boolean IORING_SPLICE_SUPPORTED;
29 static {
30 Throwable cause = null;
31 boolean socketNonEmptySupported = false;
32 boolean spliceSupported = false;
33 try {
34 if (SystemPropertyUtil.getBoolean("io.netty.transport.noNative", false)) {
35 cause = new UnsupportedOperationException(
36 "Native transport was explicit disabled with -Dio.netty.transport.noNative=true");
37 } else {
38 String kernelVersion = Native.kernelVersion();
39 Native.checkKernelVersion(kernelVersion);
40 Throwable unsafeCause = PlatformDependent.getUnsafeUnavailabilityCause();
41 if (unsafeCause == null) {
42 RingBuffer ringBuffer = null;
43 try {
44 ringBuffer = Native.createRingBuffer();
45 Native.checkAllIOSupported(ringBuffer.fd());
46 socketNonEmptySupported = Native.isIOUringCqeFSockNonEmptySupported(ringBuffer.fd());
47 spliceSupported = Native.isIOUringSupportSplice(ringBuffer.fd());
48 } finally {
49 if (ringBuffer != null) {
50 try {
51 ringBuffer.close();
52 } catch (Exception ignore) {
53
54 }
55 }
56 }
57 } else {
58 cause = new UnsupportedOperationException("Unsafe is not supported", unsafeCause);
59 }
60 }
61 } catch (Throwable t) {
62 cause = t;
63 }
64 if (cause != null) {
65 InternalLogger logger = InternalLoggerFactory.getInstance(IoUring.class);
66 if (logger.isTraceEnabled()) {
67 logger.debug("IoUring support is not available", cause);
68 } else if (logger.isDebugEnabled()) {
69 logger.debug("IoUring support is not available: {}", cause.getMessage());
70 }
71 }
72 UNAVAILABILITY_CAUSE = cause;
73 IORING_CQE_F_SOCK_NONEMPTY_SUPPORTED = socketNonEmptySupported;
74 IORING_SPLICE_SUPPORTED = spliceSupported;
75 }
76
77 public static boolean isAvailable() {
78 return UNAVAILABILITY_CAUSE == null;
79 }
80
81
82
83
84
85
86
87 public static boolean isTcpFastOpenClientSideAvailable() {
88 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_CLIENT;
89 }
90
91
92
93
94
95
96
97 public static boolean isTcpFastOpenServerSideAvailable() {
98 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_SERVER;
99 }
100
101 static boolean isIOUringCqeFSockNonEmptySupported() {
102 return IORING_CQE_F_SOCK_NONEMPTY_SUPPORTED;
103 }
104
105 static boolean isIOUringSpliceSupported() {
106 return IORING_SPLICE_SUPPORTED;
107 }
108
109 public static void ensureAvailability() {
110 if (UNAVAILABILITY_CAUSE != null) {
111 throw (Error) new UnsatisfiedLinkError(
112 "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE);
113 }
114 }
115
116 public static Throwable unavailabilityCause() {
117 return UNAVAILABILITY_CAUSE;
118 }
119
120 private IoUring() {
121 }
122 }