Skip to content

Commit 3cc4052

Browse files
committed
New native transport for kqueue
Motivation: We currently don't have a native transport which supports kqueue https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2. This can be useful for BSD systems such as MacOS to take advantage of native features, and provide feature parity with the Linux native transport. Modifications: - Make a new transport-native-unix-common module with all the java classes and JNI code for generic unix items. This module will build a static library for each unix platform, and included in the dynamic libraries used for JNI (e.g. transport-native-epoll, and eventually kqueue). - Make a new transport-native-unix-common-tests module where the tests for the transport-native-unix-common module will live. This is so each unix platform can inherit from these test and ensure they pass. - Add a new transport-native-kqueue module which uses JNI to directly interact with kqueue Result: JNI support for kqueue. Fixes netty#2448 Fixes netty#4231
1 parent 2d38a44 commit 3cc4052

File tree

145 files changed

+10341
-1260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+10341
-1260
lines changed

all/pom.xml

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
<profiles>
3737
<profile>
3838
<id>full</id>
39-
39+
<activation>
40+
<property>
41+
<name>uber</name>
42+
</property>
43+
</activation>
4044
<!-- Only include in full profile as this will not work on Java9 yet -->
4145
<!-- https://issues.apache.org/jira/browse/JXR-133 -->
4246
<build>
@@ -162,25 +166,6 @@
162166
</plugins>
163167
</build>
164168
</profile>
165-
<profile>
166-
<id>linux</id>
167-
<activation>
168-
<os>
169-
<family>linux</family>
170-
</os>
171-
</activation>
172-
<dependencies>
173-
<!-- All release modules -->
174-
<dependency>
175-
<groupId>${project.groupId}</groupId>
176-
<artifactId>netty-transport-native-epoll</artifactId>
177-
<version>${project.version}</version>
178-
<classifier>${epoll.classifier}</classifier>
179-
<scope>compile</scope>
180-
<optional>true</optional>
181-
</dependency>
182-
</dependencies>
183-
</profile>
184169
</profiles>
185170

186171
<dependencies>
@@ -347,6 +332,22 @@
347332
<scope>compile</scope>
348333
<optional>true</optional>
349334
</dependency>
335+
<dependency>
336+
<groupId>${project.groupId}</groupId>
337+
<artifactId>netty-transport-native-epoll</artifactId>
338+
<version>${project.version}</version>
339+
<classifier>linux-x86_64</classifier>
340+
<scope>compile</scope>
341+
<optional>true</optional>
342+
</dependency>
343+
<dependency>
344+
<groupId>${project.groupId}</groupId>
345+
<artifactId>netty-transport-native-kqueue</artifactId>
346+
<version>${project.version}</version>
347+
<classifier>osx-x86_64</classifier>
348+
<scope>compile</scope>
349+
<optional>true</optional>
350+
</dependency>
350351

