Commit Graph

3883 Commits

Author SHA1 Message Date
Trustin Lee
5f9090a7f0 Fix invalid memory access in AIO writes
To perform writes in AioSocketChannel, we get a ByteBuffer view of the
outbound buffer and specify it as a parameter when we call
AsynchronousSocketChannel.write().

In most cases, the write() operation is finished immediately.  However,
sometimes, it is scheduled for later execution.  In such a case, there's
a chance for a user's handler to append more data to the outbound
buffer.

When more data is appended to the outbound buffer, the outbound buffer
can expand its capacity by itself.  Changing the capacity of a buffer is
basically made of the following steps:

1. Allocate a larger new internal memory region.
2. Copy the current content of the buffer to the new memory region.
3. Rewire the buffer so that it refers to the new region.
4. Deallocate the old memory region.

Because the old memory region is deallocated at the step 4, the write
operation scheduled later will access the deallocated region, leading
all sort of data corruption or even segfaults.

To prevent this situation, I added suspendIntermediaryDeallocations()
and resumeIntermediaryDeallocations() to UnsafeByteBuf.

AioSocketChannel.doFlushByteBuf() now calls suspendIntermediaryDealloc()
to defer the deallocation of the old memory regions until the completion
handler is notified.
2012-12-02 21:50:33 +09:00
Trustin Lee
72e0acbe84 Use correct timeout in AioSocketChannel.beginRead() 2012-12-02 20:38:59 +09:00
Trustin Lee
bfe2a96505 Fix AssertionError from AsyncSocketChannel.beginRead()
An AssertionError is triggered by a ByteBuf when beginRead() attempts to
access the buffer which has been freed already.  This commit ensures the
buffer is not freed before performing an I/O operation.

To determine if the buffer has been freed, UnsafeByteBuf.isFreed() has
been added.
2012-12-02 20:17:53 +09:00
Trustin Lee
95e8ec1db9 Handle the case where JDK notifies aync I/O handler immediately
After some debugging, I found that JDK AIO implementation often performs
I/O immediately from the caller thread if the caller thread is the I/O
thread, and notifies the completion handler also immediately.  This
commit handles such a case correctly during reads and writes.

