- DefaultChannelPipeline detects such cases and creates an object called
'bridge' that works as a man-in-the-middle to deal with a race
condition
- Slight performance drop is observed but still faster than v3.
Couldn't find much from a profiler yet.
- Previously, head was a volatile field which is null at the beginning.
While iterating over the pipeline, if the loop hits null, it called
Channel.Unsafe explicitly.
- Instead, I created an outbound handler that redirects all requests
to the unsafe and made it a final field of the pipeline.
- As a result, DefaultChannelPipeline code became much simpler.
- SocketTestCombination generates all possible test combinations of
socket transports.
- SocketEchoTest iterates over the combinations and runs all tests
using reflection.
- The handler you specify with initializer() is actually simply added
to the pipeline and that's all. It's ChannelInitializer which does
additional work. For example, a user can specify just a single
handler with initializer() and it will still work. This is especially
common for Bootstrap, so I renamed initializer to handler, which makes
more sense.
- DefaultChannelPipeline uses this information to reject invalid buffer
access in inbound(Message|Byte)Buffer. Otherwise, a user can access
a message buffer when the channel is stream-oriented.
- Because ChannelType cannot be both STREAM and MESSAGE, catch-all
buffer has been removed to avoid confusion and unexpected behavior
(it's already causing headache.)
- As a result, codec embedder needs rework.
... just like we do with byte arrays. toByteBuffer() and
toByteBuffers() had an indeterministic behavior and thus it could not
tell when the returned NIO buffer is shared or not. nioBuffer() always
returns a view buffer of the Netty buffer. The only case where
hasNioBuffer() returns false and nioBuffer() fails is the
CompositeChannelBuffer, which is not very commonly used and *slow*.
- Add EventExecutor and make EventLoop extend it
- Add SingleThreadEventExecutor and MultithreadEventExecutor
- Add EventExecutor's default implementation
- Fixed an API design problem where there is no way to get non-bypass
buffer of desired type
- Add ChannelHandlerContext.eventLoop() for convenience
- Bootstrap and ServerBootstrap handles channel initialization failure
better
- More strict checks for missing @Sharable annotation
- A handler without @Sharable annotation cannot be added more than
once now.
- Added a new convenience method to ChannelInboundstreamHandlerAdapter
- EchoServerHandler uses the new method
- DefaultChannelPipeline calls inboundByteBuffer.discardReadBytes()
when it is sure there's no memory copy involved
- Really attempt to create a queue to determine LTQ can be initialized
in runtime, and cache the result
- Remove unnecessary Class<T> parameter in createQueue()
- Remove unused createQueue(Collection)
- LocalChannel and LocalServerChannel uses it to close themselves on
shutdown
- LocalEcho example does not call close() anymore because the channels
are closed automatically on shutdown