351352
<!-- Add optional dependencies explicitly to avoid Javadoc warnings and errors. -->
352353
<dependency>
@@ -429,7 +430,7 @@
429430
<goal>unpack-dependencies</goal>
430431
</goals>
431432
<configuration>
432-
<excludes>io/netty/example/**,META-INF/native/libnetty-tcnative*</excludes>
433+
<excludes>io/netty/example/**,META-INF/native/libnetty-tcnative*,META-INF/native/include/**,META-INF/native/**/*.a</excludes>
433434
<includes>io/netty/**,META-INF/native/**</includes>
434435
<includeScope>runtime</includeScope>
435436
<includeGroupIds>${project.groupId}</includeGroupIds>

common/src/main/java/io/netty/util/NetUtil.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import java.io.BufferedReader;
2525
import java.io.File;
2626
import java.io.FileReader;
27+
import java.io.IOException;
28+
import java.io.InputStream;
29+
import java.io.InputStreamReader;
2730
import java.net.Inet4Address;
2831
import java.net.Inet6Address;
2932
import java.net.InetAddress;
@@ -271,12 +274,27 @@ public Integer run() {
271274
logger.debug("{}: {}", file, somaxconn);
272275
}
273276
} else {
274-
if (logger.isDebugEnabled()) {
275-
logger.debug("{}: {} (non-existent)", file, somaxconn);
277+
// Try to get from sysctl
278+
Integer tmp = null;
279+
if (SystemPropertyUtil.getBoolean("io.netty.net.somaxconn.trySysctl", false)) {
280+
tmp = sysctlGetInt("kern.ipc.somaxconn");
281+
if (tmp == null) {
282+
tmp = sysctlGetInt("kern.ipc.soacceptqueue");
283+
if (tmp != null) {
284+
somaxconn = tmp;
285+
}
286+
} else {
287+
somaxconn = tmp;
288+
}
289+
}
290+
291+
if (tmp == null) {
292+
logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file,
293+
somaxconn);
276294
}
277295
}
278296
} catch (Exception e) {
279-
logger.debug("Failed to get SOMAXCONN from: {}", file, e);
297+
logger.debug("Failed to get SOMAXCONN from sysctl and file {}. Default: {}", file, somaxconn, e);
280298
} finally {
281299
if (in != null) {
282300
try {
@@ -291,6 +309,38 @@ public Integer run() {
291309
});
292310
}
293311

312+
/**
313+
* This will execute <a href ="https://www.freebsd.org/cgi/man.cgi?sysctl(8)">sysctl</a> with the {@code sysctlKey}
314+
* which is expected to return the numeric value for for {@code sysctlKey}.
315+
* @param sysctlKey The key which the return value corresponds to.
316+
* @return The <a href ="https://www.freebsd.org/cgi/man.cgi?sysctl(8)">sysctl</a> value for {@code sysctlKey}.
317+
*/
318+
private static Integer sysctlGetInt(String sysctlKey) throws IOException {
319+
Process process = new ProcessBuilder("sysctl", sysctlKey).start();
320+
try {
321+
InputStream is = process.getInputStream();
322+
InputStreamReader isr = new InputStreamReader(is);
323+
BufferedReader br = new BufferedReader(isr);
324+
try {
325+
String line = br.readLine();
326+
if (line.startsWith(sysctlKey)) {
327+
for (int i = line.length() - 1; i > sysctlKey.length(); --i) {
328+
if (!Character.isDigit(line.charAt(i))) {
329+
return Integer.valueOf(line.substring(i + 1, line.length()));
330+
}
331+
}
332+
}
333+
return null;
334+
} finally {
335+
br.close();
336+
}
337+
} finally {
338+
if (process != null) {
339+
process.destroy();
340+
}
341+
}
342+
}
343+
294344
/**
295345
* Returns {@code true} if IPv4 should be used even if the system supports both IPv4 and IPv6. Setting this
296346
* property to {@code true} will disable IPv6 support. The default value of this property is {@code false}.

common/src/main/java/io/netty/util/internal/EmptyArrays.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
public final class EmptyArrays {
2626

27+
public static final int[] EMPTY_INTS = {};
2728
public static final byte[] EMPTY_BYTES = {};
2829
public static final char[] EMPTY_CHARS = {};
2930
public static final Object[] EMPTY_OBJECTS = {};

common/src/main/java/io/netty/util/internal/PlatformDependent.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ public static void freeMemory(long address) {
287287
PlatformDependent0.freeMemory(address);
288288
}
289289

290+
public static long reallocateMemory(long address, long newSize) {
291+
return PlatformDependent0.reallocateMemory(address, newSize);
292+
}
293+
290294
/**
291295
* Raises an exception bypassing compiler checks for checked exceptions.
292296
*/

common/src/main/java/io/netty/util/internal/PlatformDependent0.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,10 @@ static void freeMemory(long address) {
752752
UNSAFE.freeMemory(address);
753753
}
754754

755+
static long reallocateMemory(long address, long newSize) {
756+
return UNSAFE.reallocateMemory(address, newSize);
757+
}
758+
755759
private PlatformDependent0() {
756760
}
757761
}

microbench/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
<groupId>${project.groupId}</groupId>
5252
<artifactId>netty-transport-native-epoll</artifactId>
5353
<version>${project.version}</version>
54-
<classifier>${epoll.classifier}</classifier>
54+
<classifier>${jni.classifier}</classifier>
5555
</dependency>
5656
</dependencies>
5757
<build>

pom.xml

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -146,55 +146,72 @@
146146
</os>
147147
</activation>
148148
<modules>
149+
<module>transport-native-unix-common-tests</module>
150+
<module>transport-native-unix-common</module>
149151
<module>transport-native-epoll</module>
150152
</modules>
151153
</profile>
152-
<!--
153-
Netty must be released from RHEL 6.8 x86_64 or compatible so that:
154-
155-
1) we ship x86_64 version of epoll transport officially, and
156-
2) we ensure the ABI compatibility with older GLIBC versions.
154+
<profile>
155+
<id>mac</id>
156+
<activation>
157+
<os>
158+
<family>mac</family>
159+
</os>
160+
</activation>
161+
<modules>
162+
<module>transport-native-unix-common-tests</module>
163+
<module>transport-native-unix-common</module>
164+
<module>transport-native-kqueue</module>
165+
</modules>
166+
</profile>
167+
<profile>
168+
<id>freebsd</id>
169+
<activation>
170+
<os>
171+
<family>unix</family>
172+
<name>freebsd</name>
173+
</os>
174+
</activation>
175+
<modules>
176+
<module>transport-native-unix-common-tests</module>
177+
<module>transport-native-unix-common</module>
178+
<module>transport-native-kqueue</module>
179+
</modules>
180+
</profile>
181+
<profile>
182+
<id>openbsd</id>
183+
<activation>
184+
<os>
185+
<family>unix</family>
186+
<name>openbsd</name>
187+
</os>
188+
</activation>
189+
<modules>
190+
<module>transport-native-unix-common-tests</module>
191+
<module>transport-native-unix-common</module>
192+
<module>transport-native-kqueue</module>
193+
</modules>
194+
</profile>
195+
<!-- The uber artifacts depend on artifacts built from different platforms and will fail if these artifacts are not
196+
available. Typically we only build the uber jars as part of the release process so the build sequencing
197+
is controlled and can be sequenced correctly. For example we may do the following:
157198

