diff --git a/4.2/api/argfile b/4.2/api/argfile index 32fa5cd4184..ee2ae9b1f28 100644 --- a/4.2/api/argfile +++ b/4.2/api/argfile @@ -55,6 +55,7 @@ '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/UnstableApi.java' '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/PendingWrite.java' '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/PriorityQueue.java' +'/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/BoundedInputStream.java' '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/PriorityQueueNode.java' '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/svm/PlatformDependentSubstitution.java' '/Users/norman/Documents/workspace/netty/common/src/main/java/io/netty/util/internal/svm/UnsafeRefArrayAccessSubstitution.java' @@ -1458,6 +1459,7 @@ '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/IoUringIoEvent.java' '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/MsgHdrMemory.java' '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/SockaddrIn.java' +'/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/IoUringFileRegion.java' '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/MsgHdr.java' '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/AbstractIoUringStreamChannel.java' '/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java/io/netty/channel/uring/NativeStaticallyReferencedJniMethods.java' @@ -1621,6 +1623,7 @@ '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/InsecureTrustManagerFactory.java' '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/KeytoolSelfSignedCertGenerator.java' '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/SimpleTrustManagerFactory.java' +'/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/CertificateBuilderCertGenerator.java' '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/package-info.java' '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/util/BouncyCastleSelfSignedCertGenerator.java' '/Users/norman/Documents/workspace/netty/handler/src/main/java/io/netty/handler/ssl/OpenSslApplicationProtocolNegotiator.java' @@ -1739,4 +1742,12 @@ '/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java/io/netty/handler/ssl/ocsp/OcspServerCertificateValidator.java' '/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java/io/netty/handler/ssl/ocsp/OcspValidationEvent.java' '/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java/io/netty/handler/ssl/ocsp/package-info.java' -'/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java/io/netty/handler/ssl/ocsp/OcspClient.java' \ No newline at end of file +'/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java/io/netty/handler/ssl/ocsp/OcspClient.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/RevocationServer.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/GeneralNameUtils.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/Signed.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/CertificateList.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/Algorithms.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/CertificateBuilder.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/package-info.java' +'/Users/norman/Documents/workspace/netty/pkitesting/src/main/java/io/netty/pkitesting/X509Bundle.java' \ No newline at end of file diff --git a/4.2/api/options b/4.2/api/options index 4fee0ee1fc9..84b5971c6ce 100644 --- a/4.2/api/options +++ b/4.2/api/options @@ -2,14 +2,14 @@ 'en_US' -breakiterator -classpath -'/Users/norman/Documents/workspace/netty/dev-tools/target/netty-dev-tools-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/common/target/netty-common-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/buffer/target/netty-buffer-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-base/target/netty-codec-base-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-compression/target/netty-codec-compression-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-protobuf/target/netty-codec-protobuf-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-marshalling/target/netty-codec-marshalling-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec/target/netty-codec-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-dns/target/netty-codec-dns-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-haproxy/target/netty-codec-haproxy-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-http/target/netty-codec-http-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-http2/target/netty-codec-http2-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-memcache/target/netty-codec-memcache-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-mqtt/target/netty-codec-mqtt-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-redis/target/netty-codec-redis-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-smtp/target/netty-codec-smtp-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-socks/target/netty-codec-socks-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-stomp/target/netty-codec-stomp-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/codec-xml/target/netty-codec-xml-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/resolver/target/netty-resolver-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/resolver-dns/target/netty-resolver-dns-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/target/netty-resolver-dns-classes-macos-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/target/netty-resolver-dns-native-macos-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport/target/netty-transport-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-native-unix-common/target/netty-transport-native-unix-common-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-classes-epoll/target/netty-transport-classes-epoll-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-native-epoll/target/netty-transport-native-epoll-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/target/netty-transport-classes-io_uring-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-native-io_uring/target/netty-transport-native-io_uring-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/target/netty-transport-classes-kqueue-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-native-kqueue/target/netty-transport-native-kqueue-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-rxtx/target/netty-transport-rxtx-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-sctp/target/netty-transport-sctp-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-udt/target/netty-transport-udt-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/handler/target/netty-handler-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/handler-proxy/target/netty-handler-proxy-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/target/netty-handler-ssl-ocsp-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/testsuite-native/target/netty-testsuite-native-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/target/netty-testsuite-native-image-client-runtime-init-4.2.0.Beta1.jar:/Users/norman/Documents/workspace/netty/transport-blockhound-tests/target/netty-transport-blockhound-tests-4.2.0.Beta1.jar:/Users/norman/.m2/repository/org/graalvm/nativeimage/svm/19.3.6/svm-19.3.6.jar:/Users/norman/.m2/repository/org/jboss/jdk-misc/3.Final/jdk-misc-3.Final.jar:/Users/norman/.m2/repository/org/jctools/jctools-core/4.0.5/jctools-core-4.0.5.jar:/Users/norman/.m2/repository/org/jetbrains/annotations-java5/23.0.0/annotations-java5-23.0.0.jar:/Users/norman/.m2/repository/org/slf4j/slf4j-api/2.0.13/slf4j-api-2.0.13.jar:/Users/norman/.m2/repository/commons-logging/commons-logging/1.3.4/commons-logging-1.3.4.jar:/Users/norman/.m2/repository/org/apache/logging/log4j/log4j-1.2-api/2.23.1/log4j-1.2-api-2.23.1.jar:/Users/norman/.m2/repository/org/apache/logging/log4j/log4j-api/2.23.1/log4j-api-2.23.1.jar:/Users/norman/.m2/repository/io/projectreactor/tools/blockhound/1.0.6.RELEASE/blockhound-1.0.6.RELEASE.jar:/Users/norman/.m2/repository/com/jcraft/jzlib/1.1.3/jzlib-1.1.3.jar:/Users/norman/.m2/repository/com/ning/compress-lzf/1.0.3/compress-lzf-1.0.3.jar:/Users/norman/.m2/repository/net/jpountz/lz4/lz4/1.3.0/lz4-1.3.0.jar:/Users/norman/.m2/repository/com/github/jponge/lzma-java/1.3/lzma-java-1.3.jar:/Users/norman/.m2/repository/com/github/luben/zstd-jni/1.5.6-5/zstd-jni-1.5.6-5.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/brotli4j/1.16.0/brotli4j-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/service/1.16.0/service-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-x86_64/1.16.0/native-linux-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-aarch64/1.16.0/native-linux-aarch64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-riscv64/1.16.0/native-linux-riscv64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-osx-x86_64/1.16.0/native-osx-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-osx-aarch64/1.16.0/native-osx-aarch64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-windows-x86_64/1.16.0/native-windows-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/google/protobuf/protobuf-java/3.16.3/protobuf-java-3.16.3.jar:/Users/norman/.m2/repository/com/google/protobuf/nano/protobuf-javanano/3.0.0-alpha-5/protobuf-javanano-3.0.0-alpha-5.jar:/Users/norman/.m2/repository/org/jboss/marshalling/jboss-marshalling/1.4.11.Final/jboss-marshalling-1.4.11.Final.jar:/Users/norman/.m2/repository/org/bouncycastle/bcprov-jdk18on/1.78.1/bcprov-jdk18on-1.78.1.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-classes/2.0.69.Final/netty-tcnative-classes-2.0.69.Final.jar:/Users/norman/.m2/repository/com/fasterxml/aalto-xml/1.3.3/aalto-xml-1.3.3.jar:/Users/norman/.m2/repository/org/codehaus/woodstox/stax2-api/4.2.2/stax2-api-4.2.2.jar:/Users/norman/.m2/repository/io/netty/netty-jni-util/0.0.9.Final/netty-jni-util-0.0.9.Final-sources.jar:/Users/norman/.m2/repository/org/bouncycastle/bcpkix-jdk18on/1.78.1/bcpkix-jdk18on-1.78.1.jar:/Users/norman/.m2/repository/org/bouncycastle/bcutil-jdk18on/1.78.1/bcutil-jdk18on-1.78.1.jar:/Users/norman/.m2/repository/org/rxtx/rxtx/2.1.7/rxtx-2.1.7.jar:/Users/norman/.m2/repository/com/barchart/udt/barchart-udt-bundle/2.3.0/barchart-udt-bundle-2.3.0.jar:/Users/norman/.m2/repository/org/conscrypt/conscrypt-openjdk-uber/2.5.2/conscrypt-openjdk-uber-2.5.2.jar' +'/Users/norman/Documents/workspace/netty/dev-tools/target/netty-dev-tools-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/common/target/netty-common-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/buffer/target/netty-buffer-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-base/target/netty-codec-base-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-compression/target/netty-codec-compression-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-protobuf/target/netty-codec-protobuf-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-marshalling/target/netty-codec-marshalling-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec/target/netty-codec-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-dns/target/netty-codec-dns-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-haproxy/target/netty-codec-haproxy-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-http/target/netty-codec-http-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-http2/target/netty-codec-http2-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-memcache/target/netty-codec-memcache-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-mqtt/target/netty-codec-mqtt-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-redis/target/netty-codec-redis-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-smtp/target/netty-codec-smtp-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-socks/target/netty-codec-socks-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-stomp/target/netty-codec-stomp-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/codec-xml/target/netty-codec-xml-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/resolver/target/netty-resolver-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/resolver-dns/target/netty-resolver-dns-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/target/netty-resolver-dns-classes-macos-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/target/netty-resolver-dns-native-macos-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport/target/netty-transport-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-native-unix-common/target/netty-transport-native-unix-common-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-classes-epoll/target/netty-transport-classes-epoll-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-native-epoll/target/netty-transport-native-epoll-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/target/netty-transport-classes-io_uring-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-native-io_uring/target/netty-transport-native-io_uring-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/target/netty-transport-classes-kqueue-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-native-kqueue/target/netty-transport-native-kqueue-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-rxtx/target/netty-transport-rxtx-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-sctp/target/netty-transport-sctp-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-udt/target/netty-transport-udt-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/handler/target/netty-handler-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/handler-proxy/target/netty-handler-proxy-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/target/netty-handler-ssl-ocsp-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/pkitesting/target/netty-pkitesting-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/testsuite-jpms/target/classes:/Users/norman/Documents/workspace/netty/testsuite-native/target/netty-testsuite-native-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/target/netty-testsuite-native-image-client-runtime-init-4.2.0.RC1.jar:/Users/norman/Documents/workspace/netty/transport-blockhound-tests/target/netty-transport-blockhound-tests-4.2.0.RC1.jar:/Users/norman/.m2/repository/org/graalvm/nativeimage/svm/19.3.6/svm-19.3.6.jar:/Users/norman/.m2/repository/org/jboss/jdk-misc/3.Final/jdk-misc-3.Final.jar:/Users/norman/.m2/repository/org/jctools/jctools-core/4.0.5/jctools-core-4.0.5.jar:/Users/norman/.m2/repository/org/jetbrains/annotations-java5/23.0.0/annotations-java5-23.0.0.jar:/Users/norman/.m2/repository/org/slf4j/slf4j-api/2.0.13/slf4j-api-2.0.13.jar:/Users/norman/.m2/repository/commons-logging/commons-logging/1.3.4/commons-logging-1.3.4.jar:/Users/norman/.m2/repository/org/apache/logging/log4j/log4j-1.2-api/2.23.1/log4j-1.2-api-2.23.1.jar:/Users/norman/.m2/repository/org/apache/logging/log4j/log4j-api/2.23.1/log4j-api-2.23.1.jar:/Users/norman/.m2/repository/io/projectreactor/tools/blockhound/1.0.6.RELEASE/blockhound-1.0.6.RELEASE.jar:/Users/norman/.m2/repository/com/jcraft/jzlib/1.1.3/jzlib-1.1.3.jar:/Users/norman/.m2/repository/com/ning/compress-lzf/1.0.3/compress-lzf-1.0.3.jar:/Users/norman/.m2/repository/net/jpountz/lz4/lz4/1.3.0/lz4-1.3.0.jar:/Users/norman/.m2/repository/com/github/jponge/lzma-java/1.3/lzma-java-1.3.jar:/Users/norman/.m2/repository/com/github/luben/zstd-jni/1.5.6-5/zstd-jni-1.5.6-5.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/brotli4j/1.16.0/brotli4j-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/service/1.16.0/service-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-x86_64/1.16.0/native-linux-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-aarch64/1.16.0/native-linux-aarch64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-linux-riscv64/1.16.0/native-linux-riscv64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-osx-x86_64/1.16.0/native-osx-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-osx-aarch64/1.16.0/native-osx-aarch64-1.16.0.jar:/Users/norman/.m2/repository/com/aayushatharva/brotli4j/native-windows-x86_64/1.16.0/native-windows-x86_64-1.16.0.jar:/Users/norman/.m2/repository/com/google/protobuf/protobuf-java/3.16.3/protobuf-java-3.16.3.jar:/Users/norman/.m2/repository/com/google/protobuf/nano/protobuf-javanano/3.0.0-alpha-5/protobuf-javanano-3.0.0-alpha-5.jar:/Users/norman/.m2/repository/org/jboss/marshalling/jboss-marshalling/1.4.11.Final/jboss-marshalling-1.4.11.Final.jar:/Users/norman/.m2/repository/org/bouncycastle/bcprov-jdk18on/1.79/bcprov-jdk18on-1.79.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-classes/2.0.69.Final/netty-tcnative-classes-2.0.69.Final.jar:/Users/norman/.m2/repository/com/fasterxml/aalto-xml/1.3.3/aalto-xml-1.3.3.jar:/Users/norman/.m2/repository/org/codehaus/woodstox/stax2-api/4.2.2/stax2-api-4.2.2.jar:/Users/norman/.m2/repository/io/netty/netty-jni-util/0.0.9.Final/netty-jni-util-0.0.9.Final-sources.jar:/Users/norman/.m2/repository/org/bouncycastle/bcpkix-jdk18on/1.79/bcpkix-jdk18on-1.79.jar:/Users/norman/.m2/repository/org/bouncycastle/bcutil-jdk18on/1.79/bcutil-jdk18on-1.79.jar:/Users/norman/.m2/repository/org/rxtx/rxtx/2.1.7/rxtx-2.1.7.jar:/Users/norman/.m2/repository/com/barchart/udt/barchart-udt-bundle/2.3.0/barchart-udt-bundle-2.3.0.jar:/Users/norman/.m2/repository/org/conscrypt/conscrypt-openjdk-uber/2.5.2/conscrypt-openjdk-uber-2.5.2.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.69.Final/netty-tcnative-boringssl-static-2.0.69.Final-osx-aarch_64.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.69.Final/netty-tcnative-boringssl-static-2.0.69.Final-linux-x86_64.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.69.Final/netty-tcnative-boringssl-static-2.0.69.Final-linux-aarch_64.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.69.Final/netty-tcnative-boringssl-static-2.0.69.Final-osx-x86_64.jar:/Users/norman/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.69.Final/netty-tcnative-boringssl-static-2.0.69.Final-windows-x86_64.jar' -encoding 'UTF-8' -protected --release -sourcepath -'/Users/norman/Documents/workspace/netty/common/src/main/java:/Users/norman/Documents/workspace/netty/common/target/generated-sources/collections/java:/Users/norman/Documents/workspace/netty/common/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/buffer/src/main/java:/Users/norman/Documents/workspace/netty/buffer/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-base/src/main/java:/Users/norman/Documents/workspace/netty/codec-base/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-compression/src/main/java:/Users/norman/Documents/workspace/netty/codec-compression/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-protobuf/src/main/java:/Users/norman/Documents/workspace/netty/codec-protobuf/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-marshalling/src/main/java:/Users/norman/Documents/workspace/netty/codec-marshalling/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-dns/src/main/java:/Users/norman/Documents/workspace/netty/codec-dns/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-haproxy/src/main/java:/Users/norman/Documents/workspace/netty/codec-haproxy/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-http/src/main/java:/Users/norman/Documents/workspace/netty/codec-http/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-http2/src/main/java:/Users/norman/Documents/workspace/netty/codec-http2/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-memcache/src/main/java:/Users/norman/Documents/workspace/netty/codec-memcache/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-mqtt/src/main/java:/Users/norman/Documents/workspace/netty/codec-mqtt/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-redis/src/main/java:/Users/norman/Documents/workspace/netty/codec-redis/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-smtp/src/main/java:/Users/norman/Documents/workspace/netty/codec-smtp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-socks/src/main/java:/Users/norman/Documents/workspace/netty/codec-socks/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-stomp/src/main/java:/Users/norman/Documents/workspace/netty/codec-stomp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-xml/src/main/java:/Users/norman/Documents/workspace/netty/codec-xml/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver/src/main/java:/Users/norman/Documents/workspace/netty/resolver/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns/src/main/java:/Users/norman/Documents/workspace/netty/resolver-dns/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/src/main/java:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/src/main/c:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport/src/main/java:/Users/norman/Documents/workspace/netty/transport/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-unix-common/src/main/java:/Users/norman/Documents/workspace/netty/transport-native-unix-common/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-unix-common/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-epoll/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-epoll/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-epoll/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-epoll/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-io_uring/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-io_uring/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-kqueue/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-kqueue/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-rxtx/src/main/java:/Users/norman/Documents/workspace/netty/transport-rxtx/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-sctp/src/main/java:/Users/norman/Documents/workspace/netty/transport-sctp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-udt/src/main/java:/Users/norman/Documents/workspace/netty/transport-udt/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler/src/main/java:/Users/norman/Documents/workspace/netty/handler/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler-proxy/src/main/java:/Users/norman/Documents/workspace/netty/handler-proxy/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/src/main/java:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/target/generated-sources/annotations' +'/Users/norman/Documents/workspace/netty/common/src/main/java:/Users/norman/Documents/workspace/netty/common/target/generated-sources/collections/java:/Users/norman/Documents/workspace/netty/common/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/buffer/src/main/java:/Users/norman/Documents/workspace/netty/buffer/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-base/src/main/java:/Users/norman/Documents/workspace/netty/codec-base/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-compression/src/main/java:/Users/norman/Documents/workspace/netty/codec-compression/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-protobuf/src/main/java:/Users/norman/Documents/workspace/netty/codec-protobuf/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-marshalling/src/main/java:/Users/norman/Documents/workspace/netty/codec-marshalling/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-dns/src/main/java:/Users/norman/Documents/workspace/netty/codec-dns/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-haproxy/src/main/java:/Users/norman/Documents/workspace/netty/codec-haproxy/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-http/src/main/java:/Users/norman/Documents/workspace/netty/codec-http/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-http2/src/main/java:/Users/norman/Documents/workspace/netty/codec-http2/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-memcache/src/main/java:/Users/norman/Documents/workspace/netty/codec-memcache/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-mqtt/src/main/java:/Users/norman/Documents/workspace/netty/codec-mqtt/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-redis/src/main/java:/Users/norman/Documents/workspace/netty/codec-redis/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-smtp/src/main/java:/Users/norman/Documents/workspace/netty/codec-smtp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-socks/src/main/java:/Users/norman/Documents/workspace/netty/codec-socks/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-stomp/src/main/java:/Users/norman/Documents/workspace/netty/codec-stomp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/codec-xml/src/main/java:/Users/norman/Documents/workspace/netty/codec-xml/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver/src/main/java:/Users/norman/Documents/workspace/netty/resolver/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns/src/main/java:/Users/norman/Documents/workspace/netty/resolver-dns/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/src/main/java:/Users/norman/Documents/workspace/netty/resolver-dns-classes-macos/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/src/main/c:/Users/norman/Documents/workspace/netty/resolver-dns-native-macos/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport/src/main/java:/Users/norman/Documents/workspace/netty/transport/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-unix-common/src/main/java:/Users/norman/Documents/workspace/netty/transport-native-unix-common/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-unix-common/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-epoll/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-epoll/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-epoll/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-epoll/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-io_uring/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-io_uring/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-io_uring/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/src/main/java:/Users/norman/Documents/workspace/netty/transport-classes-kqueue/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-native-kqueue/src/main/c:/Users/norman/Documents/workspace/netty/transport-native-kqueue/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-rxtx/src/main/java:/Users/norman/Documents/workspace/netty/transport-rxtx/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-sctp/src/main/java:/Users/norman/Documents/workspace/netty/transport-sctp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/transport-udt/src/main/java:/Users/norman/Documents/workspace/netty/transport-udt/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler/src/main/java:/Users/norman/Documents/workspace/netty/handler/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler-proxy/src/main/java:/Users/norman/Documents/workspace/netty/handler-proxy/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/src/main/java:/Users/norman/Documents/workspace/netty/handler-ssl-ocsp/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/pkitesting/src/main/java:/Users/norman/Documents/workspace/netty/pkitesting/target/generated-sources/annotations:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/src/main/java:/Users/norman/Documents/workspace/netty/testsuite-native-image-client-runtime-init/target/generated-sources/annotations' -bottom 'Copyright © 2008–2024 The Netty Project. All rights reserved.' -charset @@ -20,7 +20,7 @@ 'UTF-8' -docfilessubdirs -doctitle -'Netty API Reference (4.2.0.Beta1)' +'Netty API Reference (4.2.0.RC1)' -group 'Low-level data representation' 'io.netty.buffer*' -group @@ -42,4 +42,4 @@ 'https://www.slf4j.org/apidocs' -use -windowtitle -'Netty API Reference (4.2.0.Beta1)' \ No newline at end of file +'Netty API Reference (4.2.0.RC1)' \ No newline at end of file diff --git a/4.2/xref/allclasses-frame.html b/4.2/xref/allclasses-frame.html index eb0ddb90ed1..53459e8234f 100644 --- a/4.2/xref/allclasses-frame.html +++ b/4.2/xref/allclasses-frame.html @@ -177,6 +177,7 @@

