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