Commit Graph

598 Commits

Author SHA1 Message Date
Norman Maurer
36b80c25f7 Correctly return from selector loop one a scheduled task is ready for processing
Motivation:

We use the nanoTime of the scheduledTasks to calculate the milli-seconds to wait for a select operation to select something. Once these elapsed we check if there was something selected or some task is ready for processing. Unfortunally we not take into account scheduled tasks here so the selection loop will continue if only scheduled tasks are ready for processing. This will delay the execution of these tasks.

Modification:

- Check if a scheduled task is ready after selecting
- also make a tiny change in NioEventLoop to not trigger a rebuild if nothing was selected because the timeout was reached a few times in a row.

Result:

Execute scheduled tasks on time.
2014-07-02 09:10:37 +02:00
Norman Maurer
23840b76d7 [#2623] Release local references to guard against StackOverflow in JNI
Motivation:

When we do a (env*)->GetObjectArrayElement(...) call we may created many local references which will only be cleaned up once we exist the native method. Thus a lot of memory can be used and so a StackOverFlow may be triggered. Beside this the JNI specification only say that an implementation must cope with 16 local references.

Modification:

Call (env*)->ReleaseLocalRef(...) to release the resource once not needed anymore.

Result:

Less memory usage and guard against StackOverflow
2014-06-30 09:57:13 +02:00
Norman Maurer
776f3aeb3d Let EpollReuseAddrTest also work with kernel versions that not have bugfix release part 2014-06-27 17:56:17 +02:00
Norman Maurer
76cd3a37e5 [#2598] Add Epoll.isAvailable() which allows to check if epoll can be used.
Motivation:

At the moment there is no simple way for a user to check if the native epoll transport can be used on the running platform. Thus the user can only try to instance it and catch any exception and fallback to nio transport.

Modification:

Add Epoll.isAvailable() which allows to check if epoll can be used.

Result:

User can easily check if epoll transport can be used or not
2014-06-26 12:27:09 +02:00
Norman Maurer
b0e5c9be00 [#2605] Use SO_REUSEADDR on EpollServerSocketChannel to match defaults of java.nio.ServerSocketChannel impl
Motivation:

When using openjdk and oracle jdk's nio (while using the nio transport) the ServerSocketChannel uses SO_REUSEADDR by default. Our native transport should do the same to make it easier to switch between the different implementations and get the expected result.

Modification:

Change EpollServerSocketChannelConfig to set SO_REUSEADDR on the created socket.

Result:

SO_REUSEADDR is used by default on servers.
2014-06-26 11:57:40 +02:00
Norman Maurer
31211487e9 Use IntObjectMap to replace Map in EpollEventLoop.
Motivation:

We need to map from ints to AbstractEpollChannel in EpollEventLoop but there is no need for box to Integer.

Modification:

Replace Map with IntObjectMap.

Result:

No more auto-boxing needed.
2014-06-25 20:22:58 +02:00
Trustin Lee
e99f26fe09 Make sure OpenSslEngine is tested against transport-native-epoll 2014-06-21 18:28:54 +09:00
Trustin Lee
b6c0c0c95f Add an OpenSslEngine and the universal API for enabling SSL
Motivation:

Some users already use an SSLEngine implementation in finagle-native. It
wraps OpenSSL to get higher SSL performance.  However, to take advantage
of it, finagle-native must be compiled manually, and it means we cannot
pull it in as a dependency and thus we cannot test our SslHandler
against the OpenSSL-based SSLEngine.  For an instance, we had #2216.

Because the construction procedures of JDK SSLEngine and OpenSslEngine
are very different from each other, we also need to provide a universal
way to enable SSL in a Netty application.

Modifications:

- Pull netty-tcnative in as an optional dependency.
  http://netty.io/wiki/forked-tomcat-native.html
- Backport NativeLibraryLoader from 4.0
- Move OpenSSL-based SSLEngine implementation into our code base.
  - Copied from finagle-native; originally written by @jpinner et al.
  - Overall cleanup by @trustin.
- Run all SslHandler tests with both default SSLEngine and OpenSslEngine
- Add a unified API for creating an SSL context
  - SslContext allows you to create a new SSLEngine or a new SslHandler
    with your PKCS#8 key and X.509 certificate chain.
  - Add JdkSslContext and its subclasses
  - Add OpenSslServerContext
- Add ApplicationProtocolSelector to ensure the future support for NPN
  (NextProtoNego) and ALPN (Application Layer Protocol Negotiation) on
  the client-side.
- Add SimpleTrustManagerFactory to help a user write a
  TrustManagerFactory easily, which should be useful for those who need
  to write an alternative verification mechanism. For example, we can
  use it to implement an unsafe TrustManagerFactory that accepts
  self-signed certificates for testing purposes.
- Add InsecureTrustManagerFactory and FingerprintTrustManager for quick
  and dirty testing
- Add SelfSignedCertificate class which generates a self-signed X.509
  certificate very easily.
- Update all our examples to use SslContext.newClient/ServerContext()
- SslHandler now logs the chosen cipher suite when handshake is
  finished.

Result:

- Cleaner unified API for configuring an SSL client and an SSL server
  regardless of its internal implementation.
- When native libraries are available, OpenSSL-based SSLEngine
  implementation is selected automatically to take advantage of its
  performance benefit.
- Examples take advantage of this modification and thus are cleaner.
2014-05-18 02:54:06 +09:00
Norman Maurer
59d92ad6cf [#2485] Use RecvByteBufAllocator for all allocations related to read from Channel
Motivation:
At the moment we sometimes use only RecvByteBufAllocator.guess() to guess the next size and the use the ByteBufAllocator.* directly to allocate the buffer. We should always use RecvByteBufAllocator.allocate(...) all the time as this makes the behavior easier to adjust.

Modifications:
Change the read() implementations to make use of RecvByteBufAllocator.

Result:
Behavior is more consistent.
2014-05-10 15:27:43 +02:00
Norman Maurer
c5e4c2294e [#2469] Correctly update indices after incomplete gathering write
Motivation:
 When doing a gathering write we need to update the indices after the write partial completes. In the current code-base we use the wrong value when compare the expected written bytes and the actual written bytes.

 Modifications:
 Use the correct value when compare.

Result:
Indices are updated correctly and so no corruption can happen when resume writing after data was only partial written before.
2014-05-07 07:13:39 +02:00
Trustin Lee
296db210ab Generate the default JAR to make oss.sonatype.org happy
Motivation:

oss.sonatype.org refuses to promote an artifact if it doesn't have the
default JAR (the JAR without classifier.)

Modifications:

- Generate both the default JAR and the native JAR to make
  oss.sonatype.org happy
- Rename the profile 'release' to 'restricted-release' which reflects
  what it really does better
- Remove the redundant <quickbuild>true</quickbuild> in all/pom.xml
  We specify the profile 'full' that triggers that property already
  in maven-release-plugin configuration.

Result:

oss.sonatype.org is happy.  Simpler pom.xml
2014-05-03 17:32:45 +09:00
Trustin Lee
6c1af9036f Simplify native library resolution using os-maven-plugin
Motivation:

So far, we used a very simple platform string such as linux64 and
linux32.  However, this is far from perfection because it does not
include anything about the CPU architecture.

Also, the current build tries to put multiple versions of .so files into
a single JAR.  This doesn't work very well when we have to ship for many
different platforms.  Think about shipping .so/.dynlib files for both
Linux and Mac OS X.

Modification:

- Use os-maven-plugin as an extension to determine the current OS and
  CPU architecture reliable at build time
- Use Maven classifier instead of trying to put all shared libraries
  into a single JAR
- NativeLibraryLoader does not guess the OS and bit mode anymore and it
  always looks for the same location regardless of platform, because the
  Maven classifier does the job instead.

Result:

Better scalable native library deployment and retrieval
2014-05-02 04:21:47 +09:00
Trustin Lee
b9039eaa82 Synchronized between 4.1 and master again (part 2)
Motivation:
4 and 5 were diverged long time ago and we recently reverted some of the
early commits in master.  We must make sure 4.1 and master are not very
different now.

Modification:
Remove ChannelHandlerInvoker.writeAndFlush(...) and the related
implementations.

Result:
4.1 and master got closer.
2014-04-25 15:06:26 +09:00
Norman Maurer
9afb56c3c6 [#2414] Fix IllegalStateException when try to configure AbstractEpollChannel once it is deregistered
Motivation:
AbstractEpollChannel.clearEpollIn() throws an IllegalStateException if a user tries to change the autoRead configuration for the Channel and the Channel is not registered on an EventLoop yet. This makes it for example impossible to set AUTO_READ to false via the ServerBootstrap as the configuration is modifed before the Channel is registered.

Modification:
Check if the Channel is registered and if not just modify the flags directly so they are respected once the Channel is registered

Result:
It is possible now to configure AUTO_READ via the ServerBootstrap
2014-04-22 10:18:17 +02:00
Norman Maurer
ff4a89b5ae [#2414] Fix RuntimeException during modify events via EpollEventLoop
Motivation:
We are currently try to modify the events via EpollEventLoop even when the channel was closed before and so the fd was set to -1. This fails with a RuntimeException in this case.

Modification:
Always check if the Channel is still open before try to modify the events.

Result:
No more RuntimeException because of a not open channel
2014-04-21 11:19:08 +02:00
Norman Maurer
b5ab5150be Use correct generics for TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT in EpollChannelOption. Part of [#2396]
Motivation:
Currently the generics used for TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT are incorrect.

Modifications:
Use Integer as type

Result:
User can use TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT as expected
2014-04-21 10:00:26 +02:00
Norman Maurer
d6ec44c871 Fix buffer leak in EpollDatagramChannel
Motivation:
EpollDatagramChannel produced buffer leaks when tried to read from the channel and nothing was ready to be read.

Modifications:
Correctly release buffer if nothing was read

Result:
No buffer leak
2014-04-18 20:37:52 +02:00
Norman Maurer
97553069b6 [#2396] Allow to set TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT in native transport
Motivation:
Allow to set TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT in native transport to offer the user with more flexibility.

Modifications:
Expose methods to set these options and write the JNI implementation.

Result:
User can now use TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT.
2014-04-18 11:32:17 +02:00
Norman Maurer
199d2b499c [#2405] Add support for SO_REUSEPORT to EpollDatagramChannel
Motivation:
With SO_REUSEPORT it is possible to bind multiple sockets to the same port and so handle the processing of packets via multiple threads. This allows to handle DatagramPackets with more then one thread on the same port and so gives better performance.

Modifications:
Expose EpollDatagramChannelConfig.setReusePort(..) and isReusePort()

Result:
Allow to bind multiple times to the same local address and so archive better performance.
2014-04-17 11:55:38 +02:00
Norman Maurer
20ef4690e7 [#2375] [#2404] Fix bug in respecting ChannelConfig.setAutoRead(false) and also fix Channel.read() for OIO
Motivation:
At the moment ChanneConfig.setAutoRead(false) only is guaranteer to not have an extra channelRead(...) triggered when used from within the channelRead(...) or channelReadComplete(...) method. This is not the correct behaviour as it should also work from other methods that are triggered from within the EventLoop. For example a valid use case is to have it called from within a ChannelFutureListener, which currently not work as expected.

Beside this there is another bug which is kind of related. Currently Channel.read() will not work as expected for OIO as we will stop try to read even if nothing could be read there after one read operation on the socket (when the SO_TIMEOUT kicks in).

Modifications:
Implement the logic the right way for the NIO/OIO/SCTP and native transport, specific to the transport implementation. Also correctly handle Channel.read() for OIO transport by trigger a new read if SO_TIMEOUT was catched.

Result:
It is now also possible to use ChannelConfig.setAutoRead(false) from other methods that are called from within the EventLoop and have direct effect.

Conflicts:
	transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpChannel.java
	transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java
	transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java
2014-04-17 07:50:51 +02:00
Norman Maurer
91b3780054 [#2377] Implement epoll based DatagramChannel
Motivation:
There is currently no epoll based DatagramChannel. We should add one to make the set of provided channels complete and also to be able to offer better performance compared to the NioDatagramChannel once SO_REUSEPORT is implemented.

Modifications:
Add implementation of DatagramChannel which uses epoll. This implementation does currently not support multicast yet which will me implemented later on. As most users will not use multicast anyway I think it is fair to just add the EpollDatagramChannel without the support for now. We shipped NioDatagramChannel without support earlier too ...

Result:
Be able to use EpollDatagramChannel for max. performance on linux
2014-04-16 15:05:43 +02:00
Norman Maurer
6615d72db0 [#2376] Add support for SO_REUSEPORT in native transport
Motivation:
In linux kernel 3.9 a new featured named SO_REUSEPORT was introduced which allows to have multiple sockets bind to the same port and so handle the accept() of new connections with multiple threads. This can greatly improve the performance when you not to accept a lot of connections.

Modifications:
Implement SO_REUSEPORT via JNI

Result:
Be able to use the SO_REUSEPORT feature when using the EpollServerSocketChannel
2014-04-16 14:37:49 +02:00
Norman Maurer
ad955fa8a4 [#2371] Fix Potential data corruption in EpollSocketChannel when writing to the Channel
Motivation:
We sometimes see data corruption when writing to the EpollSocketChannel.

Modifications:
Correctly update the position of the ByteBuffer after something was written.

Result:
Fix data-corruption which could happen on partial writes
2014-04-09 14:25:39 +02:00
Norman Maurer
88481131be [#2353] Use a privileged block to get ClassLoader and System property if needed
Motivation:
When using System.getProperty(...) and various methods to get a ClassLoader it will fail when a SecurityManager is in place.

Modifications:
Use a priveled block if needed. This work is based in the PR #2353 done by @anilsaldhana .

Result:
Code works also when SecurityManager is present
2014-04-08 14:12:25 +02:00
Norman Maurer
791c38befe [#2359] EpollSocketChannel.remoteAddress0() is always null on accepted EpollSocketChannels
Motivation:
EpollSocketChannel.remoteAddress0() is always null on accepted EpollSocketChannels as we not set it excplicit.

Modifications:
Correctly retrieve the local and remote address when accept new channel and store it

Result:
EpollSocketchannel.remoteAddress0() and EpollSocketChannel.localAddress0() return correct addresses
2014-04-04 15:45:14 +02:00
Norman Maurer
2fa79b2d5d [#2361] Native.epollCreate(...) fails on systems using a kernel < 2.6.27 / glibc < 2.9
Motivation:
Native.epollCreate(...) fails on systems using a kernel < 2.6.27 / glibc < 2.9 because it uses epoll_create1(...) without checking if it is present

Modifications:
Check if epoll_create1(...) exists abd if not fall back to use epoll_create(...)

Result:
Works even on systems with kernel < 2.6.27 / glibc < 2.9
2014-04-04 07:56:01 +02:00
Trustin Lee
844362a947 User-definable thread model via ChannelHandlerInvoker
Motivation:

While the default thread model provided by Netty is reasonable enough for most applications, some users might have a special requirement for the thread model.  Here are a few examples:

- A user might want to invoke handlers from the caller thread directly, assuming that his or her application is completely asynchronous and does not make any invocation from non-I/O thread.  In this case, the default invoker implementation will only add the overhead of checking if the current thread is an I/O thread or not.
- A user might want to invoke handlers from different threads depending on the type of events flexibly.

Modifications:

- Backport 132af3a485 which is a fix for #1912
  - Add a new interface called 'ChannelHandlerInvoker' that performs the invocation of event handler methods.
  - Add pipeline manipulation methods that accept ChannelHandlerInvoker
- The differences from the original commit:
  - Separated the irrelevant changes out
  - Channel.eventLoop is null until the registration is complete in this branch, so Channel.Unsafe.invoker() doesn't work before registration.
  - Deregistration is not gone in this branch, so the methods related with deregistration were added to ChannelHandlerInvoker
2014-03-24 18:09:27 +09:00
Norman Maurer
32ccdcdb18 Make sure the local / remote InetSocketAddres can be obtained. Part of [#2262]
Motivation:
Make sure the remote/local InetSocketAddress can be obtained correctly

Modifications:
Set the remote/local InetSocketAddress after a bind/connect operation was performed

Result:
It is possible to still access the informations even after the fd became invalid. This mirror the behaviour of NIO.
2014-03-22 22:02:19 +01:00
Trustin Lee
bd9ad4b532 Perform cross-tests between NIO and epoll transport
Motivation:

The epoll testsuite tests the epoll transport only against itself (i.e. epoll x epoll only).  We should test the epoll transport also against the well-tested NIO transport, too.

Modifications:

- Make SocketTestPermutation extensible and reusable so that the epoll testsuite can take advantage of it.
- Rename EpollTestUtils to EpollSocketTestPermutation and make it extend SocketTestPermutation.
- Overall clean-up of SocketTestPermutation
  - Use Arrays.asList() for simplicity
  - Add combo() method to remove code duplication

Result:

The epoll transport is now also tested against the NIO transport.  SocketTestPermutation got cleaner.
2014-03-17 10:35:48 +09:00
Trustin Lee
1a72bd09d5 Fix 'incompatible event loop' regression
Motivation:

Previous commit (2de65e25e9) introduced a regression that makes the epoll testsuite fail with an 'incompatible event loop' error.

Modifications:

Use the correct event loop type.

Result:

Build doesn't fail anymore.
2014-03-17 09:51:16 +09:00
Trustin Lee
2de65e25e9 Set timeout for SocketSslEchoTest
Motivation:

We are seeing EpollSocketSslEchoTest does not finish itself while its I/O thread is busy.  Jenkins should have terminated them when the global build timeout reaches, but Jenkins seems to fail to do so.  What's more interesting is that Jenkins will start another job before the EpollSocketSslEchoTest is terminated, and Linux starts to oom-kill them, impacting the uptime of the CI service.

Modifications:

- Set timeout for all test cases in SocketSslEchoTest so that all SSL tests terminate themselves when they take too long.
- Fix a bug where the epoll testsuite uses non-daemon threads which can potentially prevent JVM from quitting.
- (Cleanup) Separate boss group and worker group just like we do for NIO/OIO transport testsuite.

Result:

Potentially more stable CI machine.
2014-03-17 09:30:58 +09:00
Norman Maurer
218bb8b034 Replace usage of UnknownHostException with UnresolveableAddressException. Part of [#2262]
Motivation:
We better use UnresolveableAddressException as NIO does the same.

Modifications:
Replace usage of UnknownHostException with UnresolveableAddressException

Result:
epoll transport and nio transport behave the same way
2014-03-16 08:32:24 -07:00
Norman Maurer
4f5f4cdc9d [#2262] Fix NPE triggered by unresolveable InetSocketAddress in epoll transport
Motivation:
At the moment when an unresolvable InetSocketAddress is passed into the epoll transport a NPE is thrown

Modifications:
Add check in place which will throw an UnknownHostException if an InetSocketAddress could not been resolved.

Result:
Proper handling of unresolvable InetSocketAddresses
2014-03-16 06:28:07 -07:00
Norman Maurer
d63c9f2bdb [#2297] Correctly close all registered Channels on EpollEventLoop.closeAll() 2014-03-10 20:37:16 +01:00
Aaron Riekenberg
f62012cba5 [#2280] Correct logic in Native.finishConnect. Fix use of optval parameter in c getOption function. In epoll event loop, check that channel is open before processing event. 2014-03-09 19:38:16 +01:00
Norman Maurer
d3ffa1b02b [#1259] Add optimized queue for SCMP pattern and use it in NIO and native transport
This queue also produces less GC then CLQ when make use of OneTimeTask
2014-02-27 13:28:37 +01:00
Norman Maurer
8c68c5a3ae Fix check to clear READ_OP and EPOLLIN. Part of [#2254] 2014-02-22 20:06:52 +01:00
Norman Maurer
b32316b33c [#2254] Correctly handle Channel.read() and ChannelHandlerContext.read()
This includes also when it is called from channelRead(...) and channelReadComplete(...) methods.
2014-02-22 18:48:47 +01:00
Norman Maurer
47fab2bfe8 Directly use memory addresses for gathering writes to reduce gc pressure. Part of [#2239]
This also does factor out some logic of ChannelOutboundBuffer. Mainly we not need nioBuffers() for many
transports and also not need to copy from heap to direct buffer. So this functionality was moved to
NioSocketChannelOutboundBuffer. Also introduce a EpollChannelOutboundBuffer which makes use of
memory addresses for all the writes to reduce GC pressure
2014-02-21 13:37:33 +01:00
Norman Maurer
78db65d0fb [#2254] Fix regression in handling autoRead and Channel.read()
This regression was introduced by e0b39159657c9eb711047bc32367537c4870d467
2014-02-21 09:19:36 +01:00
Norman Maurer
eb143d6d6e Correctly handle remove from epoll and EPOLLRDHUP. Also fix a bug with removing EPOLLIN and EPOLLOUT 2014-02-19 16:34:57 +01:00
Norman Maurer
6bef9c8489 Use optimized write and read calls if memoryAddress is present. Part of [#2239] 2014-02-17 17:28:37 +01:00
Trustin Lee
5612472ae6 Fix an inspector warning 2014-02-17 05:25:17 -08:00
Trustin Lee
91da8e228b Overall clean-up in EpollSocketChannel
- Extract writev part from doWrite() for simplicity
- Clearer comments
2014-02-17 05:21:10 -08:00
Norman Maurer
8f3c09ba6b [#2238] Fix bug which caused a SIGSEGV when calling remoteAddress() or localAddress() 2014-02-17 12:00:56 +01:00
Norman Maurer
5a369e60b1 Correctly update the ByteBuffers position on write and writev 2014-02-17 07:30:25 +01:00
Norman Maurer
728417abd5 Use correct writerIndex when read for channel 2014-02-16 20:43:36 +01:00
Norman Maurer
9330172f80 Introduce a native transport for linux using epoll ET
This transport use JNI (C) to directly make use of epoll in Edge-Triggered mode for maximal performance on Linux. Beside this it also support using TCP_CORK and produce less GC then the NIO transport using JDK NIO.
It only builds on linux and skip the build if linux is not used. The transport produce a jar which contains all needed .so files for 32bit and 64 bit. The user only need to include the jar as dependency as usually
to make use of it and use the correct classes.

This includes also some cleanup of @trustin
2014-02-15 22:44:56 +01:00