All Classes

  • AhoCorasicSearchProcessorFactory
  • AhoCorasicSearchProcessorFactory.Context
  • AhoCorasicSearchProcessorFactory.Processor
  • +
  • Algorithms
  • AppendableCharSequence
  • ApplicationProtocolAccessor
  • ApplicationProtocolConfig
  • @@ -254,6 +255,7 @@

    All Classes

  • BouncyCastleAlpnSslUtils.null
  • BouncyCastlePemReader
  • BouncyCastleSelfSignedCertGenerator
  • +
  • BoundedInputStream
  • Brotli
  • BrotliDecoder
  • BrotliDecoder.State
  • @@ -367,6 +369,14 @@

    All Classes

  • Cache.Entries
  • CachingClassResolver
  • CaseIgnoringComparator
  • +
  • CertificateBuilder
  • +
  • CertificateBuilder.Algorithm
  • +
  • CertificateBuilder.BuilderCallback
  • +
  • CertificateBuilder.ExtendedKeyUsage
  • +
  • CertificateBuilder.KeyUsage
  • +
  • CertificateBuilder.SecureRandomHolder
  • +
  • CertificateBuilderCertGenerator
  • +
  • CertificateList
  • Channel
  • Channel.Unsafe
  • ChannelBufferByteInput
  • @@ -1066,6 +1076,7 @@

    All Classes

  • FullMemcacheMessage
  • Future
  • FutureListener
  • +
  • GeneralNameUtils
  • GenericFutureListener
  • GenericProgressiveFutureListener
  • GenericUnixChannelOption
  • @@ -1603,6 +1614,7 @@

    All Classes

  • IoUringDatagramChannel.IoUringDatagramChannelUnsafe
  • IoUringDatagramChannel.IoUringDatagramChannelUnsafe.WriteProcessor
  • IoUringDatagramChannelConfig
  • +
  • IoUringFileRegion
  • IoUringIoEvent
  • IoUringIoHandle
  • IoUringIoHandler
  • @@ -2306,6 +2318,8 @@

    All Classes

  • ResumableX509ExtendedTrustManager
  • ResumptionController
  • ResumptionController.X509ExtendedWrapTrustManager
  • +
  • RevocationServer
  • +
  • RevocationServer.CrlInfo
  • RingBuffer
  • RotationalDnsServerAddresses
  • RoundRobinDnsAddressResolverGroup
  • @@ -2434,6 +2448,7 @@

    All Classes

  • Signal
  • Signal.SignalConstant
  • SignatureAlgorithmConverter
  • +
  • Signed
  • SimpleChannelInboundHandler
  • SimpleChannelPool
  • SimpleChannelPool.ChannelPoolFullException
  • @@ -2839,6 +2854,7 @@

    All Classes

  • UnknownSocksResponse
  • UnmarshallerProvider
  • UnorderedThreadPoolEventExecutor
  • +
  • UnorderedThreadPoolEventExecutor.AccountingThreadFactory
  • UnorderedThreadPoolEventExecutor.NonNotifyRunnable
  • UnorderedThreadPoolEventExecutor.RunnableScheduledFutureTask
  • UnpaddedInternalThreadLocalMap
  • @@ -3006,6 +3022,7 @@

    All Classes

  • WriteTimeoutException
  • WriteTimeoutHandler
  • WriteTimeoutHandler.WriteTimeoutTask
  • +
  • X509Bundle
  • X509KeyManagerWrapper
  • X509TrustManagerWrapper
  • XmlAttribute
  • diff --git a/4.2/xref/index.html b/4.2/xref/index.html index 8e3b6a2053e..9a749f3b767 100644 --- a/4.2/xref/index.html +++ b/4.2/xref/index.html @@ -4,7 +4,7 @@ - Netty Source Xref (4.2.0.Beta1) + Netty Source Xref (4.2.0.RC1) + + diff --git a/4.2/xref/io/netty/channel/uring/IoUringIoHandler.html b/4.2/xref/io/netty/channel/uring/IoUringIoHandler.html index 3d617b59683..20dc3066187 100644 --- a/4.2/xref/io/netty/channel/uring/IoUringIoHandler.html +++ b/4.2/xref/io/netty/channel/uring/IoUringIoHandler.html @@ -76,367 +76,371 @@ 68 // these two ids are used internally any so can't be used by nextRegistrationId(). 69 private static final int EVENTFD_ID = Integer.MAX_VALUE; 70 private static final int RINGFD_ID = EVENTFD_ID - 1; -71 -72 IoUringIoHandler(RingBuffer ringBuffer) { -73 // Ensure that we load all native bits as otherwise it may fail when try to use native methods in IovArray -74 IoUring.ensureAvailability(); -75 this.ringBuffer = requireNonNull(ringBuffer, "ringBuffer"); -76 registrations = new IntObjectHashMap<>(); -77 eventfd = Native.newBlockingEventFd(); -78 eventfdReadBuf = PlatformDependent.allocateMemory(8); -79 } -80 -81 @Override -82 public int run(IoExecutionContext context) { -83 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); -84 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); -85 if (!completionQueue.hasCompletions() && context.canBlock()) { -86 if (eventfdReadSubmitted == 0) { -87 submitEventFdRead(); -88 } -89 if (context.deadlineNanos() != -1) { -90 submitTimeout(context); -91 } -92 submissionQueue.submitAndWait(); -93 } else { -94 submissionQueue.submit(); -95 } -96 return completionQueue.process(this::handle); -97 } -98 -99 private void handle(int res, int flags, int id, byte op, short data) { -100 if (id == EVENTFD_ID) { -101 handleEventFdRead(); -102 return; -103 } -104 if (id == RINGFD_ID) { -105 if (op == Native.IORING_OP_NOP && data == RING_CLOSE) { -106 completeRingClose(); -107 } -108 return; -109 } -110 DefaultIoUringIoRegistration registration = registrations.get(id); -111 if (registration == null) { -112 logger.debug("ignoring {} completion for unknown registration (id={}, res={})", -113 Native.opToStr(op), id, res); -114 return; -115 } -116 registration.handle(res, flags, op, data); -117 } -118 -119 private void handleEventFdRead() { -120 eventfdReadSubmitted = 0; -121 if (!eventFdClosing) { -122 eventfdAsyncNotify.set(false); -123 submitEventFdRead(); -124 } -125 } -126 -127 private void submitEventFdRead() { -128 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); -129 eventfdReadSubmitted = submissionQueue.addEventFdRead( -130 eventfd.intValue(), eventfdReadBuf, 0, 8, EVENTFD_ID, (short) 0); -131 } -132 -133 private void submitTimeout(IoExecutionContext context) { -134 long delayNanos = context.delayNanos(System.nanoTime()); -135 ringBuffer.ioUringSubmissionQueue().addTimeout( -136 ringBuffer.fd(), delayNanos, RINGFD_ID, (short) 0); -137 } -138 -139 @Override -140 public void prepareToDestroy() { -141 shuttingDown = true; -142 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); -143 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); -144 -145 List<DefaultIoUringIoRegistration> copy = new ArrayList<>(registrations.values()); -146 // Ensure all previously submitted IOs get to complete before closing all fds. -147 submissionQueue.addNop(ringBuffer.fd(), Native.IOSQE_IO_DRAIN, RINGFD_ID, (short) 0); -148 -149 for (DefaultIoUringIoRegistration registration: copy) { -150 registration.close(); -151 if (submissionQueue.count() > 0) { -152 submissionQueue.submit(); -153 } -154 if (completionQueue.hasCompletions()) { -155 completionQueue.process(this::handle); -156 } -157 } -158 } -159 -160 @Override -161 public void destroy() { -162 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); -163 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); -164 drainEventFd(); -165 if (submissionQueue.remaining() < 2) { -166 // We need to submit 2 linked operations. Since they are linked, we cannot allow a submit-call to -167 // separate them. We don't have enough room (< 2) in the queue, so we submit now to make more room. -168 submissionQueue.submit(); -169 } -170 // Try to drain all the IO from the queue first... -171 submissionQueue.addNop(ringBuffer.fd(), Native.IOSQE_IO_DRAIN, RINGFD_ID, (short) 0); -172 // ... but only wait for 200 milliseconds on this -173 submissionQueue.addLinkTimeout(ringBuffer.fd(), TimeUnit.MILLISECONDS.toNanos(200), RINGFD_ID, (short) 0); -174 submissionQueue.submitAndWait(); -175 completionQueue.process(this::handle); -176 completeRingClose(); -177 } -178 -179 // We need to prevent the race condition where a wakeup event is submitted to a file descriptor that has -180 // already been freed (and potentially reallocated by the OS). Because submitted events is gated on the -181 // `eventfdAsyncNotify` flag we can close the gate but may need to read any outstanding events that have -182 // (or will) be written. -183 private void drainEventFd() { -184 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); -185 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); -186 assert !eventFdClosing; -187 eventFdClosing = true; -188 boolean eventPending = eventfdAsyncNotify.getAndSet(true); -189 if (eventPending) { -190 // There is an event that has been or will be written by another thread, so we must wait for the event. -191 // Make sure we're actually listening for writes to the event fd. -192 while (eventfdReadSubmitted == 0) { -193 submitEventFdRead(); -194 submissionQueue.submit(); -195 } -196 // Drain the eventfd of the pending wakup. -197 class DrainFdEventCallback implements CompletionCallback { -198 boolean eventFdDrained; -199 -200 @Override -201 public void handle(int res, int flags, int id, byte op, short data) { -202 if (id == EVENTFD_ID) { -203 eventFdDrained = true; -204 } -205 IoUringIoHandler.this.handle(res, flags, id, op, data); -206 } -207 } -208 final DrainFdEventCallback handler = new DrainFdEventCallback(); -209 completionQueue.process(handler); -210 while (!handler.eventFdDrained) { -211 submissionQueue.submitAndWait(); -212 completionQueue.process(handler); -213 } -214 } -215 // We've consumed any pending eventfd read and `eventfdAsyncNotify` should never -216 // transition back to false, thus we should never have any more events written. -217 // So, if we have a read event pending, we can cancel it. -218 if (eventfdReadSubmitted != 0) { -219 submissionQueue.addCancel(eventfd.intValue(), eventfdReadSubmitted, EVENTFD_ID); -220 eventfdReadSubmitted = 0; -221 submissionQueue.submit(); -222 } -223 } -224 -225 private void completeRingClose() { -226 if (closeCompleted) { -227 // already done. -228 return; -229 } -230 closeCompleted = true; -231 ringBuffer.close(); -232 try { -233 eventfd.close(); -234 } catch (IOException e) { -235 logger.warn("Failed to close eventfd", e); -236 } -237 PlatformDependent.freeMemory(eventfdReadBuf); -238 } -239 -240 @Override -241 public IoRegistration register(IoEventLoop eventLoop, IoHandle handle) throws Exception { -242 IoUringIoHandle ioHandle = cast(handle); -243 if (shuttingDown) { -244 throw new RejectedExecutionException("IoEventLoop is shutting down"); -245 } -246 DefaultIoUringIoRegistration registration = new DefaultIoUringIoRegistration(eventLoop, ioHandle); -247 for (;;) { -248 int id = nextRegistrationId(); -249 DefaultIoUringIoRegistration old = registrations.put(id, registration); -250 if (old != null) { -251 assert old.handle != registration.handle; -252 registrations.put(id, old); -253 } else { -254 registration.setId(id); -255 break; -256 } -257 } -258 -259 ringBuffer.ioUringSubmissionQueue().incrementHandledFds(); -260 return registration; -261 } +71 private static final int INVALID_ID = 0; +72 +73 IoUringIoHandler(RingBuffer ringBuffer) { +74 // Ensure that we load all native bits as otherwise it may fail when try to use native methods in IovArray +75 IoUring.ensureAvailability(); +76 this.ringBuffer = requireNonNull(ringBuffer, "ringBuffer"); +77 registrations = new IntObjectHashMap<>(); +78 eventfd = Native.newBlockingEventFd(); +79 eventfdReadBuf = PlatformDependent.allocateMemory(8); +80 } +81 +82 @Override +83 public int run(IoExecutionContext context) { +84 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); +85 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); +86 if (!completionQueue.hasCompletions() && context.canBlock()) { +87 if (eventfdReadSubmitted == 0) { +88 submitEventFdRead(); +89 } +90 if (context.deadlineNanos() != -1) { +91 submitTimeout(context); +92 } +93 submissionQueue.submitAndWait(); +94 } else { +95 submissionQueue.submit(); +96 } +97 return completionQueue.process(this::handle); +98 } +99 +100 private void handle(int res, int flags, int id, byte op, short data) { +101 if (id == EVENTFD_ID) { +102 handleEventFdRead(); +103 return; +104 } +105 if (id == RINGFD_ID) { +106 if (op == Native.IORING_OP_NOP && data == RING_CLOSE) { +107 completeRingClose(); +108 } +109 return; +110 } +111 DefaultIoUringIoRegistration registration = registrations.get(id); +112 if (registration == null) { +113 logger.debug("ignoring {} completion for unknown registration (id={}, res={})", +114 Native.opToStr(op), id, res); +115 return; +116 } +117 registration.handle(res, flags, op, data); +118 } +119 +120 private void handleEventFdRead() { +121 eventfdReadSubmitted = 0; +122 if (!eventFdClosing) { +123 eventfdAsyncNotify.set(false); +124 submitEventFdRead(); +125 } +126 } +127 +128 private void submitEventFdRead() { +129 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); +130 eventfdReadSubmitted = submissionQueue.addEventFdRead( +131 eventfd.intValue(), eventfdReadBuf, 0, 8, EVENTFD_ID, (short) 0); +132 } +133 +134 private void submitTimeout(IoExecutionContext context) { +135 long delayNanos = context.delayNanos(System.nanoTime()); +136 ringBuffer.ioUringSubmissionQueue().addTimeout( +137 ringBuffer.fd(), delayNanos, RINGFD_ID, (short) 0); +138 } +139 +140 @Override +141 public void prepareToDestroy() { +142 shuttingDown = true; +143 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); +144 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); +145 +146 List<DefaultIoUringIoRegistration> copy = new ArrayList<>(registrations.values()); +147 +148 for (DefaultIoUringIoRegistration registration: copy) { +149 registration.close(); +150 } +151 +152 // Ensure all previously submitted IOs get to complete before tearing down everything. +153 submissionQueue.addNop(ringBuffer.fd(), (byte) Native.IOSQE_IO_DRAIN, RINGFD_ID, (short) 0); +154 submissionQueue.submit(); +155 while (completionQueue.hasCompletions()) { +156 completionQueue.process(this::handle); +157 +158 if (submissionQueue.count() > 0) { +159 submissionQueue.submit(); +160 } +161 } +162 } +163 +164 @Override +165 public void destroy() { +166 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); +167 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); +168 drainEventFd(); +169 if (submissionQueue.remaining() < 2) { +170 // We need to submit 2 linked operations. Since they are linked, we cannot allow a submit-call to +171 // separate them. We don't have enough room (< 2) in the queue, so we submit now to make more room. +172 submissionQueue.submit(); +173 } +174 // Try to drain all the IO from the queue first... +175 submissionQueue.addNop(ringBuffer.fd(), (byte) Native.IOSQE_IO_DRAIN, RINGFD_ID, (short) 0); +176 // ... but only wait for 200 milliseconds on this +177 submissionQueue.addLinkTimeout(ringBuffer.fd(), TimeUnit.MILLISECONDS.toNanos(200), RINGFD_ID, (short) 0); +178 submissionQueue.submitAndWait(); +179 completionQueue.process(this::handle); +180 completeRingClose(); +181 } +182 +183 // We need to prevent the race condition where a wakeup event is submitted to a file descriptor that has +184 // already been freed (and potentially reallocated by the OS). Because submitted events is gated on the +185 // `eventfdAsyncNotify` flag we can close the gate but may need to read any outstanding events that have +186 // (or will) be written. +187 private void drainEventFd() { +188 CompletionQueue completionQueue = ringBuffer.ioUringCompletionQueue(); +189 SubmissionQueue submissionQueue = ringBuffer.ioUringSubmissionQueue(); +190 assert !eventFdClosing; +191 eventFdClosing = true; +192 boolean eventPending = eventfdAsyncNotify.getAndSet(true); +193 if (eventPending) { +194 // There is an event that has been or will be written by another thread, so we must wait for the event. +195 // Make sure we're actually listening for writes to the event fd. +196 while (eventfdReadSubmitted == 0) { +197 submitEventFdRead(); +198 submissionQueue.submit(); +199 } +200 // Drain the eventfd of the pending wakup. +201 class DrainFdEventCallback implements CompletionCallback { +202 boolean eventFdDrained; +203 +204 @Override +205 public void handle(int res, int flags, int id, byte op, short data) { +206 if (id == EVENTFD_ID) { +207 eventFdDrained = true; +208 } +209 IoUringIoHandler.this.handle(res, flags, id, op, data); +210 } +211 } +212 final DrainFdEventCallback handler = new DrainFdEventCallback(); +213 completionQueue.process(handler); +214 while (!handler.eventFdDrained) { +215 submissionQueue.submitAndWait(); +216 completionQueue.process(handler); +217 } +218 } +219 // We've consumed any pending eventfd read and `eventfdAsyncNotify` should never +220 // transition back to false, thus we should never have any more events written. +221 // So, if we have a read event pending, we can cancel it. +222 if (eventfdReadSubmitted != 0) { +223 submissionQueue.addCancel(eventfd.intValue(), eventfdReadSubmitted, EVENTFD_ID); +224 eventfdReadSubmitted = 0; +225 submissionQueue.submit(); +226 } +227 } +228 +229 private void completeRingClose() { +230 if (closeCompleted) { +231 // already done. +232 return; +233 } +234 closeCompleted = true; +235 ringBuffer.close(); +236 try { +237 eventfd.close(); +238 } catch (IOException e) { +239 logger.warn("Failed to close eventfd", e); +240 } +241 PlatformDependent.freeMemory(eventfdReadBuf); +242 } +243 +244 @Override +245 public IoRegistration register(IoEventLoop eventLoop, IoHandle handle) throws Exception { +246 IoUringIoHandle ioHandle = cast(handle); +247 if (shuttingDown) { +248 throw new RejectedExecutionException("IoEventLoop is shutting down"); +249 } +250 DefaultIoUringIoRegistration registration = new DefaultIoUringIoRegistration(eventLoop, ioHandle); +251 for (;;) { +252 int id = nextRegistrationId(); +253 DefaultIoUringIoRegistration old = registrations.put(id, registration); +254 if (old != null) { +255 assert old.handle != registration.handle; +256 registrations.put(id, old); +257 } else { +258 registration.setId(id); +259 break; +260 } +261 } 262 -263 private int nextRegistrationId() { -264 int id; -265 do { -266 id = nextRegistrationId++; -267 } while (id == RINGFD_ID || id == EVENTFD_ID); -268 return id; -269 } -270 -271 private final class DefaultIoUringIoRegistration implements IoUringIoRegistration { -272 private final Promise<?> cancellationPromise; -273 private final IoEventLoop eventLoop; -274 private final IoUringIoEvent event = new IoUringIoEvent(0, 0, (byte) 0, (short) 0); -275 final IoUringIoHandle handle; -276 -277 private boolean removeLater; -278 private int outstandingCompletions; -279 private int id; +263 ringBuffer.ioUringSubmissionQueue().incrementHandledFds(); +264 return registration; +265 } +266 +267 private int nextRegistrationId() { +268 int id; +269 do { +270 id = nextRegistrationId++; +271 } while (id == RINGFD_ID || id == EVENTFD_ID || id == INVALID_ID); +272 return id; +273 } +274 +275 private final class DefaultIoUringIoRegistration implements IoUringIoRegistration { +276 private final Promise<?> cancellationPromise; +277 private final IoEventLoop eventLoop; +278 private final IoUringIoEvent event = new IoUringIoEvent(0, 0, (byte) 0, (short) 0); +279 final IoUringIoHandle handle; 280 -281 DefaultIoUringIoRegistration(IoEventLoop eventLoop, IoUringIoHandle handle) { -282 this.eventLoop = eventLoop; -283 this.handle = handle; -284 this.cancellationPromise = eventLoop.newPromise(); -285 } -286 -287 void setId(int id) { -288 this.id = id; +281 private boolean removeLater; +282 private int outstandingCompletions; +283 private int id; +284 +285 DefaultIoUringIoRegistration(IoEventLoop eventLoop, IoUringIoHandle handle) { +286 this.eventLoop = eventLoop; +287 this.handle = handle; +288 this.cancellationPromise = eventLoop.newPromise(); 289 } 290 -291 @Override -292 public long submit(IoOps ops) { -293 IoUringIoOps ioOps = (IoUringIoOps) ops; -294 long udata = UserData.encode(id, ioOps.opcode(), ioOps.data()); -295 if (!isValid()) { -296 return udata; -297 } -298 if (eventLoop.inEventLoop()) { -299 submit0(ioOps, udata); -300 } else { -301 eventLoop.execute(() -> submit0(ioOps, udata)); -302 } -303 return udata; -304 } -305 -306 private void submit0(IoUringIoOps ioOps, long udata) { -307 ringBuffer.ioUringSubmissionQueue().enqueueSqe(ioOps.opcode(), ioOps.flags(), ioOps.ioPrio(), -308 ioOps.rwFlags(), ioOps.fd(), ioOps.bufferAddress(), ioOps.length(), ioOps.offset(), udata); -309 outstandingCompletions++; -310 } -311 -312 @Override -313 public IoUringIoHandler ioHandler() { -314 return IoUringIoHandler.this; -315 } -316 -317 @Override -318 public void cancel() { -319 if (cancellationPromise.trySuccess(null)) { -320 return; -321 } -322 if (eventLoop.inEventLoop()) { -323 tryRemove(); -324 } else { -325 eventLoop.execute(this::tryRemove); -326 } -327 } -328 -329 @Override -330 public Future<?> cancelFuture() { -331 return cancellationPromise; -332 } -333 -334 private void tryRemove() { -335 if (outstandingCompletions > 0) { -336 // We have some completions outstanding, we will remove the id <-> registration mapping -337 // once these are done. -338 removeLater = true; -339 return; -340 } -341 remove(); -342 } -343 -344 private void remove() { -345 DefaultIoUringIoRegistration old = registrations.remove(id); -346 assert old == this; -347 ringBuffer.ioUringSubmissionQueue().decrementHandledFds(); -348 } -349 -350 void close() { -351 assert eventLoop.inEventLoop(); -352 try { -353 cancel(); -354 } catch (Exception e) { -355 logger.debug("Exception during canceling " + this, e); -356 } -357 try { -358 handle.close(); -359 } catch (Exception e) { -360 logger.debug("Exception during closing " + handle, e); -361 } -362 } -363 -364 void handle(int res, int flags, byte op, short data) { -365 event.update(res, flags, op, data); -366 handle.handle(this, event); -367 if (--outstandingCompletions == 0 && removeLater) { -368 // No more outstanding completions, remove the fd <-> registration mapping now. -369 removeLater = false; -370 remove(); -371 } -372 } -373 } -374 -375 private static IoUringIoHandle cast(IoHandle handle) { -376 if (handle instanceof IoUringIoHandle) { -377 return (IoUringIoHandle) handle; -378 } -379 throw new IllegalArgumentException("IoHandle of type " + StringUtil.simpleClassName(handle) + " not supported"); -380 } -381 -382 @Override -383 public void wakeup(IoEventLoop eventLoop) { -384 if (!eventLoop.inEventLoop() && !eventfdAsyncNotify.getAndSet(true)) { -385 // write to the eventfd which will then trigger an eventfd read completion. -386 Native.eventFdWrite(eventfd.intValue(), 1L); -387 } -388 } -389 -390 @Override -391 public boolean isCompatible(Class<? extends IoHandle> handleType) { -392 return IoUringIoHandle.class.isAssignableFrom(handleType); -393 } -394 -395 /** -396 * {@code byte[]} that can be used as temporary storage to encode the ipv4 address -397 */ -398 byte[] inet4AddressArray() { -399 return inet4AddressArray; -400 } -401 -402 /** -403 * {@code byte[]} that can be used as temporary storage to encode the ipv6 address -404 */ -405 byte[] inet6AddressArray() { -406 return inet6AddressArray; -407 } -408 -409 /** -410 * Create a new {@link IoHandlerFactory} that can be used to create {@link IoUringIoHandler}s. -411 * -412 * @return factory -413 */ -414 public static IoHandlerFactory newFactory() { -415 IoUring.ensureAvailability(); -416 return () -> new IoUringIoHandler(Native.createRingBuffer()); -417 } -418 -419 /** -420 * Create a new {@link IoHandlerFactory} that can be used to create {@link IoUringIoHandler}s. -421 * Each {@link IoUringIoHandler} will use a ring of size {@code ringSize}. -422 * -423 * @param ringSize the size of the ring. -424 * @return factory -425 */ -426 public static IoHandlerFactory newFactory(int ringSize) { -427 IoUring.ensureAvailability(); -428 ObjectUtil.checkPositive(ringSize, "ringSize"); -429 return () -> new IoUringIoHandler(Native.createRingBuffer(ringSize)); -430 } -431 } +291 void setId(int id) { +292 this.id = id; +293 } +294 +295 @Override +296 public long submit(IoOps ops) { +297 IoUringIoOps ioOps = (IoUringIoOps) ops; +298 if (!isValid()) { +299 return INVALID_ID; +300 } +301 long udata = UserData.encode(id, ioOps.opcode(), ioOps.data()); +302 if (eventLoop.inEventLoop()) { +303 submit0(ioOps, udata); +304 } else { +305 eventLoop.execute(() -> submit0(ioOps, udata)); +306 } +307 return udata; +308 } +309 +310 private void submit0(IoUringIoOps ioOps, long udata) { +311 ringBuffer.ioUringSubmissionQueue().enqueueSqe(ioOps.opcode(), ioOps.flags(), ioOps.ioPrio(), +312 ioOps.fd(), ioOps.union1(), ioOps.union2(), ioOps.len(), ioOps.union3(), udata, +313 ioOps.union4(), ioOps.personality(), ioOps.union5(), ioOps.union6() +314 ); +315 outstandingCompletions++; +316 } +317 +318 @Override +319 public IoUringIoHandler ioHandler() { +320 return IoUringIoHandler.this; +321 } +322 +323 @Override +324 public void cancel() { +325 if (!cancellationPromise.trySuccess(null)) { +326 // Already cancelled. +327 return; +328 } +329 if (eventLoop.inEventLoop()) { +330 tryRemove(); +331 } else { +332 eventLoop.execute(this::tryRemove); +333 } +334 } +335 +336 @Override +337 public Future<?> cancelFuture() { +338 return cancellationPromise; +339 } +340 +341 private void tryRemove() { +342 if (outstandingCompletions > 0) { +343 // We have some completions outstanding, we will remove the id <-> registration mapping +344 // once these are done. +345 removeLater = true; +346 return; +347 } +348 remove(); +349 } +350 +351 private void remove() { +352 DefaultIoUringIoRegistration old = registrations.remove(id); +353 assert old == this; +354 ringBuffer.ioUringSubmissionQueue().decrementHandledFds(); +355 } +356 +357 void close() { +358 // Closing the handle will also cancel the registration. +359 // It's important that we not manually cancel as close() might need to submit some work to the ring. +360 assert eventLoop.inEventLoop(); +361 try { +362 handle.close(); +363 } catch (Exception e) { +364 logger.debug("Exception during closing " + handle, e); +365 } +366 } +367 +368 void handle(int res, int flags, byte op, short data) { +369 event.update(res, flags, op, data); +370 handle.handle(this, event); +371 if (--outstandingCompletions == 0 && removeLater) { +372 // No more outstanding completions, remove the fd <-> registration mapping now. +373 removeLater = false; +374 remove(); +375 } +376 } +377 } +378 +379 private static IoUringIoHandle cast(IoHandle handle) { +380 if (handle instanceof IoUringIoHandle) { +381 return (IoUringIoHandle) handle; +382 } +383 throw new IllegalArgumentException("IoHandle of type " + StringUtil.simpleClassName(handle) + " not supported"); +384 } +385 +386 @Override +387 public void wakeup(IoEventLoop eventLoop) { +388 if (!eventLoop.inEventLoop() && !eventfdAsyncNotify.getAndSet(true)) { +389 // write to the eventfd which will then trigger an eventfd read completion. +390 Native.eventFdWrite(eventfd.intValue(), 1L); +391 } +392 } +393 +394 @Override +395 public boolean isCompatible(Class<? extends IoHandle> handleType) { +396 return IoUringIoHandle.class.isAssignableFrom(handleType); +397 } +398 +399 /** +400 * {@code byte[]} that can be used as temporary storage to encode the ipv4 address +401 */ +402 byte[] inet4AddressArray() { +403 return inet4AddressArray; +404 } +405 +406 /** +407 * {@code byte[]} that can be used as temporary storage to encode the ipv6 address +408 */ +409 byte[] inet6AddressArray() { +410 return inet6AddressArray; +411 } +412 +413 /** +414 * Create a new {@link IoHandlerFactory} that can be used to create {@link IoUringIoHandler}s. +415 * +416 * @return factory +417 */ +418 public static IoHandlerFactory newFactory() { +419 IoUring.ensureAvailability(); +420 return () -> new IoUringIoHandler(Native.createRingBuffer()); +421 } +422 +423 /** +424 * Create a new {@link IoHandlerFactory} that can be used to create {@link IoUringIoHandler}s. +425 * Each {@link IoUringIoHandler} will use a ring of size {@code ringSize}. +426 * +427 * @param ringSize the size of the ring. +428 * @return factory +429 */ +430 public static IoHandlerFactory newFactory(int ringSize) { +431 IoUring.ensureAvailability(); +432 ObjectUtil.checkPositive(ringSize, "ringSize"); +433 return () -> new IoUringIoHandler(Native.createRingBuffer(ringSize)); +434 } +435 }
    diff --git a/4.2/xref/io/netty/channel/uring/IoUringIoOps.html b/4.2/xref/io/netty/channel/uring/IoUringIoOps.html index 70876b025a1..e54845494e1 100644 --- a/4.2/xref/io/netty/channel/uring/IoUringIoOps.html +++ b/4.2/xref/io/netty/channel/uring/IoUringIoOps.html @@ -27,337 +27,432 @@ 19 20 /** 21 * {@link IoOps} for implementation for -22 * <a href="https://github.com/axboe/liburing/blob/liburing-2.6/src/include/liburing/io_uring.h">IO_uring</a>. +22 * <a href="https://github.com/axboe/liburing/blob/liburing-2.8/src/include/liburing.h">Io_uring</a>. 23 */ 24 public final class IoUringIoOps implements IoOps { 25 26 private final byte opcode; -27 private final int flags; +27 private final byte flags; 28 private final short ioPrio; 29 private final int fd; -30 private final int rwFlags; -31 private final long bufferAddress; -32 private final int length; -33 private final long offset; +30 private final long union1; +31 private final long union2; +32 private final int len; +33 private final int union3; 34 private final short data; -35 -36 /** -37 * Create a new instance -38 * -39 * @param opcode the operation. -40 * @param flags the flags -41 * @param ioPrio the priority. -42 * @param fd the filedescriptor. -43 * @param rwFlags the flags specific for the op. -44 * @param bufferAddress the bufferaddress -45 * @param length the length -46 * @param offset the offset. -47 * @param data the user data that will be passed back on completion. -48 */ -49 public IoUringIoOps(byte opcode, int flags, short ioPrio, int fd, int rwFlags, long bufferAddress, -50 int length, long offset, short data) { -51 this.opcode = opcode; -52 this.flags = flags; -53 this.ioPrio = ioPrio; -54 this.fd = fd; -55 this.rwFlags = rwFlags; -56 this.bufferAddress = bufferAddress; -57 this.length = length; -58 this.offset = offset; -59 this.data = data; -60 } -61 -62 /** -63 * Returns the filedescriptor. -64 * -65 * @return fd -66 */ -67 public int fd() { -68 return fd; -69 } -70 -71 /** -72 * Returns the opcode. -73 * -74 * @return opcode -75 */ -76 public byte opcode() { -77 return opcode; -78 } -79 -80 /** -81 * Returns the flags that will be applied. -82 * -83 * @return flags -84 */ -85 public int flags() { -86 return flags; -87 } -88 -89 /** -90 * Returns the priority. -91 * -92 * @return ioPrio -93 */ -94 public short ioPrio() { -95 return ioPrio; -96 } -97 -98 /** -99 * Returns the rwFlags that will be applied. These are specific to the opcode. -100 * -101 * @return rwFlags -102 */ -103 public int rwFlags() { -104 return rwFlags; -105 } -106 -107 /** -108 * Returns the bufferAddress that will be used. This is specific to the opcode. -109 * -110 * @return bufferAddress -111 */ -112 public long bufferAddress() { -113 return bufferAddress; -114 } -115 -116 /** -117 * Returns the length that will be used. This is specific to the opcode. -118 * -119 * @return length -120 */ -121 public int length() { -122 return length; -123 } -124 -125 /** -126 * Returns the offset that will be used. This is specific to the opcode. -127 * -128 * @return offset -129 */ -130 public long offset() { -131 return offset; -132 } -133 -134 /** -135 * Returns the data that the user attached to the op. This data will be passed back on completion. -136 * -137 * @return data -138 */ -139 public short data() { -140 return data; -141 } -142 -143 @Override -144 public String toString() { -145 return "IOUringIoOps{" + -146 "opcode=" + opcode + -147 ", flags=" + flags + -148 ", ioPrio=" + ioPrio + -149 ", fd=" + fd + -150 ", rwFlags=" + rwFlags + -151 ", bufferAddress=" + bufferAddress + -152 ", length=" + length + -153 ", offset=" + offset + -154 ", data=" + data + -155 '}'; -156 } -157 -158 /** -159 * Returns a new {@code OP_ASYNC_CANCEL} {@link IoUringIoOps}. -160 * -161 * @param fd the filedescriptor -162 * @param flags the flags. -163 * @param userData the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled. -164 * The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}. -165 * @param data the data -166 * @return ops. -167 */ -168 public static IoUringIoOps newAsyncCancel(int fd, int flags, long userData, short data) { -169 // Best effort to cancel the -170 return new IoUringIoOps(Native.IORING_OP_ASYNC_CANCEL, flags, (short) 0, fd, 0, -171 userData, 0, 0, data); -172 } -173 -174 /** -175 * Returns a new {@code OP_CLOSE} {@link IoUringIoOps}. -176 * -177 * @param fd the filedescriptor -178 * @param flags the flags. -179 * @param data the data -180 * @return ops. -181 */ -182 public static IoUringIoOps newClose(int fd, int flags, short data) { -183 return new IoUringIoOps(Native.IORING_OP_CLOSE, flags, (short) 0, fd, 0, 0, 0, 0, data); -184 } -185 -186 /** -187 * Returns a new {@code OP_POLL_ADD} {@link IoUringIoOps}. -188 * -189 * @param fd the filedescriptor -190 * @param flags the flags. -191 * @param mask the mask. -192 * @param data the data -193 * @return ops. -194 */ -195 public static IoUringIoOps newPollAdd(int fd, int flags, int mask, short data) { -196 return new IoUringIoOps(Native.IORING_OP_POLL_ADD, flags, (short) 0, fd, mask, 0, 0, 0, data); +35 private final short personality; +36 private final short union4; +37 private final int union5; +38 private final long union6; +39 +40 /** +41 * Create a new instance which represents the {@code io_uring_sqe} struct. +42 * +43 * <pre>{@code +44 * struct io_uring_sqe { +45 * __u8 opcode; // type of operation for this sqe +46 * __u8 flags; // IOSQE_ flags +47 * __u16 ioprio; // ioprio for the request +48 * __s32 fd; // file descriptor to do IO on +49 * +50 * union { // union1 +51 * __u64 off; // offset into file +52 * __u64 addr2; +53 * struct { +54 * __u32 cmd_op; +55 * __u32 __pad1; +56 * }; +57 * }; +58 * +59 * union { // union2 +60 * __u64 addr; // pointer to buffer or iovecs +61 * __u64 splice_off_in; +62 * struct { +63 * __u32 level; +64 * __u32 optname; +65 * }; +66 * }; +67 * __u32 len; // buffer size or number of iovecs +68 * +69 * union { // union3 +70 * __kernel_rwf_t rw_flags; +71 * __u32 fsync_flags; +72 * __u16 poll_events; // compatibility +73 * __u32 poll32_events; // word-reversed for BE +74 * __u32 sync_range_flags; +75 * __u32 msg_flags; +76 * __u32 timeout_flags; +77 * __u32 accept_flags; +78 * __u32 cancel_flags; +79 * __u32 open_flags; +80 * __u32 statx_flags; +81 * __u32 fadvise_advice; +82 * __u32 splice_flags; +83 * __u32 rename_flags; +84 * __u32 unlink_flags; +85 * __u32 hardlink_flags; +86 * __u32 xeattr_flags; +87 * __u32 msg_ring_flags; +88 * __u32 uring_cmd_flags; +89 * __u32 waitid_flags; +90 * __u32 futex_flags; +91 * __u32 install_fd_flags; +92 * __u32 nop_flags; +93 * }; +94 * __u64 user_data; // data to be passed back at completion time +95 * // pack this to avoid bogus arm OABI complaints +96 * +97 * union { // union4 +98 * +99 * // index into fixed buffers, if used +100 * __u16 buf_index; +101 * // for grouped buffer selection +102 * __u16 buf_group; +103 * }__attribute__((packed)); +104 * // personality to use, if used +105 * __u16 personality; +106 * +107 * union { // union5 +108 * +109 * __s32 splice_fd_in; +110 * __u32 file_index; +111 * __u32 optlen; +112 * struct { +113 * __u16 addr_len; +114 * __u16 __pad3[ 1]; +115 * }; +116 * }; +117 * +118 * union { // union6 +119 * +120 * struct { +121 * __u64 addr3; +122 * __u64 __pad2[ 1]; +123 * }; +124 * __u64 optval; +125 * // +126 * // If the ring is initialized with IORING_SETUP_SQE128, then +127 * // this field is used for 80 bytes of arbitrary command data +128 * __u8 cmd[ 0]; +129 * }; +130 * }; +131 * } +132 * </pre> +133 */ +134 public IoUringIoOps(byte opcode, byte flags, short ioPrio, int fd, long union1, long union2, int len, int union3, +135 short data, short union4, short personality, int union5, long union6) { +136 this.opcode = opcode; +137 this.flags = flags; +138 this.ioPrio = ioPrio; +139 this.fd = fd; +140 this.union1 = union1; +141 this.union2 = union2; +142 this.len = len; +143 this.union3 = union3; +144 this.data = data; +145 this.union4 = union4; +146 this.personality = personality; +147 this.union5 = union5; +148 this.union6 = union6; +149 } +150 +151 byte opcode() { +152 return opcode; +153 } +154 +155 byte flags() { +156 return flags; +157 } +158 +159 short ioPrio() { +160 return ioPrio; +161 } +162 +163 int fd() { +164 return fd; +165 } +166 +167 long union1() { +168 return union1; +169 } +170 +171 long union2() { +172 return union2; +173 } +174 +175 int len() { +176 return len; +177 } +178 +179 int union3() { +180 return union3; +181 } +182 +183 short data() { +184 return data; +185 } +186 +187 short personality() { +188 return personality; +189 } +190 +191 short union4() { +192 return union4; +193 } +194 +195 int union5() { +196 return union5; 197 } 198 -199 /** -200 * Returns a new {@code OP_SENDMSG} {@link IoUringIoOps}. -201 * -202 * @param fd the filedescriptor -203 * @param flags the flags. -204 * @param msgFlags the msg flags. -205 * @param data the data -206 * @return ops. -207 */ -208 public static IoUringIoOps newSendmsg(int fd, int flags, int msgFlags, long address, short data) { -209 return new IoUringIoOps(Native.IORING_OP_SENDMSG, flags, (short) 0, fd, msgFlags, address, 1, 0, data); -210 } -211 -212 /** -213 * Returns a new {@code OP_CONNECT} {@link IoUringIoOps}. -214 * -215 * @param fd the filedescriptor -216 * @param flags the flags. -217 * @param remoteMemoryAddress the memory address of the sockaddr_storage. -218 * @param data the data -219 * @return ops. -220 */ -221 public static IoUringIoOps newConnect(int fd, int flags, long remoteMemoryAddress, short data) { -222 return new IoUringIoOps(Native.IORING_OP_CONNECT, flags, (short) 0, fd, 0, remoteMemoryAddress, -223 0, Native.SIZEOF_SOCKADDR_STORAGE, data); -224 } -225 -226 /** -227 * Returns a new {@code OP_POLL_REMOVE} {@link IoUringIoOps}. -228 * -229 * @param fd the filedescriptor -230 * @param flags the flags. -231 * @param userData the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled. -232 * The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}. -233 * @param data the data -234 * @return ops. -235 */ -236 public static IoUringIoOps newPollRemove(int fd, int flags, long userData, short data) { -237 return new IoUringIoOps(Native.IORING_OP_POLL_REMOVE, flags, (short) 0, fd, 0, userData, 0, 0, data); -238 } -239 -240 /** -241 * Returns a new {@code OP_ACCEPT} {@link IoUringIoOps}. -242 * -243 * @param fd the filedescriptor -244 * @param flags the flags. -245 * @param acceptedAddressMemoryAddress the memory address of the sockaddr_storage. -246 * @param acceptedAddressLengthMemoryAddress the memory address of the length that will be updated once a new -247 * connection was accepted. -248 * @param data the data -249 * @return ops. -250 */ -251 public static IoUringIoOps newAccept(int fd, int flags, int acceptFlags, long acceptedAddressMemoryAddress, -252 long acceptedAddressLengthMemoryAddress, short data) { -253 return new IoUringIoOps(Native.IORING_OP_ACCEPT, flags, (short) 0, fd, acceptFlags, -254 acceptedAddressMemoryAddress, 0, acceptedAddressLengthMemoryAddress, data); -255 } -256 -257 /** -258 * Returns a new {@code OP_WRITEV} {@link IoUringIoOps}. -259 * -260 * @param fd the filedescriptor -261 * @param flags the flags. -262 * @param writevFlags the writev flags. -263 * @param memoryAddress the memory address of the io_vec array. -264 * @param length the length of the io_vec array. -265 * @param data the data -266 * @return ops. -267 */ -268 public static IoUringIoOps newWritev(int fd, int flags, int writevFlags, long memoryAddress, -269 int length, short data) { -270 return new IoUringIoOps(Native.IORING_OP_WRITEV, flags, (short) 0, fd, -271 writevFlags, memoryAddress, length, 0, data); -272 } -273 -274 /** -275 * Returns a new {@code OP_WRITE} {@link IoUringIoOps}. -276 * -277 * @param fd the filedescriptor -278 * @param flags the flags. -279 * @param writeFlags the write flags. -280 * @param memoryAddress the memory address of the buffer -281 * @param length the length of the buffer. -282 * @param data the data -283 * @return ops. -284 */ -285 public static IoUringIoOps newWrite( -286 int fd, int flags, int writeFlags, long memoryAddress, int length, short data) { -287 return new IoUringIoOps(Native.IORING_OP_WRITE, flags, (short) 0, fd, -288 writeFlags, memoryAddress, length, 0, data); -289 } -290 -291 /** -292 * Returns a new {@code OP_RECV} {@link IoUringIoOps}. -293 * -294 * @param fd the filedescriptor -295 * @param flags the flags. -296 * @param recvFlags the recv flags. -297 * @param memoryAddress the memory address of the buffer -298 * @param length the length of the buffer. -299 * @param data the data -300 * @return ops. -301 */ -302 public static IoUringIoOps newRecv( -303 int fd, int flags, int recvFlags, long memoryAddress, int length, short data) { -304 return new IoUringIoOps( -305 Native.IORING_OP_RECV, flags, (short) 0, fd, recvFlags, memoryAddress, length, 0, data); +199 long union6() { +200 return union6; +201 } +202 +203 @Override +204 public String toString() { +205 return "IOUringIoOps{" + +206 "opcode=" + opcode + +207 ", flags=" + flags + +208 ", ioPrio=" + ioPrio + +209 ", fd=" + fd + +210 ", union1=" + union1 + +211 ", union2=" + union2 + +212 ", len=" + len + +213 ", union3=" + union3 + +214 ", data=" + data + +215 ", union4=" + union4 + +216 ", personality=" + personality + +217 ", union5=" + union5 + +218 ", union6=" + union6 + +219 '}'; +220 } +221 +222 /** +223 * Returns a new {@code OP_ASYNC_CANCEL} {@link IoUringIoOps}. +224 * +225 * @param fd the filedescriptor +226 * @param flags the flags. +227 * @param userData the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled. +228 * The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}. +229 * @param data the data +230 * @return ops. +231 */ +232 static IoUringIoOps newAsyncCancel(int fd, byte flags, long userData, short data) { +233 // Best effort to cancel the +234 return new IoUringIoOps(Native.IORING_OP_ASYNC_CANCEL, flags, (short) 0, fd, 0, userData, 0, 0, +235 data, (short) 0, (short) 0, 0, 0); +236 } +237 +238 /** +239 * Returns a new {@code OP_CLOSE} {@link IoUringIoOps}. +240 * +241 * @param fd the filedescriptor +242 * @param flags the flags. +243 * @param data the data +244 * @return ops. +245 */ +246 static IoUringIoOps newClose(int fd, byte flags, short data) { +247 return new IoUringIoOps(Native.IORING_OP_CLOSE, flags, (short) 0, fd, 0L, 0L, 0, 0, data, +248 (short) 0, (short) 0, 0, 0); +249 } +250 +251 /** +252 * Returns a new {@code OP_POLL_ADD} {@link IoUringIoOps}. +253 * +254 * @param fd the filedescriptor +255 * @param flags the flags. +256 * @param mask the mask. +257 * @param data the data +258 * @return ops. +259 */ +260 static IoUringIoOps newPollAdd(int fd, byte flags, int mask, short data) { +261 return new IoUringIoOps(Native.IORING_OP_POLL_ADD, flags, (short) 0, fd, 0L, 0L, 0, mask, data, +262 (short) 0, (short) 0, 0, 0); +263 } +264 +265 /** +266 * Returns a new {@code OP_SENDMSG} {@link IoUringIoOps}. +267 * +268 * @param fd the filedescriptor +269 * @param flags the flags. +270 * @param msgFlags the msg flags. +271 * @param data the data +272 * @return ops. +273 */ +274 static IoUringIoOps newSendmsg(int fd, byte flags, int msgFlags, long address, short data) { +275 return new IoUringIoOps(Native.IORING_OP_SENDMSG, flags, (short) 0, fd, 0L, address, 1, msgFlags, data, +276 (short) 0, (short) 0, 0, 0); +277 } +278 +279 /** +280 * Returns a new {@code OP_CONNECT} {@link IoUringIoOps}. +281 * +282 * @param fd the filedescriptor +283 * @param flags the flags. +284 * @param remoteMemoryAddress the memory address of the sockaddr_storage. +285 * @param data the data +286 * @return ops. +287 */ +288 static IoUringIoOps newConnect(int fd, byte flags, long remoteMemoryAddress, short data) { +289 return new IoUringIoOps(Native.IORING_OP_CONNECT, flags, (short) 0, fd, Native.SIZEOF_SOCKADDR_STORAGE, +290 remoteMemoryAddress, 0, 0, data, (short) 0, (short) 0, 0, 0); +291 } +292 +293 /** +294 * Returns a new {@code OP_POLL_REMOVE} {@link IoUringIoOps}. +295 * +296 * @param fd the filedescriptor +297 * @param flags the flags. +298 * @param userData the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled. +299 * The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}. +300 * @param data the data +301 * @return ops. +302 */ +303 static IoUringIoOps newPollRemove(int fd, byte flags, long userData, short data) { +304 return new IoUringIoOps(Native.IORING_OP_POLL_REMOVE, flags, (short) 0, fd, 0, userData, 0, 0, data, +305 (short) 0, (short) 0, 0, 0); 306 } 307 308 /** -309 * Returns a new {@code OP_RECVMSG} {@link IoUringIoOps}. +309 * Returns a new {@code OP_ACCEPT} {@link IoUringIoOps}. 310 * 311 * @param fd the filedescriptor 312 * @param flags the flags. -313 * @param msgFlags the recvmsg flags. -314 * @param memoryAddress the memory address of the msghdr struct -315 * @param data the data -316 * @return ops. -317 */ -318 public static IoUringIoOps newRecvmsg(int fd, int flags, int msgFlags, long memoryAddress, short data) { -319 return new IoUringIoOps( -320 Native.IORING_OP_RECVMSG, flags, (short) 0, fd, msgFlags, memoryAddress, 1, 0, data); -321 } -322 -323 /** -324 * Returns a new {@code OP_SEND} {@link IoUringIoOps}. -325 * -326 * @param fd the filedescriptor -327 * @param flags the flags. -328 * @param sendFlags the send flags. -329 * @param memoryAddress the memory address of the buffer. -330 * @param length the length of the buffer. -331 * @param data the data -332 * @return ops. -333 */ -334 public static IoUringIoOps newSend( -335 int fd, int flags, int sendFlags, long memoryAddress, int length, short data) { -336 return new IoUringIoOps( -337 Native.IORING_OP_SEND, flags, (short) 0, fd, sendFlags, memoryAddress, length, 0, data); -338 } -339 -340 /** -341 * Returns a new {@code OP_SHUTDOWN} {@link IoUringIoOps}. -342 * -343 * @param fd the filedescriptor -344 * @param flags the flags. -345 * @param how how the shutdown will be done. -346 * @param data the data -347 * @return ops. -348 */ -349 public static IoUringIoOps newShutdown(int fd, int flags, int how, int id, short data) { -350 return new IoUringIoOps(Native.IORING_OP_SHUTDOWN, flags, (short) 0, fd, 0, 0, how, 0, data); -351 } -352 } +313 * @param acceptedAddressMemoryAddress the memory address of the sockaddr_storage. +314 * @param acceptedAddressLengthMemoryAddress the memory address of the length that will be updated once a new +315 * connection was accepted. +316 * @param data the data +317 * @return ops. +318 */ +319 static IoUringIoOps newAccept(int fd, byte flags, int acceptFlags, long acceptedAddressMemoryAddress, +320 long acceptedAddressLengthMemoryAddress, short data) { +321 +322 return new IoUringIoOps(Native.IORING_OP_ACCEPT, flags, (short) 0, fd, acceptedAddressLengthMemoryAddress, +323 acceptedAddressMemoryAddress, 0, acceptFlags, data, (short) 0, (short) 0, 0, 0); +324 } +325 +326 /** +327 * Returns a new {@code OP_WRITEV} {@link IoUringIoOps}. +328 * +329 * @param fd the filedescriptor +330 * @param flags the flags. +331 * @param writevFlags the writev flags. +332 * @param memoryAddress the memory address of the io_vec array. +333 * @param length the length of the io_vec array. +334 * @param data the data +335 * @return ops. +336 */ +337 static IoUringIoOps newWritev(int fd, byte flags, int writevFlags, long memoryAddress, +338 int length, short data) { +339 return new IoUringIoOps(Native.IORING_OP_WRITEV, flags, (short) 0, fd, +340 0, memoryAddress, length, writevFlags, data, (short) 0, (short) 0, 0, 0); +341 } +342 +343 /** +344 * Returns a new {@code OP_WRITE} {@link IoUringIoOps}. +345 * +346 * @param fd the filedescriptor +347 * @param flags the flags. +348 * @param writeFlags the write flags. +349 * @param memoryAddress the memory address of the buffer +350 * @param length the length of the buffer. +351 * @param data the data +352 * @return ops. +353 */ +354 static IoUringIoOps newWrite( +355 int fd, byte flags, int writeFlags, long memoryAddress, int length, short data) { +356 return new IoUringIoOps(Native.IORING_OP_WRITE, flags, (short) 0, fd, +357 0, memoryAddress, length, writeFlags, data, (short) 0, (short) 0, 0, 0); +358 } +359 +360 /** +361 * Returns a new {@code OP_RECV} {@link IoUringIoOps}. +362 * +363 * @param fd the filedescriptor +364 * @param flags the flags. +365 * @param recvFlags the recv flags. +366 * @param memoryAddress the memory address of the buffer +367 * @param length the length of the buffer. +368 * @param data the data +369 * @return ops. +370 */ +371 static IoUringIoOps newRecv( +372 int fd, byte flags, int recvFlags, long memoryAddress, int length, short data) { +373 return new IoUringIoOps(Native.IORING_OP_RECV, flags, (short) 0, fd, +374 0, memoryAddress, length, recvFlags, data, (short) 0, (short) 0, 0, 0); +375 } +376 +377 /** +378 * Returns a new {@code OP_RECVMSG} {@link IoUringIoOps}. +379 * +380 * @param fd the filedescriptor +381 * @param flags the flags. +382 * @param msgFlags the recvmsg flags. +383 * @param memoryAddress the memory address of the msghdr struct +384 * @param data the data +385 * @return ops. +386 */ +387 static IoUringIoOps newRecvmsg(int fd, byte flags, int msgFlags, long memoryAddress, short data) { +388 return new IoUringIoOps( +389 Native.IORING_OP_RECVMSG, flags, (short) 0, fd, 0L, memoryAddress, 1, msgFlags, data, +390 (short) 0, (short) 0, 0, 0); +391 } +392 +393 /** +394 * Returns a new {@code OP_SEND} {@link IoUringIoOps}. +395 * +396 * @param fd the filedescriptor +397 * @param flags the flags. +398 * @param sendFlags the send flags. +399 * @param memoryAddress the memory address of the buffer. +400 * @param length the length of the buffer. +401 * @param data the data +402 * @return ops. +403 */ +404 static IoUringIoOps newSend( +405 int fd, byte flags, int sendFlags, long memoryAddress, int length, short data) { +406 return new IoUringIoOps(Native.IORING_OP_SEND, flags, (short) 0, fd, +407 memoryAddress, 0L, length, sendFlags, data, (short) 0, (short) 0, 0, 0); +408 } +409 +410 /** +411 * Returns a new {@code OP_SHUTDOWN} {@link IoUringIoOps}. +412 * +413 * @param fd the filedescriptor +414 * @param flags the flags. +415 * @param how how the shutdown will be done. +416 * @param data the data +417 * @return ops. +418 */ +419 static IoUringIoOps newShutdown(int fd, byte flags, int how, short data) { +420 return new IoUringIoOps(Native.IORING_OP_SHUTDOWN, flags, (short) 0, fd, 0, 0, how, 0, data, +421 (short) 0, (short) 0, 0, 0); +422 } +423 +424 /** +425 * +426 * Returns a new {@code OP_SPLICE} {@link IoUringIoOps}. +427 * +428 * @param fd_in the filedescriptor +429 * @param off_in the filedescriptor offset +430 * @param fd_out the filedescriptor +431 * @param off_out the filedescriptor offset +432 * @param nbytes splice bytes +433 * @param splice_flags the flag +434 * @param data the data +435 * @return ops. +436 */ +437 static IoUringIoOps newSplice(int fd_in, long off_in, +438 int fd_out, long off_out, +439 int nbytes, +440 int splice_flags, +441 short data) { +442 return new IoUringIoOps( +443 Native.IORING_OP_SPLICE, (byte) 0, (short) 0, fd_out, off_out, off_in, +444 nbytes, splice_flags, data, (short) 0, (short) 0, fd_in, 0 +445 ); +446 } +447 }
    diff --git a/4.2/xref/io/netty/channel/uring/IoUringIoRegistration.html b/4.2/xref/io/netty/channel/uring/IoUringIoRegistration.html index 7c01a06e034..40eeb0941ba 100644 --- a/4.2/xref/io/netty/channel/uring/IoUringIoRegistration.html +++ b/4.2/xref/io/netty/channel/uring/IoUringIoRegistration.html @@ -36,13 +36,15 @@ 28 * 29 * @param ops ops. 30 * @return the u_data of the {@link IoUringIoOps}. This can be used to cancel a previous submitted -31 * {@link IoUringIoOps}. -32 */ -33 @Override -34 long submit(IoOps ops); -35 -36 void cancel(); -37 } +31 * {@link IoUringIoOps}. If submission failed as the registration is not valid anymore this method will return +32 * {@code 0}. +33 */ +34 @Override +35 long submit(IoOps ops); +36 +37 @Override +38 void cancel(); +39 }
    diff --git a/4.2/xref/io/netty/channel/uring/MsgHdrMemoryArray.html b/4.2/xref/io/netty/channel/uring/MsgHdrMemoryArray.html index 298fe411a14..6ab01ae9565 100644 --- a/4.2/xref/io/netty/channel/uring/MsgHdrMemoryArray.html +++ b/4.2/xref/io/netty/channel/uring/MsgHdrMemoryArray.html @@ -26,7 +26,7 @@ 18 import java.util.Arrays; 19 20 final class MsgHdrMemoryArray { -21 static final long NO_ID = -1; +21 static final long NO_ID = 0; 22 23 private final MsgHdrMemory[] hdrs; 24 private final int capacity; diff --git a/4.2/xref/io/netty/channel/uring/Native.html b/4.2/xref/io/netty/channel/uring/Native.html index ef8ad22df6d..c9b38f8a8df 100644 --- a/4.2/xref/io/netty/channel/uring/Native.html +++ b/4.2/xref/io/netty/channel/uring/Native.html @@ -23,420 +23,435 @@ 15 */ 16 package io.netty.channel.uring; 17 -18 import io.netty.util.internal.ObjectUtil; -19 import io.netty.util.internal.logging.InternalLogger; -20 import io.netty.util.internal.logging.InternalLoggerFactory; -21 import io.netty.channel.unix.FileDescriptor; -22 import io.netty.channel.unix.PeerCredentials; -23 import io.netty.channel.unix.Unix; -24 import io.netty.util.internal.ClassInitializerUtil; -25 import io.netty.util.internal.NativeLibraryLoader; -26 import io.netty.util.internal.PlatformDependent; -27 import io.netty.util.internal.SystemPropertyUtil; -28 import io.netty.util.internal.ThrowableUtil; -29 -30 import java.io.File; -31 import java.io.IOException; -32 import java.nio.channels.Selector; -33 import java.nio.file.Path; -34 import java.util.Arrays; -35 import java.util.Locale; -36 -37 final class Native { -38 private static final InternalLogger logger = InternalLoggerFactory.getInstance(Native.class); -39 static final int DEFAULT_RING_SIZE = Math.max(64, SystemPropertyUtil.getInt("io.netty.iouring.ringSize", 4096)); -40 -41 static { -42 Selector selector = null; -43 try { -44 // We call Selector.open() as this will under the hood cause IOUtil to be loaded. -45 // This is a workaround for a possible classloader deadlock that could happen otherwise: -46 // -47 // See https://github.com/netty/netty/issues/10187 -48 selector = Selector.open(); -49 } catch (IOException ignore) { -50 // Just ignore -51 } -52 -53 // Preload all classes that will be used in the OnLoad(...) function of JNI to eliminate the possiblity of a -54 // class-loader deadlock. This is a workaround for https://github.com/netty/netty/issues/11209. -55 -56 // This needs to match all the classes that are loaded via NETTY_JNI_UTIL_LOAD_CLASS or looked up via -57 // NETTY_JNI_UTIL_FIND_CLASS. -58 ClassInitializerUtil.tryLoadClasses( -59 Native.class, -60 // netty_io_uring_linuxsocket -61 PeerCredentials.class, java.io.FileDescriptor.class -62 ); -63 -64 File tmpDir = PlatformDependent.tmpdir(); -65 Path tmpFile = tmpDir.toPath().resolve("netty_io_uring.tmp"); -66 try { -67 // First, try calling a side-effect free JNI method to see if the library was already -68 // loaded by the application. -69 Native.createFile(tmpFile.toString()); -70 } catch (UnsatisfiedLinkError ignore) { -71 // The library was not previously loaded, load it now. -72 loadNativeLibrary(); -73 } finally { -74 tmpFile.toFile().delete(); -75 try { -76 if (selector != null) { -77 selector.close(); -78 } -79 } catch (IOException ignore) { -80 // Just ignore -81 } -82 } -83 Unix.registerInternal(Native::registerUnix); -84 } -85 -86 static final int SOCK_NONBLOCK = NativeStaticallyReferencedJniMethods.sockNonblock(); -87 static final int SOCK_CLOEXEC = NativeStaticallyReferencedJniMethods.sockCloexec(); -88 static final short AF_INET = (short) NativeStaticallyReferencedJniMethods.afInet(); -89 static final short AF_INET6 = (short) NativeStaticallyReferencedJniMethods.afInet6(); -90 static final int SIZEOF_SOCKADDR_STORAGE = NativeStaticallyReferencedJniMethods.sizeofSockaddrStorage(); -91 static final int SIZEOF_SOCKADDR_IN = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn(); -92 static final int SIZEOF_SOCKADDR_IN6 = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn6(); -93 static final int SOCKADDR_IN_OFFSETOF_SIN_FAMILY = -94 NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinFamily(); -95 static final int SOCKADDR_IN_OFFSETOF_SIN_PORT = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinPort(); -96 static final int SOCKADDR_IN_OFFSETOF_SIN_ADDR = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinAddr(); -97 static final int IN_ADDRESS_OFFSETOF_S_ADDR = NativeStaticallyReferencedJniMethods.inAddressOffsetofSAddr(); -98 static final int SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY = -99 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Family(); -100 static final int SOCKADDR_IN6_OFFSETOF_SIN6_PORT = -101 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Port(); -102 static final int SOCKADDR_IN6_OFFSETOF_SIN6_FLOWINFO = -103 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Flowinfo(); -104 static final int SOCKADDR_IN6_OFFSETOF_SIN6_ADDR = -105 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Addr(); -106 static final int SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID = -107 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6ScopeId(); -108 static final int IN6_ADDRESS_OFFSETOF_S6_ADDR = NativeStaticallyReferencedJniMethods.in6AddressOffsetofS6Addr(); -109 static final int SIZEOF_SIZE_T = NativeStaticallyReferencedJniMethods.sizeofSizeT(); -110 static final int SIZEOF_IOVEC = NativeStaticallyReferencedJniMethods.sizeofIovec(); -111 static final int CMSG_SPACE = NativeStaticallyReferencedJniMethods.cmsgSpace(); -112 static final int CMSG_LEN = NativeStaticallyReferencedJniMethods.cmsgLen(); -113 static final int CMSG_OFFSETOF_CMSG_LEN = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgLen(); -114 static final int CMSG_OFFSETOF_CMSG_LEVEL = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgLevel(); -115 static final int CMSG_OFFSETOF_CMSG_TYPE = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgType(); -116 -117 static final int IOVEC_OFFSETOF_IOV_BASE = NativeStaticallyReferencedJniMethods.iovecOffsetofIovBase(); -118 static final int IOVEC_OFFSETOF_IOV_LEN = NativeStaticallyReferencedJniMethods.iovecOffsetofIovLen(); -119 static final int SIZEOF_MSGHDR = NativeStaticallyReferencedJniMethods.sizeofMsghdr(); -120 static final int MSGHDR_OFFSETOF_MSG_NAME = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgName(); -121 static final int MSGHDR_OFFSETOF_MSG_NAMELEN = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgNamelen(); -122 static final int MSGHDR_OFFSETOF_MSG_IOV = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgIov(); -123 static final int MSGHDR_OFFSETOF_MSG_IOVLEN = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgIovlen(); -124 static final int MSGHDR_OFFSETOF_MSG_CONTROL = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgControl(); -125 static final int MSGHDR_OFFSETOF_MSG_CONTROLLEN = -126 NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgControllen(); -127 static final int MSGHDR_OFFSETOF_MSG_FLAGS = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgFlags(); -128 static final int POLLIN = NativeStaticallyReferencedJniMethods.pollin(); -129 static final int POLLOUT = NativeStaticallyReferencedJniMethods.pollout(); -130 static final int POLLRDHUP = NativeStaticallyReferencedJniMethods.pollrdhup(); -131 static final int ERRNO_ECANCELED_NEGATIVE = -NativeStaticallyReferencedJniMethods.ecanceled(); -132 static final int ERRNO_ETIME_NEGATIVE = -NativeStaticallyReferencedJniMethods.etime(); -133 -134 // These constants must be defined to have the same numeric value as their corresponding -135 // ordinal in the enum defined in the io_uring.h header file. -136 // DO NOT CHANGE THESE VALUES! -137 static final byte IORING_OP_NOP = 0; // Specified by IORING_OP_NOP in io_uring.h -138 static final byte IORING_OP_READV = 1; // Specified by IORING_OP_READV in io_uring.h -139 static final byte IORING_OP_WRITEV = 2; // Specified by IORING_OP_WRITEV in io_uring.h -140 static final byte IORING_OP_FSYNC = 3; // Specified by IORING_OP_FSYNC in io_uring.h -141 static final byte IORING_OP_READ_FIXED = 4; // Specified by IORING_OP_READ_FIXED in io_uring.h -142 static final byte IORING_OP_WRITE_FIXED = 5; // Specified by IORING_OP_WRITE_FIXED in io_uring.h -143 static final byte IORING_OP_POLL_ADD = 6; // Specified by IORING_OP_POLL_ADD in io_uring.h -144 static final byte IORING_OP_POLL_REMOVE = 7; // Specified by IORING_OP_POLL_REMOVE in io_uring.h -145 static final byte IORING_OP_SYNC_FILE_RANGE = 8; // Specified by IORING_OP_SYNC_FILE_RANGE in io_uring.h -146 static final byte IORING_OP_SENDMSG = 9; // Specified by IORING_OP_SENDMSG in io_uring.h -147 static final byte IORING_OP_RECVMSG = 10; // Specified by IORING_OP_RECVMSG in io_uring.h -148 static final byte IORING_OP_TIMEOUT = 11; // Specified by IORING_OP_TIMEOUT in io_uring.h -149 static final byte IORING_OP_TIMEOUT_REMOVE = 12; // Specified by IORING_OP_TIMEOUT_REMOVE in io_uring.h -150 static final byte IORING_OP_ACCEPT = 13; // Specified by IORING_OP_ACCEPT in io_uring.h -151 static final byte IORING_OP_ASYNC_CANCEL = 14; // Specified by IORING_OP_ASYNC_CANCEL in io_uring.h -152 static final byte IORING_OP_LINK_TIMEOUT = 15; // Specified by IORING_OP_LINK_TIMEOUT in io_uring.h -153 static final byte IORING_OP_CONNECT = 16; // Specified by IORING_OP_CONNECT in io_uring.h -154 static final byte IORING_OP_FALLOCATE = 17; // Specified by IORING_OP_FALLOCATE in io_uring.h -155 static final byte IORING_OP_OPENAT = 18; // Specified by IORING_OP_OPENAT in io_uring.h -156 static final byte IORING_OP_CLOSE = 19; // Specified by IORING_OP_CLOSE in io_uring.h -157 static final byte IORING_OP_FILES_UPDATE = 20; // Specified by IORING_OP_FILES_UPDATE in io_uring.h -158 static final byte IORING_OP_STATX = 21; // Specified by IORING_OP_STATX in io_uring.h -159 static final byte IORING_OP_READ = 22; // Specified by IORING_OP_READ in io_uring.h -160 static final byte IORING_OP_WRITE = 23; // Specified by IORING_OP_WRITE in io_uring.h -161 static final byte IORING_OP_FADVISE = 24; // Specified by IORING_OP_FADVISE in io_uring.h -162 static final byte IORING_OP_MADVISE = 25; // Specified by IORING_OP_MADVISE in io_uring.h -163 static final byte IORING_OP_SEND = 26; // Specified by IORING_OP_SEND in io_uring.h -164 static final byte IORING_OP_RECV = 27; // Specified by IORING_OP_RECV in io_uring.h -165 static final byte IORING_OP_OPENAT2 = 28; // Specified by IORING_OP_OPENAT2 in io_uring.h -166 static final byte IORING_OP_EPOLL_CTL = 29; // Specified by IORING_OP_EPOLL_CTL in io_uring.h -167 static final byte IORING_OP_SPLICE = 30; // Specified by IORING_OP_SPLICE in io_uring.h -168 static final byte IORING_OP_PROVIDE_BUFFERS = 31; // Specified by IORING_OP_PROVIDE_BUFFERS in io_uring.h -169 static final byte IORING_OP_REMOVE_BUFFERS = 32; // Specified by IORING_OP_REMOVE_BUFFERS in io_uring.h -170 static final byte IORING_OP_TEE = 33; // Specified by IORING_OP_TEE in io_uring.h -171 static final byte IORING_OP_SHUTDOWN = 34; // Specified by IORING_OP_SHUTDOWN in io_uring.h -172 static final byte IORING_OP_RENAMEAT = 35; // Specified by IORING_OP_RENAMEAT in io_uring.h -173 static final byte IORING_OP_UNLINKAT = 36; // Specified by IORING_OP_UNLINKAT in io_uring.h -174 static final byte IORING_OP_MKDIRAT = 37; // Specified by IORING_OP_MKDIRAT in io_uring.h -175 static final byte IORING_OP_SYMLINKAT = 38; // Specified by IORING_OP_SYMLINKAT in io_uring.h -176 static final byte IORING_OP_LINKAT = 39; // Specified by IORING_OP_LINKAT in io_uring.h -177 static final byte IORING_OP_MSG_RING = 40; -178 static final byte IORING_OP_FSETXATTR = 41; -179 static final byte IORING_OP_SETXATTR = 42; -180 static final byte IORING_OP_FGETXATTR = 43; -181 static final byte IORING_OP_GETXATTR = 44; -182 static final byte IORING_OP_SOCKET = 45; -183 static final byte IORING_OP_URING_CMD = 46; -184 static final byte IORING_OP_SEND_ZC = 47; -185 static final byte IORING_OP_SENDMSG_ZC = 48; -186 static final byte IORING_OP_READ_MULTISHOT = 49; -187 static final byte IORING_OP_WAITID = 50; -188 static final byte IORING_OP_FUTEX_WAIT = 51; -189 static final byte IORING_OP_FUTEX_WAKE = 52; -190 static final byte IORING_OP_FUTEX_WAITV = 53; -191 static final byte IORING_OP_FIXED_FD_INSTALL = 54; -192 static final byte IORING_OP_FTRUNCATE = 55; -193 static final byte IORING_CQE_F_SOCK_NONEMPTY = 1 << 2; -194 -195 static String opToStr(byte op) { -196 switch (op) { -197 case IORING_OP_NOP: return "NOP"; -198 case IORING_OP_READV: return "READV"; -199 case IORING_OP_WRITEV: return "WRITEV"; -200 case IORING_OP_FSYNC: return "FSYNC"; -201 case IORING_OP_READ_FIXED: return "READ_FIXED"; -202 case IORING_OP_WRITE_FIXED: return "WRITE_FIXED"; -203 case IORING_OP_POLL_ADD: return "POLL_ADD"; -204 case IORING_OP_POLL_REMOVE: return "POLL_REMOVE"; -205 case IORING_OP_SYNC_FILE_RANGE: return "SYNC_FILE_RANGE"; -206 case IORING_OP_SENDMSG: return "SENDMSG"; -207 case IORING_OP_RECVMSG: return "RECVMSG"; -208 case IORING_OP_TIMEOUT: return "TIMEOUT"; -209 case IORING_OP_TIMEOUT_REMOVE: return "TIMEOUT_REMOVE"; -210 case IORING_OP_ACCEPT: return "ACCEPT"; -211 case IORING_OP_ASYNC_CANCEL: return "ASYNC_CANCEL"; -212 case IORING_OP_LINK_TIMEOUT: return "LINK_TIMEOUT"; -213 case IORING_OP_CONNECT: return "CONNECT"; -214 case IORING_OP_FALLOCATE: return "FALLOCATE"; -215 case IORING_OP_OPENAT: return "OPENAT"; -216 case IORING_OP_CLOSE: return "CLOSE"; -217 case IORING_OP_FILES_UPDATE: return "FILES_UPDATE"; -218 case IORING_OP_STATX: return "STATX"; -219 case IORING_OP_READ: return "READ"; -220 case IORING_OP_WRITE: return "WRITE"; -221 case IORING_OP_FADVISE: return "FADVISE"; -222 case IORING_OP_MADVISE: return "MADVISE"; -223 case IORING_OP_SEND: return "SEND"; -224 case IORING_OP_RECV: return "RECV"; -225 case IORING_OP_OPENAT2: return "OPENAT2"; -226 case IORING_OP_EPOLL_CTL: return "EPOLL_CTL"; -227 case IORING_OP_SPLICE: return "SPLICE"; -228 case IORING_OP_PROVIDE_BUFFERS: return "PROVIDE_BUFFERS"; -229 case IORING_OP_REMOVE_BUFFERS: return "REMOVE_BUFFERS"; -230 case IORING_OP_TEE: return "TEE"; -231 case IORING_OP_SHUTDOWN: return "SHUTDOWN"; -232 case IORING_OP_RENAMEAT: return "RENAMEAT"; -233 case IORING_OP_UNLINKAT: return "UNLINKAT"; -234 case IORING_OP_MKDIRAT: return "MKDIRAT"; -235 case IORING_OP_SYMLINKAT: return "SYMLINKAT"; -236 case IORING_OP_LINKAT: return "LINKAT"; -237 default: return "[OP CODE " + op + ']'; -238 } -239 } -240 -241 static final int IORING_ENTER_GETEVENTS = NativeStaticallyReferencedJniMethods.ioringEnterGetevents(); -242 static final int IOSQE_ASYNC = NativeStaticallyReferencedJniMethods.iosqeAsync(); -243 static final int IOSQE_LINK = NativeStaticallyReferencedJniMethods.iosqeLink(); -244 static final int IOSQE_IO_DRAIN = NativeStaticallyReferencedJniMethods.iosqeDrain(); -245 static final int MSG_DONTWAIT = NativeStaticallyReferencedJniMethods.msgDontwait(); -246 static final int MSG_FASTOPEN = NativeStaticallyReferencedJniMethods.msgFastopen(); -247 static final int SOL_UDP = NativeStaticallyReferencedJniMethods.solUdp(); -248 static final int UDP_SEGMENT = NativeStaticallyReferencedJniMethods.udpSegment(); -249 private static final int TFO_ENABLED_CLIENT_MASK = 0x1; -250 private static final int TFO_ENABLED_SERVER_MASK = 0x2; -251 private static final int TCP_FASTOPEN_MODE = NativeStaticallyReferencedJniMethods.tcpFastopenMode(); -252 /** -253 * <a href ="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt">tcp_fastopen</a> client mode enabled -254 * state. -255 */ -256 static final boolean IS_SUPPORTING_TCP_FASTOPEN_CLIENT = -257 (TCP_FASTOPEN_MODE & TFO_ENABLED_CLIENT_MASK) == TFO_ENABLED_CLIENT_MASK; -258 /** -259 * <a href ="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt">tcp_fastopen</a> server mode enabled -260 * state. -261 */ -262 static final boolean IS_SUPPORTING_TCP_FASTOPEN_SERVER = -263 (TCP_FASTOPEN_MODE & TFO_ENABLED_SERVER_MASK) == TFO_ENABLED_SERVER_MASK; -264 -265 private static final int[] REQUIRED_IORING_OPS = { -266 IORING_OP_POLL_ADD, -267 IORING_OP_TIMEOUT, -268 IORING_OP_ACCEPT, -269 IORING_OP_READ, -270 IORING_OP_WRITE, -271 IORING_OP_POLL_REMOVE, -272 IORING_OP_CONNECT, -273 IORING_OP_CLOSE, -274 IORING_OP_WRITEV, -275 IORING_OP_SENDMSG, -276 IORING_OP_RECVMSG, -277 IORING_OP_ASYNC_CANCEL, -278 IORING_OP_RECV, -279 IORING_OP_NOP, -280 IORING_OP_SHUTDOWN, -281 IORING_OP_SEND -282 }; -283 -284 static RingBuffer createRingBuffer() { -285 return createRingBuffer(DEFAULT_RING_SIZE); -286 } +18 import io.netty.channel.DefaultFileRegion; +19 import io.netty.util.internal.ObjectUtil; +20 import io.netty.util.internal.logging.InternalLogger; +21 import io.netty.util.internal.logging.InternalLoggerFactory; +22 import io.netty.channel.unix.FileDescriptor; +23 import io.netty.channel.unix.PeerCredentials; +24 import io.netty.channel.unix.Unix; +25 import io.netty.util.internal.ClassInitializerUtil; +26 import io.netty.util.internal.NativeLibraryLoader; +27 import io.netty.util.internal.PlatformDependent; +28 import io.netty.util.internal.SystemPropertyUtil; +29 import io.netty.util.internal.ThrowableUtil; +30 +31 import java.io.File; +32 import java.io.IOException; +33 import java.nio.channels.FileChannel; +34 import java.nio.channels.Selector; +35 import java.nio.file.Path; +36 import java.util.Arrays; +37 import java.util.Locale; +38 +39 final class Native { +40 private static final InternalLogger logger = InternalLoggerFactory.getInstance(Native.class); +41 static final int DEFAULT_RING_SIZE = Math.max(64, SystemPropertyUtil.getInt("io.netty.iouring.ringSize", 4096)); +42 +43 static { +44 Selector selector = null; +45 try { +46 // We call Selector.open() as this will under the hood cause IOUtil to be loaded. +47 // This is a workaround for a possible classloader deadlock that could happen otherwise: +48 // +49 // See https://github.com/netty/netty/issues/10187 +50 selector = Selector.open(); +51 } catch (IOException ignore) { +52 // Just ignore +53 } +54 +55 // Preload all classes that will be used in the OnLoad(...) function of JNI to eliminate the possiblity of a +56 // class-loader deadlock. This is a workaround for https://github.com/netty/netty/issues/11209. +57 +58 // This needs to match all the classes that are loaded via NETTY_JNI_UTIL_LOAD_CLASS or looked up via +59 // NETTY_JNI_UTIL_FIND_CLASS. +60 ClassInitializerUtil.tryLoadClasses( +61 Native.class, +62 // netty_io_uring_linuxsocket +63 PeerCredentials.class, java.io.FileDescriptor.class +64 ); +65 +66 File tmpDir = PlatformDependent.tmpdir(); +67 Path tmpFile = tmpDir.toPath().resolve("netty_io_uring.tmp"); +68 try { +69 // First, try calling a side-effect free JNI method to see if the library was already +70 // loaded by the application. +71 Native.createFile(tmpFile.toString()); +72 } catch (UnsatisfiedLinkError ignore) { +73 // The library was not previously loaded, load it now. +74 loadNativeLibrary(); +75 } finally { +76 tmpFile.toFile().delete(); +77 try { +78 if (selector != null) { +79 selector.close(); +80 } +81 } catch (IOException ignore) { +82 // Just ignore +83 } +84 } +85 Unix.registerInternal(Native::registerUnix); +86 } +87 +88 static final int SOCK_NONBLOCK = NativeStaticallyReferencedJniMethods.sockNonblock(); +89 static final int SOCK_CLOEXEC = NativeStaticallyReferencedJniMethods.sockCloexec(); +90 static final short AF_INET = (short) NativeStaticallyReferencedJniMethods.afInet(); +91 static final short AF_INET6 = (short) NativeStaticallyReferencedJniMethods.afInet6(); +92 static final int SIZEOF_SOCKADDR_STORAGE = NativeStaticallyReferencedJniMethods.sizeofSockaddrStorage(); +93 static final int SIZEOF_SOCKADDR_IN = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn(); +94 static final int SIZEOF_SOCKADDR_IN6 = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn6(); +95 static final int SOCKADDR_IN_OFFSETOF_SIN_FAMILY = +96 NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinFamily(); +97 static final int SOCKADDR_IN_OFFSETOF_SIN_PORT = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinPort(); +98 static final int SOCKADDR_IN_OFFSETOF_SIN_ADDR = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinAddr(); +99 static final int IN_ADDRESS_OFFSETOF_S_ADDR = NativeStaticallyReferencedJniMethods.inAddressOffsetofSAddr(); +100 static final int SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY = +101 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Family(); +102 static final int SOCKADDR_IN6_OFFSETOF_SIN6_PORT = +103 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Port(); +104 static final int SOCKADDR_IN6_OFFSETOF_SIN6_FLOWINFO = +105 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Flowinfo(); +106 static final int SOCKADDR_IN6_OFFSETOF_SIN6_ADDR = +107 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Addr(); +108 static final int SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID = +109 NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6ScopeId(); +110 static final int IN6_ADDRESS_OFFSETOF_S6_ADDR = NativeStaticallyReferencedJniMethods.in6AddressOffsetofS6Addr(); +111 static final int SIZEOF_SIZE_T = NativeStaticallyReferencedJniMethods.sizeofSizeT(); +112 static final int SIZEOF_IOVEC = NativeStaticallyReferencedJniMethods.sizeofIovec(); +113 static final int CMSG_SPACE = NativeStaticallyReferencedJniMethods.cmsgSpace(); +114 static final int CMSG_LEN = NativeStaticallyReferencedJniMethods.cmsgLen(); +115 static final int CMSG_OFFSETOF_CMSG_LEN = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgLen(); +116 static final int CMSG_OFFSETOF_CMSG_LEVEL = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgLevel(); +117 static final int CMSG_OFFSETOF_CMSG_TYPE = NativeStaticallyReferencedJniMethods.cmsghdrOffsetofCmsgType(); +118 +119 static final int IOVEC_OFFSETOF_IOV_BASE = NativeStaticallyReferencedJniMethods.iovecOffsetofIovBase(); +120 static final int IOVEC_OFFSETOF_IOV_LEN = NativeStaticallyReferencedJniMethods.iovecOffsetofIovLen(); +121 static final int SIZEOF_MSGHDR = NativeStaticallyReferencedJniMethods.sizeofMsghdr(); +122 static final int MSGHDR_OFFSETOF_MSG_NAME = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgName(); +123 static final int MSGHDR_OFFSETOF_MSG_NAMELEN = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgNamelen(); +124 static final int MSGHDR_OFFSETOF_MSG_IOV = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgIov(); +125 static final int MSGHDR_OFFSETOF_MSG_IOVLEN = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgIovlen(); +126 static final int MSGHDR_OFFSETOF_MSG_CONTROL = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgControl(); +127 static final int MSGHDR_OFFSETOF_MSG_CONTROLLEN = +128 NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgControllen(); +129 static final int MSGHDR_OFFSETOF_MSG_FLAGS = NativeStaticallyReferencedJniMethods.msghdrOffsetofMsgFlags(); +130 static final int POLLIN = NativeStaticallyReferencedJniMethods.pollin(); +131 static final int POLLOUT = NativeStaticallyReferencedJniMethods.pollout(); +132 static final int POLLRDHUP = NativeStaticallyReferencedJniMethods.pollrdhup(); +133 static final int ERRNO_ECANCELED_NEGATIVE = -NativeStaticallyReferencedJniMethods.ecanceled(); +134 static final int ERRNO_ETIME_NEGATIVE = -NativeStaticallyReferencedJniMethods.etime(); +135 +136 // These constants must be defined to have the same numeric value as their corresponding +137 // ordinal in the enum defined in the io_uring.h header file. +138 // DO NOT CHANGE THESE VALUES! +139 static final byte IORING_OP_NOP = 0; // Specified by IORING_OP_NOP in io_uring.h +140 static final byte IORING_OP_READV = 1; // Specified by IORING_OP_READV in io_uring.h +141 static final byte IORING_OP_WRITEV = 2; // Specified by IORING_OP_WRITEV in io_uring.h +142 static final byte IORING_OP_FSYNC = 3; // Specified by IORING_OP_FSYNC in io_uring.h +143 static final byte IORING_OP_READ_FIXED = 4; // Specified by IORING_OP_READ_FIXED in io_uring.h +144 static final byte IORING_OP_WRITE_FIXED = 5; // Specified by IORING_OP_WRITE_FIXED in io_uring.h +145 static final byte IORING_OP_POLL_ADD = 6; // Specified by IORING_OP_POLL_ADD in io_uring.h +146 static final byte IORING_OP_POLL_REMOVE = 7; // Specified by IORING_OP_POLL_REMOVE in io_uring.h +147 static final byte IORING_OP_SYNC_FILE_RANGE = 8; // Specified by IORING_OP_SYNC_FILE_RANGE in io_uring.h +148 static final byte IORING_OP_SENDMSG = 9; // Specified by IORING_OP_SENDMSG in io_uring.h +149 static final byte IORING_OP_RECVMSG = 10; // Specified by IORING_OP_RECVMSG in io_uring.h +150 static final byte IORING_OP_TIMEOUT = 11; // Specified by IORING_OP_TIMEOUT in io_uring.h +151 static final byte IORING_OP_TIMEOUT_REMOVE = 12; // Specified by IORING_OP_TIMEOUT_REMOVE in io_uring.h +152 static final byte IORING_OP_ACCEPT = 13; // Specified by IORING_OP_ACCEPT in io_uring.h +153 static final byte IORING_OP_ASYNC_CANCEL = 14; // Specified by IORING_OP_ASYNC_CANCEL in io_uring.h +154 static final byte IORING_OP_LINK_TIMEOUT = 15; // Specified by IORING_OP_LINK_TIMEOUT in io_uring.h +155 static final byte IORING_OP_CONNECT = 16; // Specified by IORING_OP_CONNECT in io_uring.h +156 static final byte IORING_OP_FALLOCATE = 17; // Specified by IORING_OP_FALLOCATE in io_uring.h +157 static final byte IORING_OP_OPENAT = 18; // Specified by IORING_OP_OPENAT in io_uring.h +158 static final byte IORING_OP_CLOSE = 19; // Specified by IORING_OP_CLOSE in io_uring.h +159 static final byte IORING_OP_FILES_UPDATE = 20; // Specified by IORING_OP_FILES_UPDATE in io_uring.h +160 static final byte IORING_OP_STATX = 21; // Specified by IORING_OP_STATX in io_uring.h +161 static final byte IORING_OP_READ = 22; // Specified by IORING_OP_READ in io_uring.h +162 static final byte IORING_OP_WRITE = 23; // Specified by IORING_OP_WRITE in io_uring.h +163 static final byte IORING_OP_FADVISE = 24; // Specified by IORING_OP_FADVISE in io_uring.h +164 static final byte IORING_OP_MADVISE = 25; // Specified by IORING_OP_MADVISE in io_uring.h +165 static final byte IORING_OP_SEND = 26; // Specified by IORING_OP_SEND in io_uring.h +166 static final byte IORING_OP_RECV = 27; // Specified by IORING_OP_RECV in io_uring.h +167 static final byte IORING_OP_OPENAT2 = 28; // Specified by IORING_OP_OPENAT2 in io_uring.h +168 static final byte IORING_OP_EPOLL_CTL = 29; // Specified by IORING_OP_EPOLL_CTL in io_uring.h +169 static final byte IORING_OP_SPLICE = 30; // Specified by IORING_OP_SPLICE in io_uring.h +170 static final byte IORING_OP_PROVIDE_BUFFERS = 31; // Specified by IORING_OP_PROVIDE_BUFFERS in io_uring.h +171 static final byte IORING_OP_REMOVE_BUFFERS = 32; // Specified by IORING_OP_REMOVE_BUFFERS in io_uring.h +172 static final byte IORING_OP_TEE = 33; // Specified by IORING_OP_TEE in io_uring.h +173 static final byte IORING_OP_SHUTDOWN = 34; // Specified by IORING_OP_SHUTDOWN in io_uring.h +174 static final byte IORING_OP_RENAMEAT = 35; // Specified by IORING_OP_RENAMEAT in io_uring.h +175 static final byte IORING_OP_UNLINKAT = 36; // Specified by IORING_OP_UNLINKAT in io_uring.h +176 static final byte IORING_OP_MKDIRAT = 37; // Specified by IORING_OP_MKDIRAT in io_uring.h +177 static final byte IORING_OP_SYMLINKAT = 38; // Specified by IORING_OP_SYMLINKAT in io_uring.h +178 static final byte IORING_OP_LINKAT = 39; // Specified by IORING_OP_LINKAT in io_uring.h +179 static final byte IORING_OP_MSG_RING = 40; +180 static final byte IORING_OP_FSETXATTR = 41; +181 static final byte IORING_OP_SETXATTR = 42; +182 static final byte IORING_OP_FGETXATTR = 43; +183 static final byte IORING_OP_GETXATTR = 44; +184 static final byte IORING_OP_SOCKET = 45; +185 static final byte IORING_OP_URING_CMD = 46; +186 static final byte IORING_OP_SEND_ZC = 47; +187 static final byte IORING_OP_SENDMSG_ZC = 48; +188 static final byte IORING_OP_READ_MULTISHOT = 49; +189 static final byte IORING_OP_WAITID = 50; +190 static final byte IORING_OP_FUTEX_WAIT = 51; +191 static final byte IORING_OP_FUTEX_WAKE = 52; +192 static final byte IORING_OP_FUTEX_WAITV = 53; +193 static final byte IORING_OP_FIXED_FD_INSTALL = 54; +194 static final byte IORING_OP_FTRUNCATE = 55; +195 static final byte IORING_CQE_F_SOCK_NONEMPTY = 1 << 2; +196 +197 static final int SPLICE_F_MOVE = 1; +198 +199 static String opToStr(byte op) { +200 switch (op) { +201 case IORING_OP_NOP: return "NOP"; +202 case IORING_OP_READV: return "READV"; +203 case IORING_OP_WRITEV: return "WRITEV"; +204 case IORING_OP_FSYNC: return "FSYNC"; +205 case IORING_OP_READ_FIXED: return "READ_FIXED"; +206 case IORING_OP_WRITE_FIXED: return "WRITE_FIXED"; +207 case IORING_OP_POLL_ADD: return "POLL_ADD"; +208 case IORING_OP_POLL_REMOVE: return "POLL_REMOVE"; +209 case IORING_OP_SYNC_FILE_RANGE: return "SYNC_FILE_RANGE"; +210 case IORING_OP_SENDMSG: return "SENDMSG"; +211 case IORING_OP_RECVMSG: return "RECVMSG"; +212 case IORING_OP_TIMEOUT: return "TIMEOUT"; +213 case IORING_OP_TIMEOUT_REMOVE: return "TIMEOUT_REMOVE"; +214 case IORING_OP_ACCEPT: return "ACCEPT"; +215 case IORING_OP_ASYNC_CANCEL: return "ASYNC_CANCEL"; +216 case IORING_OP_LINK_TIMEOUT: return "LINK_TIMEOUT"; +217 case IORING_OP_CONNECT: return "CONNECT"; +218 case IORING_OP_FALLOCATE: return "FALLOCATE"; +219 case IORING_OP_OPENAT: return "OPENAT"; +220 case IORING_OP_CLOSE: return "CLOSE"; +221 case IORING_OP_FILES_UPDATE: return "FILES_UPDATE"; +222 case IORING_OP_STATX: return "STATX"; +223 case IORING_OP_READ: return "READ"; +224 case IORING_OP_WRITE: return "WRITE"; +225 case IORING_OP_FADVISE: return "FADVISE"; +226 case IORING_OP_MADVISE: return "MADVISE"; +227 case IORING_OP_SEND: return "SEND"; +228 case IORING_OP_RECV: return "RECV"; +229 case IORING_OP_OPENAT2: return "OPENAT2"; +230 case IORING_OP_EPOLL_CTL: return "EPOLL_CTL"; +231 case IORING_OP_SPLICE: return "SPLICE"; +232 case IORING_OP_PROVIDE_BUFFERS: return "PROVIDE_BUFFERS"; +233 case IORING_OP_REMOVE_BUFFERS: return "REMOVE_BUFFERS"; +234 case IORING_OP_TEE: return "TEE"; +235 case IORING_OP_SHUTDOWN: return "SHUTDOWN"; +236 case IORING_OP_RENAMEAT: return "RENAMEAT"; +237 case IORING_OP_UNLINKAT: return "UNLINKAT"; +238 case IORING_OP_MKDIRAT: return "MKDIRAT"; +239 case IORING_OP_SYMLINKAT: return "SYMLINKAT"; +240 case IORING_OP_LINKAT: return "LINKAT"; +241 default: return "[OP CODE " + op + ']'; +242 } +243 } +244 +245 static final int IORING_ENTER_GETEVENTS = NativeStaticallyReferencedJniMethods.ioringEnterGetevents(); +246 static final int IOSQE_ASYNC = NativeStaticallyReferencedJniMethods.iosqeAsync(); +247 static final int IOSQE_LINK = NativeStaticallyReferencedJniMethods.iosqeLink(); +248 static final int IOSQE_IO_DRAIN = NativeStaticallyReferencedJniMethods.iosqeDrain(); +249 static final int MSG_DONTWAIT = NativeStaticallyReferencedJniMethods.msgDontwait(); +250 static final int MSG_FASTOPEN = NativeStaticallyReferencedJniMethods.msgFastopen(); +251 static final int SOL_UDP = NativeStaticallyReferencedJniMethods.solUdp(); +252 static final int UDP_SEGMENT = NativeStaticallyReferencedJniMethods.udpSegment(); +253 private static final int TFO_ENABLED_CLIENT_MASK = 0x1; +254 private static final int TFO_ENABLED_SERVER_MASK = 0x2; +255 private static final int TCP_FASTOPEN_MODE = NativeStaticallyReferencedJniMethods.tcpFastopenMode(); +256 /** +257 * <a href ="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt">tcp_fastopen</a> client mode enabled +258 * state. +259 */ +260 static final boolean IS_SUPPORTING_TCP_FASTOPEN_CLIENT = +261 (TCP_FASTOPEN_MODE & TFO_ENABLED_CLIENT_MASK) == TFO_ENABLED_CLIENT_MASK; +262 /** +263 * <a href ="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt">tcp_fastopen</a> server mode enabled +264 * state. +265 */ +266 static final boolean IS_SUPPORTING_TCP_FASTOPEN_SERVER = +267 (TCP_FASTOPEN_MODE & TFO_ENABLED_SERVER_MASK) == TFO_ENABLED_SERVER_MASK; +268 +269 private static final int[] REQUIRED_IORING_OPS = { +270 IORING_OP_POLL_ADD, +271 IORING_OP_TIMEOUT, +272 IORING_OP_ACCEPT, +273 IORING_OP_READ, +274 IORING_OP_WRITE, +275 IORING_OP_POLL_REMOVE, +276 IORING_OP_CONNECT, +277 IORING_OP_CLOSE, +278 IORING_OP_WRITEV, +279 IORING_OP_SENDMSG, +280 IORING_OP_RECVMSG, +281 IORING_OP_ASYNC_CANCEL, +282 IORING_OP_RECV, +283 IORING_OP_NOP, +284 IORING_OP_SHUTDOWN, +285 IORING_OP_SEND +286 }; 287 -288 static RingBuffer createRingBuffer(int ringSize) { -289 ObjectUtil.checkPositive(ringSize, "ringSize"); -290 long[][] values = ioUringSetup(ringSize); -291 assert values.length == 2; -292 long[] completionQueueArgs = values[1]; -293 assert completionQueueArgs.length == 9; -294 CompletionQueue completionQueue = new CompletionQueue( -295 completionQueueArgs[0], -296 completionQueueArgs[1], -297 completionQueueArgs[2], -298 completionQueueArgs[3], -299 completionQueueArgs[4], -300 completionQueueArgs[5], -301 (int) completionQueueArgs[6], -302 completionQueueArgs[7], -303 (int) completionQueueArgs[8]); -304 long[] submissionQueueArgs = values[0]; -305 assert submissionQueueArgs.length == 11; -306 SubmissionQueue submissionQueue = new SubmissionQueue( -307 submissionQueueArgs[0], -308 submissionQueueArgs[1], -309 submissionQueueArgs[2], -310 submissionQueueArgs[3], -311 submissionQueueArgs[4], -312 submissionQueueArgs[5], -313 submissionQueueArgs[6], -314 submissionQueueArgs[7], -315 (int) submissionQueueArgs[8], -316 submissionQueueArgs[9], -317 (int) submissionQueueArgs[10], -318 completionQueue); -319 return new RingBuffer(submissionQueue, completionQueue); -320 } -321 -322 static void checkAllIOSupported(int ringFd) { -323 if (!ioUringProbe(ringFd, REQUIRED_IORING_OPS)) { -324 throw new UnsupportedOperationException("Not all operations are supported: " -325 + Arrays.toString(REQUIRED_IORING_OPS)); -326 } -327 } -328 -329 static boolean isIOUringCqeFSockNonEmptySupported(int ringFd) { -330 // IORING_OP_SOCKET was added in the same release (5.19); -331 return ioUringProbe(ringFd, new int[] { Native.IORING_OP_SOCKET }); -332 } -333 -334 static void checkKernelVersion(String kernelVersion) { -335 boolean enforceKernelVersion = SystemPropertyUtil.getBoolean( -336 "io.netty5.transport.iouring.enforceKernelVersion", true); -337 boolean kernelSupported = checkKernelVersion0(kernelVersion); -338 if (!kernelSupported) { -339 if (enforceKernelVersion) { -340 throw new UnsupportedOperationException( -341 "you need at least kernel version 5.9, current kernel version: " + kernelVersion); -342 } else { -343 logger.debug("Detected kernel " + kernelVersion + " does not match minimum version of 5.9, " + -344 "trying to use io_uring anyway"); -345 } -346 } -347 } -348 -349 private static boolean checkKernelVersion0(String kernelVersion) { -350 String[] versionComponents = kernelVersion.split("\\."); -351 if (versionComponents.length < 3) { -352 return false; -353 } -354 -355 int major; -356 try { -357 major = Integer.parseInt(versionComponents[0]); -358 } catch (NumberFormatException e) { -359 return false; -360 } -361 -362 if (major <= 4) { -363 return false; -364 } -365 if (major > 5) { -366 return true; -367 } -368 -369 int minor; -370 try { -371 minor = Integer.parseInt(versionComponents[1]); -372 } catch (NumberFormatException e) { -373 return false; -374 } -375 -376 return minor >= 9; -377 } -378 -379 private static native boolean ioUringProbe(int ringFd, int[] ios); -380 private static native long[][] ioUringSetup(int entries); -381 -382 static native int ioUringEnter(int ringFd, int toSubmit, int minComplete, int flags); -383 -384 static native void eventFdWrite(int fd, long value); -385 -386 static FileDescriptor newBlockingEventFd() { -387 return new FileDescriptor(blockingEventFd()); -388 } -389 -390 static native void ioUringExit(long submissionQueueArrayAddress, int submissionQueueRingEntries, -391 long submissionQueueRingAddress, int submissionQueueRingSize, -392 long completionQueueRingAddress, int completionQueueRingSize, -393 int ringFd); +288 static RingBuffer createRingBuffer() { +289 return createRingBuffer(DEFAULT_RING_SIZE); +290 } +291 +292 static RingBuffer createRingBuffer(int ringSize) { +293 ObjectUtil.checkPositive(ringSize, "ringSize"); +294 long[][] values = ioUringSetup(ringSize); +295 assert values.length == 2; +296 long[] completionQueueArgs = values[1]; +297 assert completionQueueArgs.length == 9; +298 CompletionQueue completionQueue = new CompletionQueue( +299 completionQueueArgs[0], +300 completionQueueArgs[1], +301 completionQueueArgs[2], +302 completionQueueArgs[3], +303 completionQueueArgs[4], +304 completionQueueArgs[5], +305 (int) completionQueueArgs[6], +306 completionQueueArgs[7], +307 (int) completionQueueArgs[8]); +308 long[] submissionQueueArgs = values[0]; +309 assert submissionQueueArgs.length == 11; +310 SubmissionQueue submissionQueue = new SubmissionQueue( +311 submissionQueueArgs[0], +312 submissionQueueArgs[1], +313 submissionQueueArgs[2], +314 submissionQueueArgs[3], +315 submissionQueueArgs[4], +316 submissionQueueArgs[5], +317 submissionQueueArgs[6], +318 submissionQueueArgs[7], +319 (int) submissionQueueArgs[8], +320 submissionQueueArgs[9], +321 (int) submissionQueueArgs[10], +322 completionQueue); +323 return new RingBuffer(submissionQueue, completionQueue); +324 } +325 +326 static void checkAllIOSupported(int ringFd) { +327 if (!ioUringProbe(ringFd, REQUIRED_IORING_OPS)) { +328 throw new UnsupportedOperationException("Not all operations are supported: " +329 + Arrays.toString(REQUIRED_IORING_OPS)); +330 } +331 } +332 +333 static boolean isIOUringCqeFSockNonEmptySupported(int ringFd) { +334 // IORING_OP_SOCKET was added in the same release (5.19); +335 return ioUringProbe(ringFd, new int[] { Native.IORING_OP_SOCKET }); +336 } +337 +338 static boolean isIOUringSupportSplice(int ringFd) { +339 // IORING_OP_SPLICE Available since 5.7 +340 return ioUringProbe(ringFd, new int[] { Native.IORING_OP_SPLICE }); +341 } +342 +343 static void checkKernelVersion(String kernelVersion) { +344 boolean enforceKernelVersion = SystemPropertyUtil.getBoolean( +345 "io.netty5.transport.iouring.enforceKernelVersion", true); +346 boolean kernelSupported = checkKernelVersion0(kernelVersion); +347 if (!kernelSupported) { +348 if (enforceKernelVersion) { +349 throw new UnsupportedOperationException( +350 "you need at least kernel version 5.9, current kernel version: " + kernelVersion); +351 } else { +352 logger.debug("Detected kernel " + kernelVersion + " does not match minimum version of 5.9, " + +353 "trying to use io_uring anyway"); +354 } +355 } +356 } +357 +358 private static boolean checkKernelVersion0(String kernelVersion) { +359 String[] versionComponents = kernelVersion.split("\\."); +360 if (versionComponents.length < 3) { +361 return false; +362 } +363 +364 int major; +365 try { +366 major = Integer.parseInt(versionComponents[0]); +367 } catch (NumberFormatException e) { +368 return false; +369 } +370 +371 if (major <= 4) { +372 return false; +373 } +374 if (major > 5) { +375 return true; +376 } +377 +378 int minor; +379 try { +380 minor = Integer.parseInt(versionComponents[1]); +381 } catch (NumberFormatException e) { +382 return false; +383 } +384 +385 return minor >= 9; +386 } +387 +388 private static native boolean ioUringProbe(int ringFd, int[] ios); +389 private static native long[][] ioUringSetup(int entries); +390 +391 static native int ioUringEnter(int ringFd, int toSubmit, int minComplete, int flags); +392 +393 static native void eventFdWrite(int fd, long value); 394 -395 private static native int blockingEventFd(); -396 -397 // for testing only! -398 static native int createFile(String name); -399 -400 private static native int registerUnix(); -401 -402 static native long cmsghdrData(long hdrAddr); -403 -404 static native String kernelVersion(); -405 -406 private Native() { -407 // utility -408 } +395 static int getFd(DefaultFileRegion fileChannel) { +396 return getFd0(fileChannel); +397 } +398 +399 private static native int getFd0(Object fileChannel); +400 +401 static FileDescriptor newBlockingEventFd() { +402 return new FileDescriptor(blockingEventFd()); +403 } +404 +405 static native void ioUringExit(long submissionQueueArrayAddress, int submissionQueueRingEntries, +406 long submissionQueueRingAddress, int submissionQueueRingSize, +407 long completionQueueRingAddress, int completionQueueRingSize, +408 int ringFd); 409 -410 // From io_uring native library -411 private static void loadNativeLibrary() { -412 String name = PlatformDependent.normalizedOs().toLowerCase(Locale.ROOT).trim(); -413 if (!name.startsWith("linux")) { -414 throw new IllegalStateException("Only supported on Linux"); -415 } -416 String staticLibName = "netty_transport_native_io_uring"; -417 String sharedLibName = staticLibName + '_' + PlatformDependent.normalizedArch(); -418 ClassLoader cl = PlatformDependent.getClassLoader(Native.class); -419 try { -420 NativeLibraryLoader.load(sharedLibName, cl); -421 } catch (UnsatisfiedLinkError e1) { -422 try { -423 NativeLibraryLoader.load(staticLibName, cl); -424 logger.info("Failed to load io_uring"); -425 } catch (UnsatisfiedLinkError e2) { -426 ThrowableUtil.addSuppressed(e1, e2); -427 throw e1; -428 } -429 } -430 } -431 } +410 private static native int blockingEventFd(); +411 +412 // for testing only! +413 static native int createFile(String name); +414 +415 private static native int registerUnix(); +416 +417 static native long cmsghdrData(long hdrAddr); +418 +419 static native String kernelVersion(); +420 +421 private Native() { +422 // utility +423 } +424 +425 // From io_uring native library +426 private static void loadNativeLibrary() { +427 String name = PlatformDependent.normalizedOs().toLowerCase(Locale.ROOT).trim(); +428 if (!name.startsWith("linux")) { +429 throw new IllegalStateException("Only supported on Linux"); +430 } +431 String staticLibName = "netty_transport_native_io_uring"; +432 String sharedLibName = staticLibName + '_' + PlatformDependent.normalizedArch(); +433 ClassLoader cl = PlatformDependent.getClassLoader(Native.class); +434 try { +435 NativeLibraryLoader.load(sharedLibName, cl); +436 } catch (UnsatisfiedLinkError e1) { +437 try { +438 NativeLibraryLoader.load(staticLibName, cl); +439 logger.info("Failed to load io_uring"); +440 } catch (UnsatisfiedLinkError e2) { +441 ThrowableUtil.addSuppressed(e1, e2); +442 throw e1; +443 } +444 } +445 } +446 }
    diff --git a/4.2/xref/io/netty/channel/uring/SubmissionQueue.html b/4.2/xref/io/netty/channel/uring/SubmissionQueue.html index 9049484ac6b..dbc1c4412f7 100644 --- a/4.2/xref/io/netty/channel/uring/SubmissionQueue.html +++ b/4.2/xref/io/netty/channel/uring/SubmissionQueue.html @@ -46,233 +46,243 @@ 38 private static final int SQE_FLAGS_FIELD = 1; 39 private static final int SQE_IOPRIO_FIELD = 2; // u16 40 private static final int SQE_FD_FIELD = 4; // s32 -41 private static final int SQE_OFFSET_FIELD = 8; -42 private static final int SQE_ADDRESS_FIELD = 16; +41 private static final int SQE_UNION1_FIELD = 8; +42 private static final int SQE_UNION2_FIELD = 16; 43 private static final int SQE_LEN_FIELD = 24; -44 private static final int SQE_RW_FLAGS_FIELD = 28; +44 private static final int SQE_UNION3_FIELD = 28; 45 private static final int SQE_USER_DATA_FIELD = 32; -46 private static final int SQE_PAD_FIELD = 40; -47 -48 private static final int KERNEL_TIMESPEC_TV_SEC_FIELD = 0; -49 private static final int KERNEL_TIMESPEC_TV_NSEC_FIELD = 8; +46 private static final int SQE_UNION4_FIELD = 40; +47 private static final int SQE_PERSONALITY_FIELD = 42; +48 private static final int SQE_UNION5_FIELD = 44; +49 private static final int SQE_UNION6_FIELD = 48; 50 -51 //these unsigned integer pointers(shared with the kernel) will be changed by the kernel -52 private final long kHeadAddress; -53 private final long kTailAddress; -54 private final long kFlagsAddress; -55 private final long kDroppedAddress; -56 private final long kArrayAddress; -57 final long submissionQueueArrayAddress; -58 -59 final int ringEntries; -60 private final int ringMask; // = ringEntries - 1 +51 private static final int KERNEL_TIMESPEC_TV_SEC_FIELD = 0; +52 private static final int KERNEL_TIMESPEC_TV_NSEC_FIELD = 8; +53 +54 //these unsigned integer pointers(shared with the kernel) will be changed by the kernel +55 private final long kHeadAddress; +56 private final long kTailAddress; +57 private final long kFlagsAddress; +58 private final long kDroppedAddress; +59 private final long kArrayAddress; +60 final long submissionQueueArrayAddress; 61 -62 final int ringSize; -63 final long ringAddress; -64 final int ringFd; -65 private final long timeoutMemoryAddress; -66 private final IntSupplier completionCount; -67 private int numHandledFds; -68 private int head; -69 private int tail; -70 -71 SubmissionQueue(long kHeadAddress, long kTailAddress, long kRingMaskAddress, long kRingEntriesAddress, -72 long kFlagsAddress, long kDroppedAddress, long kArrayAddress, -73 long submissionQueueArrayAddress, int ringSize, long ringAddress, int ringFd, -74 IntSupplier completionCount) { -75 this.kHeadAddress = kHeadAddress; -76 this.kTailAddress = kTailAddress; -77 this.kFlagsAddress = kFlagsAddress; -78 this.kDroppedAddress = kDroppedAddress; -79 this.kArrayAddress = kArrayAddress; -80 this.submissionQueueArrayAddress = submissionQueueArrayAddress; -81 this.ringSize = ringSize; -82 this.ringAddress = ringAddress; -83 this.ringFd = ringFd; -84 this.ringEntries = PlatformDependent.getIntVolatile(kRingEntriesAddress); -85 this.ringMask = PlatformDependent.getIntVolatile(kRingMaskAddress); -86 this.head = PlatformDependent.getIntVolatile(kHeadAddress); -87 this.tail = PlatformDependent.getIntVolatile(kTailAddress); -88 -89 this.timeoutMemoryAddress = PlatformDependent.allocateMemory(KERNEL_TIMESPEC_SIZE); -90 this.completionCount = completionCount; +62 final int ringEntries; +63 private final int ringMask; // = ringEntries - 1 +64 +65 final int ringSize; +66 final long ringAddress; +67 final int ringFd; +68 private final long timeoutMemoryAddress; +69 private final IntSupplier completionCount; +70 private int numHandledFds; +71 private int head; +72 private int tail; +73 +74 SubmissionQueue(long kHeadAddress, long kTailAddress, long kRingMaskAddress, long kRingEntriesAddress, +75 long kFlagsAddress, long kDroppedAddress, long kArrayAddress, +76 long submissionQueueArrayAddress, int ringSize, long ringAddress, int ringFd, +77 IntSupplier completionCount) { +78 this.kHeadAddress = kHeadAddress; +79 this.kTailAddress = kTailAddress; +80 this.kFlagsAddress = kFlagsAddress; +81 this.kDroppedAddress = kDroppedAddress; +82 this.kArrayAddress = kArrayAddress; +83 this.submissionQueueArrayAddress = submissionQueueArrayAddress; +84 this.ringSize = ringSize; +85 this.ringAddress = ringAddress; +86 this.ringFd = ringFd; +87 this.ringEntries = PlatformDependent.getIntVolatile(kRingEntriesAddress); +88 this.ringMask = PlatformDependent.getIntVolatile(kRingMaskAddress); +89 this.head = PlatformDependent.getIntVolatile(kHeadAddress); +90 this.tail = PlatformDependent.getIntVolatile(kTailAddress); 91 -92 // Zero the whole SQE array first -93 PlatformDependent.setMemory(submissionQueueArrayAddress, ringEntries * SQE_SIZE, (byte) 0); +92 this.timeoutMemoryAddress = PlatformDependent.allocateMemory(KERNEL_TIMESPEC_SIZE); +93 this.completionCount = completionCount; 94 -95 // Fill SQ array indices (1-1 with SQE array) and set nonzero constant SQE fields -96 long address = kArrayAddress; -97 for (int i = 0; i < ringEntries; i++, address += INT_SIZE) { -98 PlatformDependent.putInt(address, i); -99 } -100 } -101 -102 void incrementHandledFds() { -103 numHandledFds++; -104 } -105 -106 void decrementHandledFds() { -107 numHandledFds--; -108 assert numHandledFds >= 0; -109 } -110 -111 long enqueueSqe(byte op, int flags, short ioPrio, int rwFlags, int fd, -112 long bufferAddress, int length, long offset, int id, short data) { -113 int pending = tail - head; -114 if (pending == ringEntries) { -115 int submitted = submit(); -116 if (submitted == 0) { -117 // We have a problem, could not submit to make more room in the ring -118 throw new RuntimeException("SQ ring full and no submissions accepted"); -119 } -120 } -121 long sqe = submissionQueueArrayAddress + (tail++ & ringMask) * SQE_SIZE; -122 long udata = UserData.encode(id, op, data); -123 setData(sqe, op, flags, ioPrio, rwFlags, fd, -124 bufferAddress, length, offset, udata); -125 return udata; -126 } -127 -128 void enqueueSqe(byte op, int flags, short ioPrio, int rwFlags, int fd, -129 long bufferAddress, int length, long offset, long udata) { -130 int pending = tail - head; -131 if (pending == ringEntries) { -132 int submitted = submit(); -133 if (submitted == 0) { -134 // We have a problem, could not submit to make more room in the ring -135 throw new RuntimeException("SQ ring full and no submissions accepted"); -136 } -137 } -138 long sqe = submissionQueueArrayAddress + (tail++ & ringMask) * SQE_SIZE; -139 setData(sqe, op, flags, ioPrio, rwFlags, fd, bufferAddress, length, offset, udata); -140 } -141 -142 private void setData(long sqe, byte op, int flags, short ioPrio, int rwFlags, int fd, long bufferAddress, -143 int length, long offset, long udata) { -144 //set sqe(submission queue) properties +95 // Zero the whole SQE array first +96 PlatformDependent.setMemory(submissionQueueArrayAddress, ringEntries * SQE_SIZE, (byte) 0); +97 +98 // Fill SQ array indices (1-1 with SQE array) and set nonzero constant SQE fields +99 long address = kArrayAddress; +100 for (int i = 0; i < ringEntries; i++, address += INT_SIZE) { +101 PlatformDependent.putInt(address, i); +102 } +103 } +104 +105 void incrementHandledFds() { +106 numHandledFds++; +107 } +108 +109 void decrementHandledFds() { +110 numHandledFds--; +111 assert numHandledFds >= 0; +112 } +113 +114 private long enqueueSqe0(int id, byte opcode, byte flags, short ioPrio, int fd, long union1, long union2, int len, +115 int union3, short data, short union4, short personality, int union5, long union6) { +116 int pending = tail - head; +117 if (pending == ringEntries) { +118 int submitted = submit(); +119 if (submitted == 0) { +120 // We have a problem, could not submit to make more room in the ring +121 throw new RuntimeException("SQ ring full and no submissions accepted"); +122 } +123 } +124 long sqe = submissionQueueArrayAddress + (tail++ & ringMask) * SQE_SIZE; +125 long udata = UserData.encode(id, opcode, data); +126 setData(sqe, opcode, flags, ioPrio, fd, union1, union2, len, +127 union3, udata, union4, personality, union5, union6); +128 return udata; +129 } +130 +131 void enqueueSqe(byte opcode, byte flags, short ioPrio, int fd, long union1, long union2, int len, int union3, +132 long udata, short union4, short personality, int union5, long union6) { +133 int pending = tail - head; +134 if (pending == ringEntries) { +135 int submitted = submit(); +136 if (submitted == 0) { +137 // We have a problem, could not submit to make more room in the ring +138 throw new RuntimeException("SQ ring full and no submissions accepted"); +139 } +140 } +141 long sqe = submissionQueueArrayAddress + (tail++ & ringMask) * SQE_SIZE; +142 setData(sqe, opcode, flags, ioPrio, fd, union1, union2, len, +143 union3, udata, union4, personality, union5, union6); +144 } 145 -146 PlatformDependent.putByte(sqe + SQE_OP_CODE_FIELD, op); -147 PlatformDependent.putByte(sqe + SQE_FLAGS_FIELD, (byte) flags); -148 // This constant is set up-front -149 PlatformDependent.putShort(sqe + SQE_IOPRIO_FIELD, ioPrio); -150 PlatformDependent.putInt(sqe + SQE_FD_FIELD, fd); -151 PlatformDependent.putLong(sqe + SQE_OFFSET_FIELD, offset); -152 PlatformDependent.putLong(sqe + SQE_ADDRESS_FIELD, bufferAddress); -153 PlatformDependent.putInt(sqe + SQE_LEN_FIELD, length); -154 PlatformDependent.putInt(sqe + SQE_RW_FLAGS_FIELD, rwFlags); -155 PlatformDependent.putLong(sqe + SQE_USER_DATA_FIELD, udata); -156 -157 if (logger.isTraceEnabled()) { -158 if (op == Native.IORING_OP_WRITEV || op == Native.IORING_OP_READV) { -159 logger.trace("add(ring {}): {}(fd={}, len={} ({} bytes), off={}, data={})", -160 ringFd, Native.opToStr(op), fd, length, Iov.sumSize(bufferAddress, length), offset, udata); -161 } else { -162 logger.trace("add(ring {}): {}(fd={}, len={}, off={}, data={})", -163 ringFd, Native.opToStr(op), fd, length, offset, udata); -164 } -165 } -166 } -167 -168 @Override -169 public String toString() { -170 StringJoiner sb = new StringJoiner(", ", "SubmissionQueue [", "]"); -171 int pending = tail - head; -172 for (int i = 0; i < pending; i++) { -173 long sqe = submissionQueueArrayAddress + (head + i & ringMask) * SQE_SIZE; -174 sb.add(Native.opToStr(PlatformDependent.getByte(sqe + SQE_OP_CODE_FIELD)) + -175 "(fd=" + PlatformDependent.getInt(sqe + SQE_FD_FIELD) + ')'); -176 } -177 return sb.toString(); -178 } -179 -180 long addNop(int fd, int flags, int id, short data) { -181 return enqueueSqe(Native.IORING_OP_NOP, flags, (short) 0, 0, fd, 0, 0, 0, id, data); -182 } -183 -184 long addTimeout(int fd, long nanoSeconds, int id, short extraData) { -185 setTimeout(nanoSeconds); -186 return enqueueSqe(Native.IORING_OP_TIMEOUT, 0, (short) 0, 0, fd, -187 timeoutMemoryAddress, 1, 0, id, extraData); -188 } -189 -190 long addLinkTimeout(int fd, long nanoSeconds, int id, short extraData) { -191 setTimeout(nanoSeconds); -192 return enqueueSqe(Native.IORING_OP_LINK_TIMEOUT, 0, (short) 0, 0, fd, -193 timeoutMemoryAddress, 1, 0, id, extraData); -194 } -195 -196 long addEventFdRead(int fd, long bufferAddress, int pos, int limit, int id, short extraData) { -197 return enqueueSqe(Native.IORING_OP_READ, 0, (short) 0, 0, fd, -198 bufferAddress + pos, limit - pos, 0, id, extraData); -199 } -200 -201 long addCancel(int fd, long sqeToCancel, int id) { -202 return enqueueSqe(Native.IORING_OP_ASYNC_CANCEL, 0, (short) 0, 0, fd, sqeToCancel, 0, 0, id, (short) 0); +146 private void setData(long sqe, byte opcode, byte flags, short ioPrio, int fd, long union1, long union2, int len, +147 int union3, long udata, short union4, short personality, int union5, long union6) { +148 //set sqe(submission queue) properties +149 +150 PlatformDependent.putByte(sqe + SQE_OP_CODE_FIELD, opcode); +151 PlatformDependent.putByte(sqe + SQE_FLAGS_FIELD, flags); +152 // This constant is set up-front +153 PlatformDependent.putShort(sqe + SQE_IOPRIO_FIELD, ioPrio); +154 PlatformDependent.putInt(sqe + SQE_FD_FIELD, fd); +155 PlatformDependent.putLong(sqe + SQE_UNION1_FIELD, union1); +156 PlatformDependent.putLong(sqe + SQE_UNION2_FIELD, union2); +157 PlatformDependent.putInt(sqe + SQE_LEN_FIELD, len); +158 PlatformDependent.putInt(sqe + SQE_UNION3_FIELD, union3); +159 PlatformDependent.putLong(sqe + SQE_USER_DATA_FIELD, udata); +160 PlatformDependent.putShort(sqe + SQE_UNION4_FIELD, union4); +161 PlatformDependent.putShort(sqe + SQE_PERSONALITY_FIELD, personality); +162 PlatformDependent.putInt(sqe + SQE_UNION5_FIELD, union5); +163 PlatformDependent.putLong(sqe + SQE_UNION6_FIELD, union6); +164 +165 if (logger.isTraceEnabled()) { +166 if (opcode == Native.IORING_OP_WRITEV || opcode == Native.IORING_OP_READV) { +167 logger.trace("add(ring {}): {}(fd={}, len={} ({} bytes), off={}, data={})", +168 ringFd, Native.opToStr(opcode), fd, len, Iov.sumSize(union2, len), union1, udata); +169 } else { +170 logger.trace("add(ring {}): {}(fd={}, len={}, off={}, data={})", +171 ringFd, Native.opToStr(opcode), fd, len, union1, udata); +172 } +173 } +174 } +175 +176 @Override +177 public String toString() { +178 StringJoiner sb = new StringJoiner(", ", "SubmissionQueue [", "]"); +179 int pending = tail - head; +180 for (int i = 0; i < pending; i++) { +181 long sqe = submissionQueueArrayAddress + (head + i & ringMask) * SQE_SIZE; +182 sb.add(Native.opToStr(PlatformDependent.getByte(sqe + SQE_OP_CODE_FIELD)) + +183 "(fd=" + PlatformDependent.getInt(sqe + SQE_FD_FIELD) + ')'); +184 } +185 return sb.toString(); +186 } +187 +188 long addNop(int fd, byte flags, int id, short data) { +189 return enqueueSqe0(id, Native.IORING_OP_NOP, flags, (short) 0, fd, 0, 0, 0, 0, data, +190 (short) 0, (short) 0, 0, 0); +191 } +192 +193 long addTimeout(int fd, long nanoSeconds, int id, short extraData) { +194 setTimeout(nanoSeconds); +195 return enqueueSqe0(id, Native.IORING_OP_TIMEOUT, (byte) 0, (short) 0, fd, 0, timeoutMemoryAddress, 1, +196 0, extraData, (short) 0, (short) 0, 0, 0); +197 } +198 +199 long addLinkTimeout(int fd, long nanoSeconds, int id, short extraData) { +200 setTimeout(nanoSeconds); +201 return enqueueSqe0(id, Native.IORING_OP_LINK_TIMEOUT, (byte) 0, (short) 0, fd, 0, timeoutMemoryAddress, 1, +202 0, extraData, (short) 0, (short) 0, 0, 0); 203 } 204 -205 int submit() { -206 int submit = tail - head; -207 return submit > 0 ? submit(submit, 0, 0) : 0; +205 long addEventFdRead(int fd, long bufferAddress, int pos, int limit, int id, short extraData) { +206 return enqueueSqe0(id, Native.IORING_OP_READ, (byte) 0, (short) 0, fd, 0, bufferAddress + pos, limit - pos, +207 0, extraData, (short) 0, (short) 0, 0, 0); 208 } 209 -210 int submitAndWait() { -211 int submit = tail - head; -212 if (submit > 0) { -213 return submit(submit, 1, Native.IORING_ENTER_GETEVENTS); -214 } -215 assert submit == 0; -216 int ret = Native.ioUringEnter(ringFd, 0, 1, Native.IORING_ENTER_GETEVENTS); -217 if (ret < 0) { -218 throw new RuntimeException("ioUringEnter syscall returned " + ret); -219 } -220 return ret; // should be 0 -221 } -222 -223 private int submit(int toSubmit, int minComplete, int flags) { -224 if (logger.isTraceEnabled()) { -225 logger.trace("submit(ring {}): {}", ringFd, toString()); -226 } -227 PlatformDependent.putIntOrdered(kTailAddress, tail); // release memory barrier -228 int ret = Native.ioUringEnter(ringFd, toSubmit, minComplete, flags); -229 head = PlatformDependent.getIntVolatile(kHeadAddress); // acquire memory barrier -230 if (ret != toSubmit) { -231 if (ret < 0) { -232 throw new RuntimeException("ioUringEnter syscall returned " + ret); -233 } -234 logger.warn("Not all submissions succeeded. Only {} of {} SQEs were submitted, " + -235 "while there are {} pending completions.", ret, toSubmit, completionCount.getAsInt()); +210 long addCancel(int fd, long sqeToCancel, int id) { +211 return enqueueSqe0(id, Native.IORING_OP_ASYNC_CANCEL, (byte) 0, (short) 0, fd, 0, sqeToCancel, 0, 0, +212 (short) 0, (short) 0, (short) 0, 0, 0); +213 } +214 +215 int submit() { +216 int submit = tail - head; +217 return submit > 0 ? submit(submit, 0, 0) : 0; +218 } +219 +220 int submitAndWait() { +221 int submit = tail - head; +222 if (submit > 0) { +223 return submit(submit, 1, Native.IORING_ENTER_GETEVENTS); +224 } +225 assert submit == 0; +226 int ret = Native.ioUringEnter(ringFd, 0, 1, Native.IORING_ENTER_GETEVENTS); +227 if (ret < 0) { +228 throw new RuntimeException("ioUringEnter syscall returned " + ret); +229 } +230 return ret; // should be 0 +231 } +232 +233 private int submit(int toSubmit, int minComplete, int flags) { +234 if (logger.isTraceEnabled()) { +235 logger.trace("submit(ring {}): {}", ringFd, toString()); 236 } -237 return ret; -238 } -239 -240 private void setTimeout(long timeoutNanoSeconds) { -241 long seconds, nanoSeconds; -242 -243 if (timeoutNanoSeconds == 0) { -244 seconds = 0; -245 nanoSeconds = 0; -246 } else { -247 seconds = (int) min(timeoutNanoSeconds / 1000000000L, Integer.MAX_VALUE); -248 nanoSeconds = (int) max(timeoutNanoSeconds - seconds * 1000000000L, 0); -249 } -250 -251 PlatformDependent.putLong(timeoutMemoryAddress + KERNEL_TIMESPEC_TV_SEC_FIELD, seconds); -252 PlatformDependent.putLong(timeoutMemoryAddress + KERNEL_TIMESPEC_TV_NSEC_FIELD, nanoSeconds); -253 } -254 -255 public int count() { -256 return tail - head; -257 } -258 -259 public int remaining() { -260 return ringEntries - count(); -261 } -262 -263 //delete memory -264 public void release() { -265 PlatformDependent.freeMemory(timeoutMemoryAddress); -266 } -267 } +237 PlatformDependent.putIntOrdered(kTailAddress, tail); // release memory barrier +238 int ret = Native.ioUringEnter(ringFd, toSubmit, minComplete, flags); +239 head = PlatformDependent.getIntVolatile(kHeadAddress); // acquire memory barrier +240 if (ret != toSubmit) { +241 if (ret < 0) { +242 throw new RuntimeException("ioUringEnter syscall returned " + ret); +243 } +244 logger.warn("Not all submissions succeeded. Only {} of {} SQEs were submitted, " + +245 "while there are {} pending completions.", ret, toSubmit, completionCount.getAsInt()); +246 } +247 return ret; +248 } +249 +250 private void setTimeout(long timeoutNanoSeconds) { +251 long seconds, nanoSeconds; +252 +253 if (timeoutNanoSeconds == 0) { +254 seconds = 0; +255 nanoSeconds = 0; +256 } else { +257 seconds = (int) min(timeoutNanoSeconds / 1000000000L, Integer.MAX_VALUE); +258 nanoSeconds = (int) max(timeoutNanoSeconds - seconds * 1000000000L, 0); +259 } +260 +261 PlatformDependent.putLong(timeoutMemoryAddress + KERNEL_TIMESPEC_TV_SEC_FIELD, seconds); +262 PlatformDependent.putLong(timeoutMemoryAddress + KERNEL_TIMESPEC_TV_NSEC_FIELD, nanoSeconds); +263 } +264 +265 public int count() { +266 return tail - head; +267 } +268 +269 public int remaining() { +270 return ringEntries - count(); +271 } +272 +273 //delete memory +274 public void release() { +275 PlatformDependent.freeMemory(timeoutMemoryAddress); +276 } +277 }
    diff --git a/4.2/xref/io/netty/channel/uring/package-frame.html b/4.2/xref/io/netty/channel/uring/package-frame.html index c6b831edf8a..340895ec0c1 100644 --- a/4.2/xref/io/netty/channel/uring/package-frame.html +++ b/4.2/xref/io/netty/channel/uring/package-frame.html @@ -4,7 +4,7 @@ - Netty Source Xref (4.2.0.Beta1) Package io.netty.channel.uring + Netty Source Xref (4.2.0.RC1) Package io.netty.channel.uring @@ -60,6 +60,9 @@

    Classes

  • IoUringDatagramChannelConfig
  • +
  • + IoUringFileRegion +
  • IoUringIoEvent
  • diff --git a/4.2/xref/io/netty/channel/uring/package-summary.html b/4.2/xref/io/netty/channel/uring/package-summary.html index 852eef35d54..aee7f5ca9b4 100644 --- a/4.2/xref/io/netty/channel/uring/package-summary.html +++ b/4.2/xref/io/netty/channel/uring/package-summary.html @@ -4,7 +4,7 @@ - Netty Source Xref (4.2.0.Beta1) Package io.netty.channel.uring + Netty Source Xref (4.2.0.RC1) Package io.netty.channel.uring @@ -23,7 +23,7 @@
  • Index
  • Help
  • -
    Netty Source Xref (4.2.0.Beta1)
    +
    Netty Source Xref (4.2.0.RC1)
    -

    Netty Source Xref (4.2.0.Beta1)

    +

    Netty Source Xref (4.2.0.RC1)

    @@ -705,135 +705,140 @@

    Netty Source Xref (4.2.0.Beta1)

    + + + @@ -856,7 +861,7 @@

    Netty Source Xref (4.2.0.Beta1)

  • Index
  • Help
  • -
    Netty Source Xref (4.2.0.Beta1)
    +
    Netty Source Xref (4.2.0.RC1)
    - io.netty.resolver + io.netty.pkitesting
    - io.netty.resolver.dns + io.netty.resolver
    - io.netty.resolver.dns.macos + io.netty.resolver.dns
    - io.netty.testsuite.autobahn + io.netty.resolver.dns.macos
    - io.netty.testsuite.http2 + io.netty.testsuite.autobahn
    - io.netty.testsuite.svm + io.netty.testsuite.http2
    - io.netty.testsuite.svm.client + io.netty.testsuite.svm
    - io.netty.testsuite.transport + io.netty.testsuite.svm.client
    - io.netty.testsuite.transport.sctp + io.netty.testsuite.transport
    - io.netty.testsuite.transport.socket + io.netty.testsuite.transport.sctp
    - io.netty.testsuite.transport.udt + io.netty.testsuite.transport.socket
    - io.netty.testsuite.util + io.netty.testsuite.transport.udt
    - io.netty.util + io.netty.testsuite.util
    - io.netty.util.collection + io.netty.util
    - io.netty.util.concurrent + io.netty.util.collection
    - io.netty.util.concurrent.jmh_generated + io.netty.util.concurrent
    - io.netty.util.internal + io.netty.util.concurrent.jmh_generated
    - io.netty.util.internal.logging + io.netty.util.internal
    - io.netty.util.internal.shaded.org.jctools.counters + io.netty.util.internal.logging
    - io.netty.util.internal.shaded.org.jctools.maps + io.netty.util.internal.shaded.org.jctools.counters
    - io.netty.util.internal.shaded.org.jctools.queues + io.netty.util.internal.shaded.org.jctools.maps
    - io.netty.util.internal.shaded.org.jctools.queues.atomic + io.netty.util.internal.shaded.org.jctools.queues
    - io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded + io.netty.util.internal.shaded.org.jctools.queues.atomic
    - io.netty.util.internal.shaded.org.jctools.queues.unpadded + io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded
    - io.netty.util.internal.shaded.org.jctools.util + io.netty.util.internal.shaded.org.jctools.queues.unpadded
    - io.netty.util.internal.svm + io.netty.util.internal.shaded.org.jctools.util
    + io.netty.util.internal.svm +
    io.netty.util.jmh_generated
    @@ -454,7 +454,7 @@

    Derived buffers

    public void process(ByteBuf buf) { ... buf.release(); -}">
    ByteBuf parent = ctx.alloc().directBuffer(512);
    parent.writeBytes(...);
    
    try {
        while (parent.isReadable(16)) {
            ByteBuf derived = parent.readSlice(16);
            derived.retain();
            process(derived);
        }
    } finally {
        parent.release();
    }
    ...
    
    public void process(ByteBuf buf) {
        ...
        buf.release();
    }
    +}">
    ByteBuf parent = ctx.alloc().directBuffer(512);
    parent.writeBytes(...);
    
    try {
        while (parent.isReadable(16)) {
            ByteBuf derived = parent.readSlice(16);
            derived.retain();
            process(derived);
        }
    } finally {
        parent.release();
    }
    ...
    
    public void process(ByteBuf buf) {
        ...
        buf.release();
    }

    ByteBufHolder interface

    @@ -479,13 +479,13 @@

    Inbound messages

    } finally { buf.release(); } -}">
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        try {
            ...
        } finally {
            buf.release();
        }
    }
    +}">
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        try {
            ...
        } finally {
            buf.release();
        }
    }

    As explained in the 'Who destroys?' section of this document, if your handler passes the buffer (or any reference-counted object) to the next handler, you don't need to release it:

    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        ...
        ctx.fireChannelRead(buf);
    }
    +}">
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        ...
        ctx.fireChannelRead(buf);
    }

    Note that ByteBuf isn't the only reference-counted type in Netty. If you are dealing with the messages generated by decoders, it is very likely that the message is also reference-counted:

    Inbound messages content.release(); } } -}">
    // Assuming your handler is placed next to `HttpRequestDecoder`
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpRequest) {
            HttpRequest req = (HttpRequest) msg;
            ...
        }
        if (msg instanceof HttpContent) {
            HttpContent content = (HttpContent) msg;
            try {
                ...
            } finally {
                content.release();
            }
        }
    }
    +}">
    // Assuming your handler is placed next to `HttpRequestDecoder`
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpRequest) {
            HttpRequest req = (HttpRequest) msg;
            ...
        }
        if (msg instanceof HttpContent) {
            HttpContent content = (HttpContent) msg;
            try {
                ...
            } finally {
                content.release();
            }
        }
    }

    If you are in doubt or you want to simplify releasing the messages, you can use ReferenceCountUtil.release():

    Inbound messages } finally { ReferenceCountUtil.release(msg); } -}">
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        try {
            ...
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }
    +}">
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        try {
            ...
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    Alternatively, you could consider extending SimpleChannelHandler which calls ReferenceCountUtil.release(msg) for all messages you receive.

    Outbound messages

    @@ -538,7 +538,7 @@

    Outbound messages

    // Pass non-HttpContent through. ctx.write(message, promise); } -}'>
    // Simple-pass through
    public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {
        System.err.println("Writing: " + message);
        ctx.write(message, promise);
    }
    
    // Transformation
    public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {
        if (message instanceof HttpContent) {
            // Transform HttpContent to ByteBuf.
            HttpContent content = (HttpContent) message;
            try {
                ByteBuf transformed = ctx.alloc().buffer();
                ....
                ctx.write(transformed, promise);
            } finally {
                content.release();
            }
        } else {
            // Pass non-HttpContent through.
            ctx.write(message, promise);
        }
    }
    +}'>
    // Simple-pass through
    public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {
        System.err.println("Writing: " + message);
        ctx.write(message, promise);
    }
    
    // Transformation
    public void write(ChannelHandlerContext ctx, Object message, ChannelPromise promise) {
        if (message instanceof HttpContent) {
            // Transform HttpContent to ByteBuf.
            HttpContent content = (HttpContent) message;
            try {
                ByteBuf transformed = ctx.alloc().buffer();
                ....
                ctx.write(transformed, promise);
            } finally {
                content.release();
            }
        } else {
            // Pass non-HttpContent through.
            ctx.write(message, promise);
        }
    }

    Troubleshooting buffer leaks

    @@ -650,7 +650,7 @@

    Fixing leaks in unit tests

    // and then release it when the test thread is terminated. ByteBuf buf = releaseLater(Unpooled.directBuffer(512)); ... -}">
    import static io.netty.util.ReferenceCountUtil.*;
    
    @Test
    public void testSomething() throws Exception {
        // ReferenceCountUtil.releaseLater() will keep the reference of buf,
        // and then release it when the test thread is terminated.
        ByteBuf buf = releaseLater(Unpooled.directBuffer(512));
        ...
    }
    +}">
    import static io.netty.util.ReferenceCountUtil.*;
    
    @Test
    public void testSomething() throws Exception {
        // ReferenceCountUtil.releaseLater() will keep the reference of buf,
        // and then release it when the test thread is terminated.
        ByteBuf buf = releaseLater(Unpooled.directBuffer(512));
        ...
    }

    External Links:

    Why do we need to manually handle reference counting for Netty ByteBuf if JVM GC is still in place?

    @@ -696,7 +696,7 @@

    Fixing leaks in unit tests

    -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024
    diff --git a/wiki/related-articles.html b/wiki/related-articles.html index 3f0b6205fac..3b6e1e60f38 100644 --- a/wiki/related-articles.html +++ b/wiki/related-articles.html @@ -43,7 +43,7 @@ diff --git a/wiki/releasing-new-version.html b/wiki/releasing-new-version.html index a402d38c36c..072f5af27cf 100644 --- a/wiki/releasing-new-version.html +++ b/wiki/releasing-new-version.html @@ -43,7 +43,7 @@ diff --git a/wiki/user-guide-for-3.x.html b/wiki/user-guide-for-3.x.html index 71abb3a5051..ee1024f28db 100644 --- a/wiki/user-guide-for-3.x.html +++ b/wiki/user-guide-for-3.x.html @@ -43,7 +43,7 @@
    1. The exceptionCaught() event handler method is called with a Throwable when an exception was raised by Netty due to an I/O error or by a handler implementation due to the exception thrown while processing events. In most cases, the caught exception should be logged and its associated channel should be closed here, although the implementation of this method can be different depending on what you want to do to deal with an exceptional situation. For example, you might want to send a response message with an error code before closing the connection.
    @@ -446,7 +446,7 @@

    Looking into the Received Data

    } finally { ReferenceCountUtil.release(msg); // (2) } -}">
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        try {
            while (in.isReadable()) { // (1)
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } finally {
            ReferenceCountUtil.release(msg); // (2)
        }
    }
    +}">
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        try {
            while (in.isReadable()) { // (1)
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } finally {
            ReferenceCountUtil.release(msg); // (2)
        }
    }
    1. This inefficient loop can actually be simplified to: System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
    2. @@ -464,7 +464,7 @@

      Writing an Echo Server

      public void channelRead(ChannelHandlerContext ctx, Object msg) { ctx.write(msg); // (1) ctx.flush(); // (2) - }">
          @Override
          public void channelRead(ChannelHandlerContext ctx, Object msg) {
              ctx.write(msg); // (1)
              ctx.flush(); // (2)
          }
      + }">
          @Override
          public void channelRead(ChannelHandlerContext ctx, Object msg) {
              ctx.write(msg); // (1)
              ctx.flush(); // (2)
          }
      1. A ChannelHandlerContext object provides various operations that enable you to trigger various I/O events and operations. Here, we invoke write(Object) to write the received message in verbatim. Please note that we did not release the received message unlike we did in the DISCARD example. It is because Netty releases it for you when it is written out to the wire.
      2. @@ -761,20 +761,20 @@

        Speaking in POJO instead of By } out.add(new UnixTime(in.readUnsignedInt())); -}">
        @Override
        protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
            if (in.readableBytes() < 4) {
                return;
            }
        
            out.add(new UnixTime(in.readUnsignedInt()));
        }
        +}">
        @Override
        protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
            if (in.readableBytes() < 4) {
                return;
            }
        
            out.add(new UnixTime(in.readUnsignedInt()));
        }

        With the updated decoder, the TimeClientHandler does not use ByteBuf anymore:

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            UnixTime m = (UnixTime) msg;
            System.out.println(m);
            ctx.close();
        }
        +}">
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            UnixTime m = (UnixTime) msg;
            System.out.println(m);
            ctx.close();
        }

        Much simpler and elegant, right? The same technique can be applied on the server side. Let us update the TimeServerHandler first this time:

        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ChannelFuture f = ctx.writeAndFlush(new UnixTime());
            f.addListener(ChannelFutureListener.CLOSE);
        }
        +}">
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ChannelFuture f = ctx.writeAndFlush(new UnixTime());
            f.addListener(ChannelFutureListener.CLOSE);
        }

        Now, the only missing piece is an encoder, which is an implementation of ChannelOutboundHandler that translates a UnixTime back into a ByteBuf. It's much simpler than writing a decoder because there's no need to deal with packet fragmentation and assembly when encoding a message.

        Summary

        -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024
        diff --git a/wiki/user-guide-for-5.x.html b/wiki/user-guide-for-5.x.html index 4eb73fec688..bd1bc5bf2b2 100644 --- a/wiki/user-guide-for-5.x.html +++ b/wiki/user-guide-for-5.x.html @@ -43,7 +43,7 @@ +}">
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            try {
                // Do something with msg
            } finally {
                ReferenceCountUtil.release(msg);
            }
        }
        1. The exceptionCaught() event handler method is called with a Throwable when an exception was raised by Netty due to an I/O error or by a handler implementation due to the exception thrown while processing events. In most cases, the caught exception should be logged and its associated channel should be closed here, although the implementation of this method can be different depending on what you want to do to deal with an exceptional situation. For example, you might want to send a response message with an error code before closing the connection.
        @@ -454,7 +454,7 @@

        Looking into the Received Data

        } finally { ReferenceCountUtil.release(msg); // (2) } -}">
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            try {
                while (in.isReadable()) { // (1)
                    System.out.print((char) in.readByte());
                    System.out.flush();
                }
            } finally {
                ReferenceCountUtil.release(msg); // (2)
            }
        }
        +}">
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            try {
                while (in.isReadable()) { // (1)
                    System.out.print((char) in.readByte());
                    System.out.flush();
                }
            } finally {
                ReferenceCountUtil.release(msg); // (2)
            }
        }
        1. This inefficient loop can actually be simplified to: System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
        2. @@ -472,7 +472,7 @@

          Writing an Echo Server

          public void channelRead(ChannelHandlerContext ctx, Object msg) { ctx.write(msg); // (1) ctx.flush(); // (2) - }">
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg) {
                  ctx.write(msg); // (1)
                  ctx.flush(); // (2)
              }
          + }">
              @Override
              public void channelRead(ChannelHandlerContext ctx, Object msg) {
                  ctx.write(msg); // (1)
                  ctx.flush(); // (2)
              }
          1. A ChannelHandlerContext object provides various operations that enable you to trigger various I/O events and operations. Here, we invoke write(Object) to write the received message in verbatim. Please note that we did not release the received message unlike we did in the DISCARD example. It is because Netty releases it for you when it is written out to the wire.
          2. @@ -768,20 +768,20 @@

            Speaking in POJO instead of By } out.add(new UnixTime(in.readUnsignedInt())); -}">
            @Override
            protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
                if (in.readableBytes() < 4) {
                    return;
                }
            
                out.add(new UnixTime(in.readUnsignedInt()));
            }
            +}">
            @Override
            protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
                if (in.readableBytes() < 4) {
                    return;
                }
            
                out.add(new UnixTime(in.readUnsignedInt()));
            }

            With the updated decoder, the TimeClientHandler does not use ByteBuf anymore:

            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) {
                UnixTime m = (UnixTime) msg;
                System.out.println(m);
                ctx.close();
            }
            +}">
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) {
                UnixTime m = (UnixTime) msg;
                System.out.println(m);
                ctx.close();
            }

            Much simpler and elegant, right? The same technique can be applied on the server side. Let us update the TimeServerHandler first this time:

            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                ChannelFuture f = ctx.writeAndFlush(new UnixTime());
                f.addListener(ChannelFutureListener.CLOSE);
            }
            +}">
            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                ChannelFuture f = ctx.writeAndFlush(new UnixTime());
                f.addListener(ChannelFutureListener.CLOSE);
            }

            Now, the only missing piece is an encoder, which is an implementation of ChannelHandler that translates a UnixTime back into a ByteBuf. It's much simpler than writing a decoder because there's no need to deal with packet fragmentation and assembly when encoding a message.

            Summary

            -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024
            diff --git a/wiki/user-guide.html b/wiki/user-guide.html index 51fe8ec6d7a..cb2c6bbddaa 100644 --- a/wiki/user-guide.html +++ b/wiki/user-guide.html @@ -43,7 +43,7 @@
            -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024
            diff --git a/wiki/using-as-a-generic-library.html b/wiki/using-as-a-generic-library.html index c871a55e973..f14cc67e8c6 100644 --- a/wiki/using-as-a-generic-library.html +++ b/wiki/using-as-a-generic-library.html @@ -43,7 +43,7 @@ +obj.recycle();'>
            public class MyObject {
            
              private static final Recycler<MyObject> RECYCLER = new Recycler<MyObject>() {
                protected MyObject newObject(Recycler.Handle<MyObject> handle) {
                  return new MyObject(handle);
                }
              }
            
              public static MyObject newInstance(int a, String b) {
                MyObject obj = RECYCLER.get();
                obj.myFieldA = a;
                obj.myFieldB = b;
                return obj;
              }
                
              private final Recycler.Handle<MyObject> handle;
              private int myFieldA;
              private String myFieldB;
            
              private MyObject(Handle<MyObject> handle) {
                this.handle = handle;
              }
              
              public boolean recycle() {
                myFieldA = 0;
                myFieldB = null;
                return handle.recycle(this);
              }
            }
            
            MyObject obj = MyObject.newInstance(42, "foo");
            ...
            obj.recycle();

            User-extensible enum

            @@ -533,7 +533,7 @@

            Comparison with Guava and JDK8

            -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024
            diff --git a/wiki/writing-a-commit-message.html b/wiki/writing-a-commit-message.html index efc02fa8e7c..a6e13ff4a0b 100644 --- a/wiki/writing-a-commit-message.html +++ b/wiki/writing-a-commit-message.html @@ -43,7 +43,7 @@
            -Last retrieved on 13-Nov-2024 +Last retrieved on 11-Dec-2024