Commit Graph

1265 Commits

Author SHA1 Message Date
Norman Maurer
2fa0b83e73 Cleanup comment / code 2014-06-27 21:36:52 +02:00
Norman Maurer
8bf8252060 [#2615] Correctly update SelectionKey after selector rebuild
Motivation:

When a select rebuild was triggered the reference to the SelectionKey is not updated in AbstractNioChannel. This will cause a CancelledKeyException later.

Modification:

Correctly update SelectionKey reference after rebuild

Result:

Fix exception
2014-06-27 17:21:34 +02:00
onlychoice
5275f37ffb Fix a typo in comment 2014-06-24 11:01:35 +02:00
Norman Maurer
030bcaae81 Improve performance of Recycler
Motivation:

Recycler is used in many places to reduce GC-pressure but is still not as fast as possible because of the internal datastructures used.

Modification:

 - Rewrite Recycler to use a WeakOrderQueue which makes minimal guaranteer about order and visibility for max performance.
 - Recycling of the same object multiple times without acquire it will fail.
 - Introduce a RecyclableMpscLinkedQueueNode which can be used for MpscLinkedQueueNodes that use Recycler

These changes are based on @belliottsmith 's work that was part of #2504.

Result:

Huge increase in performance.

4.0 branch without this commit:

Benchmark                                                (size)   Mode   Samples        Score  Score error    Units
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    00000  thrpt        20 116026994.130  2763381.305    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    00256  thrpt        20 110823170.627  3007221.464    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    01024  thrpt        20 118290272.413  7143962.304    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    04096  thrpt        20 120560396.523  6483323.228    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    16384  thrpt        20 114726607.428  2960013.108    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    65536  thrpt        20 119385917.899  3172913.684    ops/s
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 297.617 sec - in io.netty.microbench.internal.RecyclableArrayListBenchmark

4.0 branch with this commit:

Benchmark                                                (size)   Mode   Samples        Score  Score error    Units
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    00000  thrpt        20 204158855.315  5031432.145    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    00256  thrpt        20 205179685.861  1934137.841    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    01024  thrpt        20 209906801.437  8007811.254    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    04096  thrpt        20 214288320.053  6413126.689    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    16384  thrpt        20 215940902.649  7837706.133    ops/s
i.n.m.i.RecyclableArrayListBenchmark.recycleSameThread    65536  thrpt        20 211141994.206  5017868.542    ops/s
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 297.648 sec - in io.netty.microbench.internal.RecyclableArrayListBenchmark
2014-06-24 10:47:38 +02:00
Norman Maurer
81e5f1ad46 [#2589] LocalServerChannel.doClose() throws NPE when localAddress == null
Motivation:

LocalServerChannel.doClose() calls LocalChannelRegistry.unregister(localAddress); without check if localAddress is null and so produce a NPE when pass null the used ConcurrentHashMapV8

Modification:
Check for localAddress != null before try to remove it from Map. Also added a unit test which showed the stacktrace of the error.

Result:

No more NPE during doClose().
2014-06-20 20:13:23 +02:00
Norman Maurer
3d3ec4753d [#2586] Use correct EventLoop to notify delayed successful registration
Motivation:

At the moment AbstractBoostrap.bind(...) will always use the GlobalEventExecutor to notify the returned ChannelFuture if the registration is not done yet. This should only be done if the registration fails later. If it completes successful we should just notify with the EventLoop of the Channel.

Modification:

Use EventLoop of the Channel if possible to use the correct Thread to notify and so guaranteer the right order of events.

Result:

Use the correct EventLoop for notification
2014-06-20 16:59:13 +02:00
Trustin Lee
085a61a310 Refactor FastThreadLocal to simplify TLV management
Motivation:

When Netty runs in a managed environment such as web application server,
Netty needs to provide an explicit way to remove the thread-local
variables it created to prevent class loader leaks.

FastThreadLocal uses different execution paths for storing a
thread-local variable depending on the type of the current thread.
It increases the complexity of thread-local removal.

Modifications:

- Moved FastThreadLocal and FastThreadLocalThread out of the internal
  package so that a user can use it.
- FastThreadLocal now keeps track of all thread local variables it has
  initialized, and calling FastThreadLocal.removeAll() will remove all
  thread-local variables of the caller thread.
- Added FastThreadLocal.size() for diagnostics and tests
- Introduce InternalThreadLocalMap which is a mixture of hard-wired
  thread local variable fields and extensible indexed variables
- FastThreadLocal now uses InternalThreadLocalMap to implement a
  thread-local variable.
- Added ThreadDeathWatcher.unwatch() so that PooledByteBufAllocator
  tells it to stop watching when its thread-local cache has been freed
  by FastThreadLocal.removeAll().
- Added FastThreadLocalTest to ensure that removeAll() works
- Added microbenchmark for FastThreadLocal and JDK ThreadLocal
- Upgraded to JMH 0.9

Result:

- A user can remove all thread-local variables Netty created, as long as
  he or she did not exit from the current thread. (Note that there's no
  way to remove a thread-local variable from outside of the thread.)
- FastThreadLocal exposes more useful operations such as isSet() because
  we always implement a thread local variable via InternalThreadLocalMap
  instead of falling back to JDK ThreadLocal.
- FastThreadLocalBenchmark shows that this change improves the
  performance of FastThreadLocal even more.
2014-06-19 21:13:55 +09:00
Norman Maurer
7ee18e92f9 Small improvement in SimpleChannelInboundHandlerAdapter javadoc 2014-06-18 14:49:36 +02:00
Norman Maurer
061cb21689 Make use of AtomicLongFieldUpdater.addAndGet(...) for cleaner code
Motivation:

The code in ChannelOutboundBuffer can be simplified by using AtomicLongFieldUpdater.addAndGet(...)

Modification:

Replace our manual looping with AtomicLongFieldUpdater.addAndGet(...)

Result:

Cleaner code
2014-06-17 20:18:18 +02:00
Norman Maurer
375da788e7 [#2577] ChannelOutboundBuffer.addFlush() unnecessary loop through all entries on multiple calls
Motivation:

If ChannelOutboundBuffer.addFlush() is called multiple times and flushed != unflushed it will still loop through all entries that are not flushed yet even if it is not needed anymore as these were marked uncancellable before.

Modifications:

Check if new messages were added since addFlush() was called and only if this was the case loop through all entries and try to mark the uncancellable.

Result:

Less overhead when ChannelOuboundBuffer.addFlush() is called multiple times without new messages been added.
2014-06-17 09:31:53 +02:00
belliottsmith
2a2a21ec59 Introduce FastThreadLocal which uses an EnumMap and a predefined fixed set of possible thread locals
Motivation:
Provide a faster ThreadLocal implementation

Modification:
Add a "FastThreadLocal" which uses an EnumMap and a predefined fixed set of possible thread locals (all of the static instances created by netty) that is around 10-20% faster than standard ThreadLocal in my benchmarks (and can be seen having an effect in the direct PooledByteBufAllocator benchmark that uses the DEFAULT ByteBufAllocator which uses this FastThreadLocal, as opposed to normal instantiations that do not, and in the new RecyclableArrayList benchmark);

Result:
Improved performance
2014-06-13 10:56:18 +02:00
Norman Maurer
8180f7922f Optimize DefaultChannelPipeline in terms of memory usage and initialization time
Motivation:
Each of DefaultChannelPipeline instance creates an head and tail that wraps a handler. These are used to chain together other DefaultChannelHandlerContext that are created once a new ChannelHandler is added. There are a few things here that can be improved in terms of memory usage and initialization time.

Modification:
- Only generate the name for the tail and head one time as it will never change anyway
- Rename DefaultChannelHandlerContext to AbstractChannelHandlerContext and make it abstract
- Create a new DefaultChannelHandlerContext that is used when a ChannelHandler is added to the DefaultChannelPipeline
- Rename TailHandler to TailContext and HeadHandler to HeadContext and let them extend AbstractChannelHandlerContext. This way we can save 2 object creations per DefaultChannelPipeline

 Result:
- Less memory usage because we have 2 less objects per DefaultChannelPipeline
- Faster creation of DefaultChannelPipeline as we not need to generate the name for the head and tail
2014-06-10 12:18:38 +02:00
Norman Maurer
a79b69adf5 ChannelFlushPromiseNotifier should allow long value for pendingDataSize
Motivation:
At the moment ChannelFlushPromiseNotifier.add(....) takes an int value for pendingDataSize, which may be too small as a user may need to use a long. This can for example be useful when a user writes a FileRegion etc. Beside this the notify* method names are kind of missleading as these should not contain *Future* because it is about ChannelPromises.

Modification:
Add a new add(...) method that takes a long for pendingDataSize and @deprecated the old method. Beside this also @deprecated all *Future* methods and add methods that have *Promise* in the method name to better reflect usage.

Result:
ChannelFlushPromiseNotifier can be used with bigger data.
2014-06-03 17:34:53 +02:00
Korotaev Boris
5b2a01a196 Fix broken CompositeMatcher
Motivation:

ChannelMatchers#CompositeMatcher inverts matches result.

Modifications:

Switched return values.

Result:

ChannelMatchers#CompositeMatcher will return correct results.
2014-06-01 13:13:49 +02:00
Frédéric Brégier
c255f38647 Correction on StringBuilder default init size
Motivation:
The default StringBuilder size is too small (data.length + 4) while it will be 2*data.length (byte to Hex) + 5 "-" char (since 5 peaces appended).

Modification:
Changing initial size to the correct one

Result:
Allocation of the correct final size from the beginning for this StringBuilder.
2014-05-30 07:35:49 +02:00
Norman Maurer
2d9e0f53a5 Better implementation of AttributeMap and also add hasAttr(...). See [#2439]
Motivation:
The old DefaultAttributeMap impl did more synchronization then needed and also did not expose a efficient way to check if an attribute exists with a specific key.

Modifications:
* Rewrite DefaultAttributeMap to not use IdentityHashMap and synchronization on the map directly. The new impl uses a combination of AtomicReferenceArray and synchronization per chain (linked-list). Also access the first Attribute per bucket can be done without any synchronization at all and just uses atomic operations. This should fit for most use-cases pretty weel.
* Add hasAttr(...) implementation

Result:
It's now possible to check for the existence of a attribute without create one. Synchronization is per linked-list and the first entry can even be added via atomic operation.
2014-05-15 06:47:42 +02: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
9752f37fa0 [#2454] Correctly return null when DefaultChannelPipeline.firstContext() is called on empty pipeline
Motivation:
DefaultChannelPipeline.firstContext() should return null when the ipeline is empty. This is not the case atm.

Modification:
Fix incorrect check in DefaultChannelPipeline.firstContext() and add unit tests.

Result:
Correctly return null when DefaultChannelPipeline.firstContext() is called on empty pipeline.
2014-05-04 21:13:17 +02:00
Norman Maurer
e8b5f19b82 Not cause busy loop when interrupt Thread of NioEventLoop
Motivation:
Because Thread.currentThread().interrupt() will unblock Selector.select() we need to take special care when check if we need to rebuild the Selector. If the unblock was caused by the interrupt() we will clear it and move on as this is most likely a bug in a custom ChannelHandler or a library the user makes use of.

Modification:
Clear the interrupt state of the Thread if the Selector was unblock because of an interrupt and the returned keys was 0.

Result:
No more busy loop caused by Thread.currentThread().interrupt()
2014-04-28 08:18:57 +02:00
Norman Maurer
d8d822fddd Eliminate unnecessary extra synchronization in DefaultChannelPipeline
Motivation:
At the moment whenever we add/remove a ChannelHandler with an EventExecutorGroup we have two synchronization points in the execution path. One to find the childInvoker and one for add/remove itself. We can eliminate the former by call findIInvoker in the synchronization block, as we need to synchronize anyway.

Modification:
Remove the usage of AtomicFieldUpdater and the extra synchronization in findInvoker by moving the call of the method in the synchronized(this) block.

Result:
Less synchronization points and volatile reads/writes
2014-04-25 14:15:23 +02:00
Trustin Lee
0fceef8ab6 Undeprecate deregister() and chanelUnregistered()
Motivation:

As discussed in #2250, it will become much less complicated to implement
deregistration and reregistration of a channel once #2250 is resolved.
Therefore, there's no need to deprecate deregister() and
channelUnregistered().

Modification:

- Undeprecate deregister() and channelUnregistered()
- Remove SuppressWarnings annotations where applicable

Result:

We (including @jakobbuchgraber) are now ready to play with #2250 at
master
2014-04-25 16:40:42 +09:00
Trustin Lee
d765f6b870 Synchronized between 4.1 and master (part 3)
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:

Fix found differences

Result:

4.1 and master got closer.
2014-04-25 16:17:59 +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
8c3eaf3b56 Synchronized between 4.1 and master again
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-24 21:28:24 +02:00
Norman Maurer
a2f1f21612 Synchronized between 4.1 and master
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:

Small adjustments to match up branches

Result:

4.1 and master got closer.
2014-04-24 21:04:20 +02:00
Trustin Lee
db3709e652 Synchronized between 4.1 and master
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:

Fix found differences

Result:

4.1 and master got closer.
2014-04-25 00:38:02 +09:00
Norman Maurer
7ae40ace32 [#2400] Not close LocalChannel during deregister() to allow register to other EventLoop
Motivation:
At the moment it is not possible to deregister a LocalChannel from its EventLoop and register it to another one as the LocalChannel is closed during the deregister.

Modification:
Not close the LocalChannel during dergister

Result:
It is now possible to deregister a LocalChannel and register it to another EventLoop
2014-04-21 10:07:42 +02:00
Norman Maurer
9e02a9bbee Move validatePromise(...) to ChannelHandlerInvokerUtil. Related to [#2398]
Motivation:
Once a user implement a custom ChannelHandlerInvoker it is needed to validate the ChannelPromise. We should expose a utility method for this.

Modifications:
Move validatePromise(...) from DefaultChannelHandlerInvoker to ChannelHandlerInvokerUtil and make it public.

Result:
User is able to reuse code
2014-04-17 16:01:26 +02:00
Norman Maurer
9b670d819f [#2144] Fix NPE in Local transport caused by a race
Motivation:
At the moment it is possible to see a NPE when the LocalSocketChannels doRegister() method is called and the LocalSocketChannels doClose() method is called before the registration was completed.

Modifications:
Make sure we delay the actual close until the registration task was executed.

Result:
No more NPE
2014-04-17 15:06:52 +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
17334a0a42 [#2390] Minimize memory usage of NioDatagramChannel
Motivation:
At the moment we create a HashMap that holds the MembershipKeys for multicast with every NioDatagramChannel even when most people not need it at al

Modifications:
Lazy create the HashMap when needed.

Result:
Less memory usage and less object creation
2014-04-15 06:56:17 +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
1087160fa7 [#2363] SelectedSelectionKeySet may hold strong reference to SelectionKey after Channel is closed
Motivation:
Because we not null out the array entry in the SelectionKey[] which is produced by SelectedSelectionKeySet.flip() we may end up with a few SelectionKeyreferences still hanging around here even after the Channel was closed. As these entries may be present at the end of the SelectionKey[] which is never updated for a long time as not enough SelectionKeys are ready.

Modifications:
Once we access the SelectionKey out of the SelectionKey[] we directly null it out.

Result:
Reference can be GC'ed right away once the Channel was closed.
2014-04-05 19:31:12 +02:00
Norman Maurer
fdb1db90c4 [#2362] AbstractChannel.AbstractUnsafe.write(...) is slow
Motivation:
At the moment we do a Channel.isActive() check in every AbstractChannel.AbstractUnsafe.write(...) call which gives quite some overhead as shown in the profiler when you write fast enough. We can eliminate the check and do something more smart here.

Modifications:
Remove the isActive() check and just check if the ChannelOutboundBuffer was set to null before, which means the Channel was closed. The rest will be handled in flush0() anyway.

Result:
Less overhead when doing many write calls
2014-04-04 09:54:52 +02:00
Norman Maurer
772a9d2610 [#2349] Correctly handle cancelled ChannelPromise in DefaultChannelHandlerContext
Motivation:
At the moment an IllegalArgumentException will be thrown if a ChannelPromise is cancelled while propagate through the ChannelPipeline. This is not correct, we should just stop to propagate it as it is valid to cancel at any time.

Modifications:
Stop propagate the operation through the ChannelPipeline once a ChannelPromise is cancelled.

Result:
No more IllegalArgumentException when cancel a ChannelPromise while moving through the ChannelPipeline.
2014-03-31 07:53:22 +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
Trustin Lee
6d4c4d9e4b Correct the return type of MultithreadEventLoopGroup.newChild()
Motivation:

MultithreadEventLoopGroup.newChild() does not override MultithreadEventExecutorGroup.newChild() which returns EventExecutor.  MultithreadEventLoopGroup.newChild() should never return an EventExecutor, so this is incorrect.

Modifications:

Override MultithreadEventLoopGroup.newChild() so that it returns EventLoop

Result:

Correct API
2014-03-24 17:05:36 +09:00
Trustin Lee
aeb6ba5684 Update the Javadoc of ChannelHandler and ChannelHandlerContext
Motivation:

It's out of date and it has broken links, etc.

Modifications:

Backport the fixes from master (132af3a485)

Result:

Better Javadoc
2014-03-24 16:07:53 +09:00
Trustin Lee
7dc63ccd95 Add EventExecutor.children() in favor of iterator()
Motivation:

EventExecutor.iterator() is fixed to return Iterator<EventExecutor> and there's no way to change that as long as we don't extend Iterable.  However, a user should have a way to cast the returned set of executors painlessly.  Currently, it is only possible with an explicit cast like (Iterator<NioEventLoop>).

Modifications:

Instead, I added a new method called 'children()' which returns an immutable collection of child executors whose method signature looks like the following:

    <E extends EventExecutor> Set<E> children();

Result:

A user can now do this:

    Set<NioEventLoop> loops = group.children();
    for (NioEventLoop l: loops) { ... }

Unfortunately, this is not possible:

    for (NioEventLoop l: group.children()) { ... }

However, it's still a gain that a user doesn't need to down-cast explicitly and to add the '@SuppressWarnings` annotation.
2014-03-24 12:32:55 +09:00
Trustin Lee
1e3b7d8273 Replace LocalEventLoopGroup with DefaultEventLoopGroup
Motivation:

LocalEventLoopGroup and LocalEventLoop are not really special for LocalChannels.  It can be used for other channel implementations as long as they don't require special handling.

Modifications:

- Add DefaultEventLoopGroup and DefaultEventLoop
- Deprecate LocalEventLoopGroup and make it extend DefaultEventLoopGroup
- Add DefaultEventLoop and remove LocalEventLoop
- Fix inspector warnings

Result:

- Better class names.
2014-03-24 11:39:55 +09:00
Trustin Lee
007694b963 Implement EventExecutor.parent() in AbstractEventExecutor
Motivation:

EventExecutor.parent() and EventLoop.parent() almost always return a constant parent executor.  There's not much reason to let it implemented in subclasses.

Modifications:

- Implement AbstractEventExecutor.parent() with an additional contructor
- Add AbstractEventLoop so that subclasses extend AbstractEventLoop, which implements parent() appropriately
- Remove redundant parent() implementations in the subclasses
- Fix inspector warnings

Result:

Less duplication.
2014-03-24 11:05:51 +09:00
CoNDoRip
ac5e838398 Allow specifying SelectorProvider when constructing an NIO channel #2311
Motivation:

At the moment we use the system-wide default selector provider for this invocation of the Java virtual machine when constructing a new NIO channel, which makes using an alternative SelectorProvider practically useless.
This change allows user specify his/her preferred SelectorProvider.

Modifications:

Add SelectorProvider as a param for current `private static *Channel newSocket` method of NioSocketChannel, NioServerSocketChannel and NioDatagramChannel.
Change default constructors of NioSocketChannel, NioServerSocketChannel and NioDatagramChannel to use DEFAULT_SELECTOR_PROVIDER when calling newSocket(SelectorProvider).
Add new constructors for NioSocketChannel, NioServerSocketChannel and NioDatagramChannel which allow user specify his/her preferred SelectorProvider.

Result:

Now users can specify his/her preferred SelectorProvider when constructing an NIO channel.
2014-03-23 15:57:46 +01:00
Trustin Lee
b5c97bcc82 Use the length of MAC address as the last property to compare to get the best MAC address
Motivation:

Some operating systems like Windows 7 uses a valid globally unique EUI-64 MAC address for a virtual device (e.g. 00:00:00:00:00:00:00:E0), and because it's usually longer than the legit MAC-48 address, we should not use the length of MAC address when two MAC addresses are of the same quality.  Instead, we should compare the INET address of the NICs before comparing the length of the MAC addresses.

Modification:

Compare the length of MAC addresses as a last resort.

Result:

Correct MAC address detection in Windows with IPv6 enabled.
2014-03-21 12:58:58 +09:00
Trustin Lee
3613d2d59e Prefer the NIC with global IP address when getting the default machine ID
Motivation:

When there are two MAC addresses which are good enough, we can choose the one with better IP address rather than just choosing the first appeared one.

Modification:

Replace isBetterAddress() with compareAddresses() to make it return if both addresses are in the same preference level.
Add compareAddresses() which compare InetAddresses and use it when compareAddress(byte[], byte[]) returns 0 (same preference)

Result:

More correct primary MAC address detection
2014-03-21 12:32:26 +09:00
Trustin Lee
ff179c3430 Reduce the time taken by NetUtil and DefaultChannelId class initialization
Motivation:

As reported in #2331, some query operations in NetworkInterface takes much longer time than we expected.  For example, specifying -Djava.net.preferIPv4Stack=true option in Window increases the execution time by more than 4 times.  Some Windows systems have more than 20 network interfaces, and this problem gets bigger as the number of unused (virtual) NICs increases.

Modification:

Use NetworkInterface.getInetAddresses() wherever possible.
Before iterating over all NICs reported by NetworkInterface, filter the NICs without proper InetAddresses.  This reduces the number of candidates quite a lot.
NetUtil does not query hardware address of NIC in the first place but uses InetAddress.isLoopbackAddress().
Do not call unnecessary query operations on NetworkInterface.  Just get hardware address and compare.

Result:

Significantly reduced class initialization time, which should fix #2331.
2014-03-21 11:39:41 +09:00
Norman Maurer
afcc7fb7cc [#2326] Add constructor to NioServerSocketChannel which accepts a ServerSocketChannel
Motivation:
Allow the user to create a NioServerSocketChannel from an existing ServerSocketChannel.

Modifications:
Add an extra constructor

Result:
Now the user is be able to create a NioServerSocketChannel from an existing ServerSocketChannel, like he can do with all the other Nio*Channel implemntations.
2014-03-16 07:03:14 -07:00
Norman Maurer
9a11c43463 [#2323] Make it clear a Channel must be closed to release all resources
Motivation:
Ensure the user know the Channel must be closed to release resources like filehandles.

Modifications:
Add some extra javadoc.

Result:
More clear documentation
2014-03-16 07:02:57 -07:00
Norman Maurer
69d3cf5539 [#2308] Use SelectorProvider.open*() to open NIO channels and so remove condition when create new NIO channels.
Motivation:
At the moment we use SocketChannel.open(), ServerSocketChannel.open() and DatagramSocketChannel.open(...) within the constructor of our
NIO channels. This introduces a bottleneck if you create a lot of connections as these calls delegate to SelectorProvider.provider() which
uses synchronized internal. This change removed the bottleneck.

Modifications:
Obtain a static instance of the SelectorProvider and use SelectorProvider.openSocketChannel(), SelectorProvider.openServerSocketChannel() and
SelectorProvider.openDatagramChannel(). This eliminates the bottleneck as SelectorProvider.provider() is not called on every channel creation.

Result:
Less conditions when create new channels.
2014-03-13 07:00:33 +01:00
Norman Maurer
adcc2d4b4b Remove condition in ChannelHandlerAdapter.isSharable() by caching the result of the annotation lookup.
Motivation:
Remove the synchronization bottleneck and so speed up things

Modifications:
Introduce a ThreadLocal cache that holds mappings between classes of ChannelHandlerAdapater implementations and the result of checking if the @Sharable annotation is present.
This way we only will need to do the real check one time and server the other calls via the cache. A ThreadLocal and WeakHashMap combo is used to implement the cache
as this way we can minimize the conditions while still be sure we not leak class instances in containers.

Result:
Less conditions during adding ChannelHandlerAdapter to the ChannelPipeline
2014-03-12 12:31:52 +01:00
Norman Maurer
95ff172c82 Corrected inconsistencies in the Javadoc.
Port of 80030493b9f7824c02dc88260c2579afc0aed8bc
2014-03-04 06:34:50 +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
1c9c797e82 Move marking ChannelPromise for writes uncancellable to addFlush for keep things simple 2014-02-17 16:16:08 +01:00
Trustin Lee
a0e74ff984 Use thread local direct buffer for I/O when the current allocator is unpooled
- Allocating and deallocating a direct buffer for I/O is an expensive
  operation, so we have to at least have a pool of direct buffers if the
  current allocator is not pooled
2014-02-15 11:24:01 -08:00
Trustin Lee
fbd4385506 Determine the default allocator from system property
- Add ByteBufAllocator.DEFAULT
- The default allocator is now 'pooled'
2014-02-14 13:04:12 -08:00
Trustin Lee
0e4c80b953 Fix IllegalStateException caused by ChannelHandlerAppender 2014-02-13 19:44:40 -08:00
Trustin Lee
c671103289 Deprecate CombinedChannelDuplexHandler in favor of ChannelHandlerAppender
- Fixes #2233
- Add ChannelHandlerAppender
2014-02-13 19:20:56 -08:00
Trustin Lee
7e1db4feb7 Deprecate CombinedChannelDuplexHandler in favor of ChannelHandlerAppender
- Fixes #2233
2014-02-13 19:20:25 -08:00
Trustin Lee
8837afddf8 Enable a user specify an arbitrary information with ReferenceCounted.touch()
- Related: #2163
- Add ResourceLeakHint to allow a user to provide a meaningful information about the leak when touching it
- DefaultChannelHandlerContext now implements ResourceLeakHint to tell where the message is going.
- Cleaner resource leak report by excluding noisy stack trace elements
2014-02-13 18:16:25 -08:00
Trustin Lee
0235244e55 Touch a ReferenceCounted while it traverses across a pipeline 2014-02-13 18:11:54 -08:00
Trustin Lee
45e70d9935 Add ReferenceCounted.touch() / Add missing retain() overrides
- Fixes #2163
- Inspector warnings
2014-02-13 18:10:11 -08:00
Trustin Lee
7e60877bc5 Merge the attribute map of ChannelHandlerContext into Channel
- Fixes #2136
- Also fixes some generics warnings
2014-02-13 18:02:44 -08:00
Trustin Lee
1d577a8d95 Get the PID properly on Android
- Related: #2109
2014-02-13 17:37:22 -08:00
Trustin Lee
d97f72d2c9 Fix a problem where DefaultChannelId prevents Netty 5 from running on Android
- Fixes #2109
- Use reflection to find the current PID
2014-02-13 17:35:44 -08:00
Trustin Lee
2b84314fdd Add Recycler.Handle.recycle() so that it's possible to recycle an object without an explicit reference to Recycler 2014-02-13 17:24:37 -08:00
Trustin Lee
df346a023b Change the return type of EmbeddedChannel.read*() from Object to an ad-hoc type parameter
.. so that there's no need to explicitly down-cast.

Fixes #2067
2014-02-13 17:19:26 -08:00
Vladimir Krivosheev
eb308cfff6 ability to use Executor instead of ThreadFactory 2014-02-13 16:14:41 -08:00
Trustin Lee
780516471f Bring back ChannelGroup.find(id) 2014-02-13 15:53:45 -08:00
Trustin Lee
40003ed250 Resurrect Channel.id() with global uniqueness
- Fixes #1810
- Add a new interface ChannelId and its default implementation which generates globally unique channel ID.
- Replace AbstractChannel.hashCode with ChannelId.hashCode() and ChannelId.shortValue()
- Add variants of ByteBuf.hexDump() which accept byte[] instead of ByteBuf.
2014-02-13 15:53:07 -08:00
Trustin Lee
812481602a Don't create an EmbeddedSocketAddress every time 2014-02-13 15:45:47 -08:00
Trustin Lee
499033d44f Add a shortcut method for collision-free naming 2014-02-13 15:17:09 -08:00
Trustin Lee
b533a1361b Replace UniqueName with Constant and ConstantPool
- Proposed fix for #1824

UniqueName and its subtypes do not allow getting the previously registered instance.  For example, let's assume that a user is running his/her application in an OSGi container with Netty bundles and his server bundle.  Whenever the server bundle is reloaded, the server will try to create a new AttributeKey instance with the same name.  However, Netty bundles were not reloaded at all, so AttributeKey will complain that the name is taken already (by the previously loaded bundle.)

To fix this problem:

- Replaced UniqueName with Constant, AbstractConstant, and ConstantPool.  Better name and better design.

- Sctp/Udt/RxtxChannelOption is not a ChannelOption anymore.  They are just constant providers and ChannelOption is final now.  It's because caching anything that's from outside of netty-transport will lead to ClassCastException on reload, because ChannelOption's constant pool will keep all option objects for reuse.

- Signal implements Constant because we can't ensure its uniqueness anymore by relying on the exception raised by UniqueName's constructor.
2014-02-13 15:14:34 -08:00
Trustin Lee
a65f097d53 Allow empty handler list when creating a new EmbeddedChannel
.. so that it can be used for dynamically initialized pipelines

- Fixes #1899
2014-02-13 14:46:33 -08:00
Norman Maurer
517da2b46a Fix checkstyle 2014-02-13 14:36:14 -08:00
Bill Gallagher
7e5aa4a911 use enum for state in LocalChannel 2014-02-13 14:35:58 -08:00
Bill Gallagher
a19fe06928 use enum for state in EmbeddedChannel 2014-02-13 14:34:51 -08:00
Trustin Lee
449ce0dd7a Remove the irrelevant AIO channel options 2014-02-13 13:59:12 -08:00
Norman Maurer
69a36b8bea Prettify exception message 2014-02-13 06:46:51 +01:00
Norman Maurer
62ebe88981 Allow to set IoRatio to 100% 2014-02-12 15:22:39 +01:00
Norman Maurer
80e6f9adf4 Correctly respect isAutoRead() and make it consistent across OIO/NIO 2014-02-11 20:46:46 +01:00
Norman Maurer
7041a9238e Allow to cancel non-flushed writes 2014-02-11 19:42:49 +01:00
Trustin Lee
d52dc3b740 Do not warn if failed to mark a void promise as success
- it's always supposed to fail.
2014-02-10 15:03:46 -08:00
Trustin Lee
96b0a949e1 Make most outbound operations cancellable / More robust promise update
- Inspired by #2214 by @normanmaurer
- Call setUncancellable() before performing an outbound operation
- Add safeSetSuccess/Failure() and use them wherever
2014-02-10 14:57:18 -08:00
Trustin Lee
041d37e0c8 Make most outbound operations are cancellable
- Inspired by #2214
- It actually reduces the chance of trying to marking a cancelled promise as success again, which raises an IllegalStateException.
2014-02-10 14:06:54 -08:00
Norman Maurer
87602fde25 [#2215] DefaultChannelHandlerContext tasks needs to be volatile to ensure every thread only see full initialized instances 2014-02-08 10:33:44 +01:00
Norman Maurer
9bee78f91c Provide an optimized AtomicIntegerFieldUpdater, AtomicLongFieldUpdater and AtomicReferenceFieldUpdater 2014-02-06 20:08:45 +01:00
Norman Maurer
64c3f58279 Not wakeup the EventLoop for writes as they will not cause a flush anyway 2014-02-01 13:45:27 +01:00
Norman Maurer
f94b563bcd Better exception message to tell the user why it is not supported 2014-01-30 07:02:22 +01:00
Norman Maurer
80ed147652 [#2164] Only reregister SelectionKeys that are still valid 2014-01-29 07:18:29 +01:00
Trustin Lee
9b0e5b9148 Fix API documentation on the usage of AttributeKey 2014-01-28 13:59:11 +09:00
William Kemper
39b8cc348a fix grouping for isActive - socket.isBound is almost always true and should not override 'isOpen' 2014-01-17 07:14:00 +01:00
Trustin Lee
237ba27499 Better exception message 2014-01-13 23:32:49 +09:00
Norman Maurer
13d65d7ccf [#2104] Make sure we only act on the SelectionKey if it is valid 2014-01-09 18:27:56 +01:00
Trustin Lee
751943ed00 Fix a potential NPE due to the race between a connection attempt and its cancellation
- should fix #2086
2014-01-09 19:24:44 +09:00
Norman Maurer
0bbc3facec [#2086] Fix race which could produce NPE in AbstractNioUnsafe.finishConnect 2014-01-09 08:22:34 +01:00
milenkovicm
393f7b2306 ChannelOutboundBuffer returns total pending write size
total pending write size may be used to optimize write batching
2014-01-07 06:52:07 +01:00
Veebs
dd8f4bc0c4 Fix typo 2014-01-03 11:15:14 +01:00