158-
The shared library built on a distribution with newer GLIBC
159-
will not run on older distributions.
160-
-->
199+
<from a linux machine>
200+
$ mvn release
201+
<after this completes log onto a MacOS machine, note fail-at-end, and -D to activate multiple profiles>
202+
$ mvn release -fae -Duber
203+
-->
161204
<profile>
162-
<id>restricted-release</id>
163-
<build>
164-
<plugins>
165-
<plugin>
166-
<artifactId>maven-enforcer-plugin</artifactId>
167-
<executions>
168-
<execution>
169-
<id>enforce-release-environment</id>
170-
<goals>
171-
<goal>enforce</goal>
172-
</goals>
173-
<configuration>
174-
<rules>
175-
<requireProperty>
176-
<regexMessage>
177-
Release process must be performed on linux-x86_64.
178-
</regexMessage>
179-
<property>os.detected.classifier</property>
180-
<regex>^linux-x86_64$</regex>
181-
</requireProperty>
182-
<requireFilesContent>
183-
<message>
184-
Release process must be performed on RHEL 6.8 or its derivatives.
185-
</message>
186-
<files>
187-
<file>/etc/redhat-release</file>
188-
</files>
189-
<content>release 6.8</content>
190-
</requireFilesContent>
191-
</rules>
192-
</configuration>
193-
</execution>
194-
</executions>
195-
</plugin>
196-
</plugins>
197-
</build>
205+
<id>uber</id>
206+
<activation>
207+
<property>
208+
<name>uber</name>
209+
</property>
210+
</activation>
211+
<modules>
212+
<module>all</module>
213+
<module>tarball</module>
214+
</modules>
198215
</profile>
199216
<profile>
200217
<!--
@@ -252,7 +269,7 @@
252269
<conscrypt.artifactId>conscrypt-openjdk-uber</conscrypt.artifactId>
253270
<conscrypt.version>1.0.0.RC7</conscrypt.version>
254271
<conscrypt.classifier />
255-
<epoll.classifier>${os.detected.name}-${os.detected.arch}</epoll.classifier>
272+
<jni.classifier>${os.detected.name}-${os.detected.arch}</jni.classifier>
256273
<logging.config>${project.basedir}/../common/src/test/resources/logback-test.xml</logging.config>
257274
<logging.logLevel>debug</logging.logLevel>
258275
<log4j2.version>2.6.2</log4j2.version>
@@ -291,9 +308,7 @@
291308
<module>testsuite-autobahn</module>
292309
<module>testsuite-osgi</module>
293310
<module>microbench</module>
294-
<module>all</module>
295311
<module>bom</module>
296-
<module>tarball</module>
297312
</modules>
298313

299314
<dependencyManagement>
@@ -979,7 +994,7 @@
979994
<version>2.5.3</version>
980995
<configuration>
981996
<useReleaseProfile>false</useReleaseProfile>
982-
<arguments>-P restricted-release,sonatype-oss-release,full</arguments>
997+
<arguments>-P restricted-release,sonatype-oss-release</arguments>
983998
<autoVersionSubmodules>true</autoVersionSubmodules>
984999
<allowTimestampedSnapshots>false</allowTimestampedSnapshots>
9851000
<tagNameFormat>netty-@{project.version}</tagNameFormat>
@@ -1110,18 +1125,6 @@
11101125

11111126
<pluginManagement>
11121127
<plugins>
1113-
<plugin>
1114-
<artifactId>maven-enforcer-plugin</artifactId>
1115-
<version>1.4.1</version>
1116-
<dependencies>
1117-
<!-- Provides the 'requireFilesContent' enforcer rule. -->
1118-
<dependency>
1119-
<groupId>com.ceilfors.maven.plugin</groupId>
1120-
<artifactId>enforcer-rules</artifactId>
1121-
<version>1.2.0</version>
1122-
</dependency>
1123-
</dependencies>
1124-
</plugin>
11251128
<!-- keep surefire and failsafe in sync -->
11261129
<plugin>
11271130
<artifactId>maven-surefire-plugin</artifactId>

tarball/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@
9696
<profiles>
9797
<profile>
9898
<id>full</id>
99+
<activation>
100+
<property>
101+
<name>uber</name>
102+
</property>
103+
</activation>
99104
<build>
100105
<plugins>
101106
<plugin>

0 commit comments

Comments
 (0)