Additionally, this commit also changes SingleThreadEventExecutor to let
it handle unexpected exceptions such as AssertionError in a robus
manner.
2012-12-02 20:03:35 +09:00
Trustin Lee
00c4b944e4 Fix more inspector warnings introduced by recent mergences 2012-12-01 00:10:42 +09:00
Trustin Lee
6208c62888 Fix inspector warnings introduced by recent mergences 2012-11-30 23:01:57 +09:00
Trustin Lee
818a7b42a3 Fix all Xlint:unchecked warnings 2012-11-30 22:49:51 +09:00
Matthias Wessendorf
b33df8399e fixing type on event/send argument 2012-11-27 19:29:29 +01:00
Trustin Lee
c661c344ed Add proper toString() implementation for internal ChannelFactory impls 2012-11-26 17:15:14 +09:00
Trustin Lee
918666481e Ensure lazily instantiated outbound buffers are instantiated from the event loop 2012-11-26 17:14:21 +09:00
Trustin Lee
74749ec15d Implement Bootstrap.toString() and use it in the testsuite
By implementing Bootstrap.toString() and printing it for each test case helps us figure out which transport is causing a trouble.
2012-11-26 16:14:24 +09:00
Trustin Lee
089d022e03 Remove redundant exception message 2012-11-26 15:34:09 +09:00
Trustin Lee
9018f8e5ca Enable assertions only for Netty classes 2012-11-26 15:01:13 +09:00
Trustin Lee
d7f0351a85 Add JVM options for faster test runs 2012-11-26 14:53:15 +09:00
Trustin Lee
40373526ce Remove unexpected bad text
Doh!
2012-11-26 14:41:12 +09:00
Trustin Lee
5b68f00382 Make CompatibleMarshallingDecoder discard the inbound buffer once TooLongFrameException is raised
(See #768)

Once too long object is received, CompatibleMarshallingDecoder has to
discard all input from now on, just like MarshallingDecoder does.
Otherwise, the decoder will raise more exceptions because the decoder
has no idea anymore where the object starts.

Before this fix, SerialThreadLocalCompatibleMarshallingDecoderTest
logged many additional exceptions raised by the decoder after test is
finished.
2012-11-26 14:40:18 +09:00
Norman Maurer
d7d8503f5c Add a line-based frame decoder with good performance.
Using DelimiterBasedFrameDecoder with Delimiters.lineDelimiter() has
quadratic performance in the size of the input buffer.  Needless to
say, the performance degrades pretty quickly as the size of the buffer
increases.  Larger MTUs or loopback connections can make it so bad that
it appears that the code is "busy waiting", when in fact it's spending
almost 100% of the CPU time in DelimiterBasedFrameDecoder.indexOf().

Add a new LineBasedFrameDecoder that decodes line-delimited frames
in O(n) instead of DelimiterBasedFrameDecoder's O(n^2) implementation.
In OpenTSDB's telnet-style protocol decoder this resulted in throughput
increases of an order of magnitude.

Change DelimiterBasedFrameDecoder to automatically detect when the
frames are delimited by line endings, and automatically switch to
using LineBasedFrameDecoder under the hood.  This means that all Netty
applications out there that using the combo DelimiterBasedFrameDecoder
with Delimiters.lineDelimiter() will automatically benefit from the
better performance of LineBasedFrameDecoder, without requiring a code
change.
2012-11-25 13:36:55 +01:00
Daniel Bevenius
b1cd953d02 Adding WebSocket Example using WebSocketServerProtocolHandler. 2012-11-25 11:44:19 +01:00
Trustin Lee
dbbc6ad73f Reduce the chance of RejectedExecutionException
When a Netty application shuts down, a user often sees a REE
(RejectedExecutionException).

A REE is raised due to various reasons we don't have control over, such
as:

- A client connects to a server while the server is shutting down.

- An event is triggered for a closed Channel while its event loop is
  also shutting down.  Some of them are:
  - channelDeregistered (triggered after a channel is closed)
  - freeIn/OutboundBuffer (triggered after channelDeregistered)
  - userEventTriggered (triggered anytime)

To address this issue, a new method called confirmShutdown() has been
added to SingleThreadEventExecutor.  After a user calls shutdown(),
confirmShutdown() runs any remaining tasks in the task queue and ensures
no events are triggered for last 2 seconds.  If any task are added to
the task queue before 2 seconds passes, confirmShutdown() prevents the
event loop from terminating by returning false.

Now that SingleThreadEventExecutor needs to accept tasks even after
shutdown(), its execute() method only rejects the task after the event
loop is terminated (i.e. isTerminated() returns true.)  Except that,
there's no change in semantics.

SingleThreadEventExecutor also checks if its subclass called
confirmShutdown() in its run() implementation, so that Netty developers
can make sure they shut down their event loop impementation correctly.

It also fixes a bug in AioSocketChannel, revealed by delayed shutdown,
where an inboundBufferUpdated() event is triggered on a closed Channel
with deallocated buffers.

Caveats:

Because SingleThreadEventExecutor.takeTask() does not have a notion of
timeout, confirmShutdown() adds a dummy task (WAKEUP_TASK) to wake up
takeTask() immediately and instead sleeps hard-coded 100ms.  I'll
address this issue later by modifying takeTask() times out dynamically.

Miscellaneous changes:

SingleThreadEventExecutor.wakeup() now has the default implementation.
Instead of interrupting the current thread, it simply adds a dummy task
(WAKEUP_TASK) to the task queue, which is more elegant and efficient.
NioEventLoop is the only implementation that overrides it. All other
implementations' wakeup()s were removed thanks to this change.
2012-11-22 20:36:13 +01:00
Trustin Lee
81e2db10fa ByteBufAllocator API w/ ByteBuf perf improvements
This commit introduces a new API for ByteBuf allocation which fixes
issue #643 along with refactoring of ByteBuf for simplicity and better
performance. (see #62)

A user can configure the ByteBufAllocator of a Channel via
ChannelOption.ALLOCATOR or ChannelConfig.get/setAllocator().  The
default allocator is currently UnpooledByteBufAllocator.HEAP_BY_DEFAULT.

To allocate a buffer, do not use Unpooled anymore. do the following:

  ctx.alloc().buffer(...); // allocator chooses the buffer type.
  ctx.alloc().heapBuffer(...);
  ctx.alloc().directBuffer(...);

To deallocate a buffer, use the unsafe free() operation:

  ((UnsafeByteBuf) buf).free();

The following is the list of the relevant changes:

- Add ChannelInboundHandler.freeInboundBuffer() and
  ChannelOutboundHandler.freeOutboundBuffer() to let a user free the
  buffer he or she allocated. ChannelHandler adapter classes implement
  is already, so most users won't need to call free() by themselves.
  freeIn/OutboundBuffer() methods are invoked when a Channel is closed
  and deregistered.

- All ByteBuf by contract must implement UnsafeByteBuf. To access an
  unsafe operation: ((UnsafeByteBuf) buf).internalNioBuffer()

- Replace WrappedByteBuf and ByteBuf.Unsafe with UnsafeByteBuf to
  simplify overall class hierarchy and to avoid unnecesary instantiation
  of Unsafe instances on an unsafe operation.

- Remove buffer reference counting which is confusing

- Instantiate SwappedByteBuf lazily to avoid instantiation cost

- Rename ChannelFutureFactory to ChannelPropertyAccess and move common
  methods between Channel and ChannelHandlerContext there. Also made it
  package-private to hide it from a user.

- Remove unused unsafe operations such as newBuffer()

- Add DetectionUtil.canFreeDirectBuffer() so that an allocator decides
  which buffer type to use safely
2012-11-22 15:10:59 +09:00
Norman Maurer
2adebc4c54 [#755] SPDY: fix header block values truncation in decompression 2012-11-20 20:09:59 +01:00
Mike Heath
ff14feeb54 The handshake handler should not handle the exception and simply close the socket. The exception should be propagated to the WebSocketServerProtocolHandler to send the appropriate response and then close the socket. 2012-11-20 10:00:28 +01:00
Mike Heath
40e53b9b68 Fixed exception handling to call the exceptionCaught method in the current handler. By default the handler will call ctx.fireExceptionCaught which is what was happening before. 2012-11-20 10:00:27 +01:00
dantran
4107b08f29 Only generate OSGi manifest only at all-in-on sub module to reduce the complexity to the build 2012-11-19 06:27:18 +01:00
dantran
434c19da33 Clean maven-bundle-plugin warnings 2012-11-18 21:12:34 +01:00
Norman Maurer
524fac5184 [#748] Upgrade to yammer metrics 2.1.4 2012-11-18 12:23:44 +01:00
coltnz
fea7475080 [#749] Report non @Shareable handler name that has been re-added. 2012-11-18 11:40:01 +01:00
alexey
5d2b41c094 basic support for socks5 codec 2012-11-17 20:03:16 +01:00
Jeff Pinner
ef26ffe9d8 SPDY: remove deprecated methods 2012-11-17 19:30:42 +01:00
Jeff Pinner
97d07253e2 SPDY: fixed session status (internal error misdocumented) 2012-11-17 19:30:42 +01:00
Evans Yang
a0da613e86 [#743] Make the "tail" point to the last channel handler context. And add several cases for DefaultChannelPipeline. 2012-11-16 07:33:32 +01:00
Evans Yang
37d04c26a8 [#739] Potential NullPointException without checking the initialCtx's status 2012-11-16 07:08:45 +01:00
Norman Maurer
d28eca7138 [#740] Fix WebSocketClientHandshaker00.finishHandshake() validations 2012-11-15 13:06:48 +01:00
Norman Maurer
46d713970b [#737] WebSocketClientHandshaker00 should set Content-Length header do workaround problem with proxy 2012-11-14 10:08:44 +01:00
Trustin Lee
b5d83a2407 Upgrade netty-build to 12 2012-11-14 16:32:44 +09:00
Shawn Silverman
0bd73b8d80 [#732] [#672] Allow replacing an inbound or outbound buffer of a handler 2012-11-13 21:17:42 +01:00
Norman Maurer
3b729848dc [#735] Improve the notification of the handshake future 2012-11-13 20:05:54 +01:00
Norman Maurer
efaa5c2ff5 [#735] Make sure the handshake ChannelFuture is notified after the right encoder is present in the ChannelPipeline 2012-11-13 09:26:32 +01:00
Norman Maurer
d177fd5a17 [#735] Make sure the handshake ChannelFuture is notified after the right encoder is present in the ChannelPipeline 2012-11-13 09:25:19 +01:00
Norman Maurer
2d5028bfd6 [#729] Correctly handle urls with empty abs_path in it when issue the websocket handshake 2012-11-12 15:29:02 +01:00
dantran
105f952f5d Clean up maven-bungle-plugin warnings 2012-11-12 11:42:42 +01:00
dantran
e236f5b77d [#154] [#727] Use maven-plugin-plugin to generate OSGi manifest 2012-11-12 09:15:36 +01:00
Trustin Lee
45de76f58d More helpful IllegalArgumentException message 2012-11-12 16:02:30 +09:00
Trustin Lee
b3be15204d Fix 'channelFactory already set' error 2012-11-12 15:59:25 +09:00
Trustin Lee
9ac522382a Fix visibility warnings from the inspector. 2012-11-12 14:03:43 +09:00
Trustin Lee
ec7849ac09 Allow '_' in parameter names although discouraged 2012-11-12 13:39:24 +09:00
Trustin Lee
a05064d3eb Fix more inspection warnings + compilation errors 2012-11-12 13:25:00 +09:00
Trustin Lee
36c8eb02e8 Fix parameter namings + some more 2012-11-12 12:59:37 +09:00
Trustin Lee
6f2840193a Fix inspection warnings related with JUnit usage 2012-11-12 12:45:06 +09:00
Trustin Lee
aedf8790c3 Fix various Javadoc issues / Do not use argN parameter names 2012-11-12 12:26:19 +09:00