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.netty.channel.kqueue; 17 18 import io.netty.channel.ChannelOption; 19 import io.netty.channel.unix.FileDescriptor; 20 import io.netty.util.internal.SystemPropertyUtil; 21 22 /** 23 * If KQueue is available the JNI resources will be loaded when this class loads. 24 */ 25 public final class KQueue { 26 private static final Throwable UNAVAILABILITY_CAUSE; 27 28 static { 29 Throwable cause = null; 30 if (SystemPropertyUtil.getBoolean("io.netty.transport.noNative", false)) { 31 cause = new UnsupportedOperationException( 32 "Native transport was explicit disabled with -Dio.netty.transport.noNative=true"); 33 } else { 34 FileDescriptor kqueueFd = null; 35 try { 36 kqueueFd = Native.newKQueue(); 37 } catch (Throwable t) { 38 cause = t; 39 } finally { 40 if (kqueueFd != null) { 41 try { 42 kqueueFd.close(); 43 } catch (Exception ignore) { 44 // ignore 45 } 46 } 47 } 48 } 49 50 UNAVAILABILITY_CAUSE = cause; 51 } 52 53 /** 54 * Returns {@code true} if and only if the <a href="https://netty.io/wiki/native-transports.html">{@code 55 * netty-transport-native-kqueue}</a> is available. 56 */ 57 public static boolean isAvailable() { 58 return UNAVAILABILITY_CAUSE == null; 59 } 60 61 /** 62 * Ensure that <a href="https://netty.io/wiki/native-transports.html">{@code netty-transport-native-kqueue}</a> is 63 * available. 64 * 65 * @throws UnsatisfiedLinkError if unavailable 66 */ 67 public static void ensureAvailability() { 68 if (UNAVAILABILITY_CAUSE != null) { 69 throw (Error) new UnsatisfiedLinkError( 70 "failed to load the required native library").initCause(UNAVAILABILITY_CAUSE); 71 } 72 } 73 74 /** 75 * Returns the cause of unavailability of <a href="https://netty.io/wiki/native-transports.html">{@code 76 * netty-transport-native-kqueue}</a>. 77 * 78 * @return the cause if unavailable. {@code null} if available. 79 */ 80 public static Throwable unavailabilityCause() { 81 return UNAVAILABILITY_CAUSE; 82 } 83 84 /** 85 * Returns {@code true} if the kqueue native transport is both {@linkplain #isAvailable() available} and supports 86 * {@linkplain ChannelOption#TCP_FASTOPEN_CONNECT client-side TCP FastOpen}. 87 * 88 * @return {@code true} if it's possible to use client-side TCP FastOpen via kqueue, otherwise {@code false}. 89 */ 90 public static boolean isTcpFastOpenClientSideAvailable() { 91 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_CLIENT; 92 } 93 94 /** 95 * Returns {@code true} if the kqueue native transport is both {@linkplain #isAvailable() available} and supports 96 * {@linkplain ChannelOption#TCP_FASTOPEN server-side TCP FastOpen}. 97 * 98 * @return {@code true} if it's possible to use server-side TCP FastOpen via kqueue, otherwise {@code false}. 99 */ 100 public static boolean isTcpFastOpenServerSideAvailable() { 101 return isAvailable() && Native.IS_SUPPORTING_TCP_FASTOPEN_SERVER; 102 } 103 104 private KQueue() { 105 } 106 }