1 /* 2 * Copyright 2016 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package io.netty5.channel.kqueue; 17 18 import io.netty5.channel.ChannelOption; 19 import io.netty5.channel.unix.FileDescriptor; 20 import io.netty5.util.internal.SystemPropertyUtil; 21 import io.netty5.util.internal.UnstableApi; 22 23 /** 24 * If KQueue is available the JNI resources will be loaded when this class loads. 25 */ 26 @UnstableApi 27 public final class KQueue { 28 private static final Throwable UNAVAILABILITY_CAUSE; 29 30 static { 31 Throwable cause = null; 32 if (SystemPropertyUtil.getBoolean("io.netty5.transport.noNative", false)) { 33 cause = new UnsupportedOperationException( 34 "Native transport was explicit disabled with -Dio.netty5.transport.noNative=true"); 35 } else { 36 FileDescriptor kqueueFd = null; 37 try { 38 kqueueFd = Native.newKQueue(); 39 } catch (Throwable t) { 40 cause = t; 41 } finally { 42 if (kqueueFd != null) { 43 try { 44 kqueueFd.close(); 45 } catch (Exception ignore) { 46 // ignore 47 } 48 } 49 } 50 } 51 52 UNAVAILABILITY_CAUSE = cause; 53 } 54 55 /** 56 * Returns {@code true} if and only if the <a href="https://netty.io/wiki/native-transports.html">{@code 57 * netty-transport-native-kqueue}</a> is available. 58 */ 59 public static boolean isAvailable() { 60 return UNAVAILABILITY_CAUSE == null; 61 } 62 63 /** 64 * Ensure that <a href="https://netty.io/wiki/native-transports.html">{@code netty-transport-native-kqueue}</a> is 65 * available. 66 * 67 * @throws UnsatisfiedLinkError if unavailable 68 */ 69 public static void ensureAvailability() { 70 if (UNAVAILABILITY_CAUSE != null) { 71 throw (Error) new UnsatisfiedLinkError( 72 "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE); 73 } 74 } 75 76 /** 77 * Returns the cause of unavailability of <a href="https://netty.io/wiki/native-transports.html">{@code 78 * netty-transport-native-kqueue}</a>. 79 * 80 * @return the cause if unavailable. {@code null} if available. 81 */ 82 public static Throwable unavailabilityCause() { 83 return UNAVAILABILITY_CAUSE; 84 } 85 86 /** 87 * Returns {@code true} if the kqueue native transport is both {@linkplain #isAvailable() available} and supports 88 * {@linkplain ChannelOption#TCP_FASTOPEN_CONNECT client-side TCP FastOpen}. 89 * 90 * @return {@code true} if it's possible to use client-side TCP FastOpen via kqueue, otherwise {@code false}. 91 */ 92 public static boolean isTcpFastOpenClientSideAvailable() { 93 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_CLIENT; 94 } 95 96 /** 97 * Returns {@code true} if the kqueue native transport is both {@linkplain #isAvailable() available} and supports 98 * {@linkplain ChannelOption#TCP_FASTOPEN server-side TCP FastOpen}. 99 * 100 * @return {@code true} if it's possible to use server-side TCP FastOpen via kqueue, otherwise {@code false}. 101 */ 102 public static boolean isTcpFastOpenServerSideAvailable() { 103 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_SERVER; 104 } 105 106 private KQueue() { 107 } 108 }