Commit Graph

5943 Commits

Author SHA1 Message Date
Trustin Lee
2b5aa716ba Use heap buffers for Unpooled.copiedBuffer()
Related issue: #2028

Motivation:

Some copiedBuffer() methods in Unpooled allocated a direct buffer.  An
allocation of a direct buffer is an expensive operation, and thus should
be avoided for unpooled buffers.

Modifications:

- Use heap buffers in all copiedBuffer() methods

Result:

Unpooled.copiedBuffers() are less expensive now.
2014-08-13 15:10:00 -07:00
Norman Maurer
c46b197c61 [#2761] Proper work-around for data-corruption caused by cached ByteBuffers
Motivation:

The previous fix did disable the caching of ByteBuffers completely which can cause performance regressions. This fix makes sure we use nioBuffers() for all writes in NioSocketChannel and so prevent data-corruptions. This is still kind of a workaround which will be replaced by a more fundamental fix later.

Modifications:

- Revert 4059c9f354
- Use nioBuffers() for all writes to prevent data-corruption

Result:

No more data-corruption but still retain the original speed.
2014-08-13 21:21:15 +02:00
Norman Maurer
2c03030950 Revert "[#2761] ChannelOutboundBuffer can cause data-corruption because of caching ByteBuffers"
This reverts commit 4059c9f354.
2014-08-13 16:41:47 +02:00
Norman Maurer
1e6fddfc72 Revert "[#2762] Not expand ByteBuffer[] in ChannelOutboundBuffer"
This reverts commit 3db0128db9 as it may cause problem if a CompositeByteBuf has more then 1024 components.
2014-08-13 16:41:20 +02:00
Norman Maurer
3db0128db9 [#2762] Not expand ByteBuffer[] in ChannelOutboundBuffer
Motivation:

At the moment we expand the ByteBuffer[] when we have more then 1024 ByteBuffer to write and replace the stored instance in its FastThreadLocal. This is not needed and may even harm performance on linux as IOV_MAX is 1024 and so this may cause the JVM to do an array copy.

Modifications:

Just exit the nioBuffers() method if we can not fit more ByteBuffer in the array. This way we will pick them up on the next call.

Result:

Remove uncessary array copy and simplify the code.
2014-08-13 11:59:20 +02:00
Norman Maurer
4059c9f354 [#2761] ChannelOutboundBuffer can cause data-corruption because of caching ByteBuffers
Motivation:

We cache the ByteBuffers in ChannelOutboundBuffer.nioBuffers() for the Entries in the ChannelOutboundBuffer to reduce some overhead. The problem is this can lead to data-corruption if an incomplete write happens and next time we try to do a non-gathering write.

To fix this we should remove the caching which does not help a lot anyway and just make the code buggy.

Modifications:

Remove the caching of ByteBuffers.

Result:

No more data-corruption.
2014-08-13 11:06:03 +02:00
fredericBregier
ef3c030013 [#2722] Improve Traffic Shaping Handling
Motivation:
Currently Traffic Shaping is using 1 timer only and could lead to
"partial" wrong bandwidth computation when "short" time occurs between
adding used bytes and when the TrafficCounter updates itself and finally
when the traffic is computed.
Indeed, the TrafficCounter is updated every x delay and it is at the
same time saved into "lastXxxxBytes" and set to 0. Therefore, when one
request the counter, it first updates the TrafficCounter with the added
used bytes. If this value is set just before the TrafficCounter is
updated, then the bandwidth computation will use the TrafficCounter with
a "0" value (this value being reset once the delay occurs). Therefore,
the traffic shaping computation is wrong in rare cases.

Secondly the traffic shapping should avoid if possible the "Timeout"
effect by not stopping reading or writing more than a maxTime, this
maxTime being less than the TimeOut limit.

Thirdly the traffic shapping in read had an issue since the readOp was
not set but should, turning in no read blocking from socket point of
view. (see #2696)

Take into account setAutoRead(boolean) setting directly
by the user in the program external to this handler.

Modifications:
The TrafficCounter has 2 new methods that compute the time to wait
according to read or write) using in priority the currentXxxxBytes (as
before), but could used (if current is at 0) the lastXxxxxBytes, and
therefore having more chance to take into account the real traffic.

Moreover the Handler could change the default "max time to wait", which
is by default set to half of "standard" Time Out (30s:2 = 15s).

Finally we add the setAutoRead(boolean) accordingly to the situation, as
proposed in #2696 (the original pull request is in error for unknown
reason so this merge).

Result:
The Traffic Shaping is better take into account (no 0 value when it
shouldn't) and it tries to not block traffic more than Time Out event.

Moreover the read is really stopped from socket point of view.

This version is similar to #2388 and #2450.
This version is for V4.0, and includes the #2696 pull request to ease
the merge process.

The test minimizes time check by reducing to 66ms steps (50s total).
2014-08-13 01:29:58 +02:00
Norman Maurer
8f019ae4fa [#2752] Add PendingWriteQueue for queue up writes
Motivation:

Sometimes ChannelHandler need to queue writes to some point and then process these. We currently have no datastructure for this so the user will use an Queue or something like this. The problem is with this Channel.isWritable() will not work as expected and so the user risk to write to fast. That's exactly what happened in our SslHandler. For this purpose we need to add a special datastructure which will also take care of update the Channel and so be sure that Channel.isWritable() works as expected.

Modifications:

- Add PendingWriteQueue which can be used for this purpose
- Make use of PendingWriteQueue in SslHandler

Result:

It is now possible to queue writes in a ChannelHandler and still have Channel.isWritable() working as expected. This also fixes #2752.
2014-08-12 06:38:10 +02:00
Jeff Pinner
857713ad4c SPDY: fix SpdySessionHandler::updateSendWindowSize
In Netty 3, downstream writes of SPDY data frames and upstream reads of
SPDY window udpate frames occur on different threads.

When receiving a window update frame, we synchronize on a java object
(SpdySessionHandler::flowControlLock) while sending any pending writes
that are now able to complete.

When writing a data frame, we check the send window size to see if we
are allowed to write it to the socket, or if we have to enqueue it as a
pending write. To prevent races with the window update frame, this is
also synchronized on the same SpdySessionHandler::flowControlLock.

In Netty 4, upstream and downstream operations on any given channel now
occur on the same thread. Since java locks are re-entrant, this now
allows downstream writes to occur while processing window update frames.

In particular, when we receive a window update frame that unblocks a
pending write, this write completes which triggers an event notification
on the response, which in turn triggers a write of a data frame. Since
this is on the same thread it re-enters the lock and modifies the send
window. When the write completes, we continue processing pending writes
without knowledge that the window size has been decremented.
2014-08-11 11:27:58 +02:00
Norman Maurer
1e5501d304 [#2744] Fix flakey HashedWheelTimerTest.testExecutionOnTime()
Motivation:

The calculation of the max wait time for HashedWheelTimerTest.testExecutionOnTime() was wrong and so the test sometimes failed.

Modifications:

Fix the max wait time.

Result:

No more test-failures
2014-08-06 07:03:58 +02:00
Trustin Lee
62186856cb Fix a bug where SpdySession.getActiveStreams() returns incorrect set
Related issue: #2743

Motivation:

When there are more than one stream with the same priority, the set
returned by SpdySession.getActiveStream() will not include all of them,
because it uses TreeSet and only compares the priority of streams. If
two different streams have the same priority, one of them will be
discarded by TreeSet.

Modification:

- Rename getActiveStreams() to activeStreams()
- Replace PriorityComparator with StreamComparator

Result:

Two different streams with the same priority are compared correctly.
2014-08-05 16:50:16 -07:00
Trustin Lee
a73a4c66c7 Add test cases for HttpContentCompressor
- Ported from 386a06dbfa
2014-08-05 15:51:03 -07:00
Trustin Lee
b3c5d67bbd Fix a bug where ChannelFuture.setFailure(null) doesn't fail
Motivation:

We forgot to do a null check on the cause parameter of
ChannelFuture.setFailure(cause)

Modifications:

Add a null check

Result:

Fixed issue: #2728
2014-08-05 11:23:28 -07:00
Norman Maurer
7b6276f1d4 [#2732] HttpRequestEncoder may produce invalid uri if uri parameters are included.
Motivation:

If the requests contains uri parameters but not path the HttpRequestEncoder does produce an invalid uri while try to add the missing path.

Modifications:

Correctly handle the case of uri with paramaters but no path.

Result:

HttpRequestEncoder produce correct uri in all cases.
2014-08-05 10:13:05 +02:00
Trustin Lee
fb5583d788 Refactoring in preparation to unify I/O logic for all branches
Motivation:

While trying to merge our ChannelOutboundBuffer changes we've made last
week, I realized that we have quite a bit of conflicting changes at 4.1
and master. It was primarily because we added
ChannelOutboundBuffer.beforeAdd() and moved some logic there, such as
direct buffer conversion.

However, this is not possible with the changes we've made for 4.0. We
made ChannelOutboundBuffer final for example.

Maintaining multiple branch is already getting painful and having
different core will make it even worse, so I think we should keep the
differences between 4.0 and other branches minimal.

Modifications:

- Move ChannelOutboundBuffer.safeRelease() to ReferenceCountUtil
- Add ByteBufUtil.threadLocalBuffer()
  - Backported from ThreadLocalPooledDirectByteBuf
- Make most methods in AbstractUnsafe final
  - Add AbstractChannel.filterOutboundMessage() so that a transport can
    convert a message to another (e.g. heap -> off-heap), and also
    reject unsupported messages
  - Move all direct buffer conversions to filterOutboundMessage()
  - Move all type checks to filterOutboundMessage()
- Move AbstractChannel.checkEOF() to OioByteStreamChannel, because it's
  the only place it is used at all
- Remove ChannelOutboundBuffer.current(Object), because it's not used
  anymore
- Add protected direct buffer conversion methods to AbstractNioChannel
  and AbstractEpollChannel so that they can be used by their subtypes
- Update all transport implementations according to the changes above

Result:

- The missing extension point in 4.0 has been added.
  - AbstractChannel.filterOutboundMessage()
  - Thanks to the new extension point, we moved all transport-specific
    logic from ChannelOutboundBuffer to each transport implementation
- We can copy most of the transport implementations in 4.0 to 4.1 and
  master now, so that we have much less merge conflict when we modify
  the core.
2014-08-05 08:04:23 +02:00
Trustin Lee
b175b3d8be Add more utility methods to check the availability of the epoll transport
Related issue: #2733

Motivation:

Unlike OpenSsl, Epoll lacks a couple useful availability checker
methods:

- ensureAvailability()
- unavailabilityCause()

Modifications:

Add missing methods

Result:

More ways to check the availability and to get the cause of
unavailability programatically.
2014-08-04 15:03:25 -07:00
Norman Maurer
3f3e66c31a Allow to use ChannelOutboundBuffer without AbstractChannel
Motivation:

We expose ChannelOutboundBuffer in Channel.Unsafe but it is not possible
to create a new ChannelOutboundBuffer without an AbstractChannel.  This
makes it impossible to write a Channel implementation that does not
extend AbstractChannel.

Modifications:

- Change ChannelOutboundBuffer to take a Channel as constructor argument.
- Add javadocs

Result:

ChannelOutboundBuffer can be used with a Channel implemention that does
not extend AbstractChannel.
2014-08-04 12:44:38 -07:00
Trustin Lee
d0e4a85830 Clean-up d9cccccbb3
- Revert irrelevant formatting changes
- Rename resource files
  - Add .pem
  - Remove 'netty' from names
2014-08-04 10:53:39 -07:00
Trustin Lee
021ecd45c3 More brief somaxconn logging
- Consistent log message format
- Avoid unnecessary autoboxing when debug level is off
- Remove the duplication of somaxconn path
2014-08-04 10:25:11 -07:00
Peter Schulz
d9cccccbb3 [#2718] Added private key decryption to JDK SSL server context.
Motivation:

Currently it is not possible to load an encrypted private key when
creating a JDK based SSL server context.

Modifications:

- Added static method to JdkSslServerContext which handles key spec generation for (encrypted) private keys and make use of it.
-Added tests for creating a SSL server context based on a (encrypted)
private key.

Result:

It is now possible to create a JDK based SSL server context with an
encrypted (password protected) private key.
2014-08-04 14:19:48 +02:00
Norman Maurer
039cace00d Remove license of deque as we not use it anymore
Motivation:

Our ChannelOutboundBuffer implementation is not based on ArrayDeque anymore so we can remove the license notice for it.

Modifications:

Remove license of deque and entry in NOTICE.

Result:

Cleaned up licenses
2014-08-04 12:21:33 +02:00
Trustin Lee
16e50765d1 Fix a stall write in EpollSocketChannel
Motivation:

When a ChannelOutboundBuffer contains a series of entries whose messages
are all empty buffers, EpollSocketChannel sometimes fails to remove
them. As a result, the result of the write(EmptyByteBuf) is never
notified, making the user application hang.

Modifications:

- Add ChannelOutboundBuffer.removeBytes(long) method that updates the
  progress of the entries and removes them as much as the specified
  number of written bytes.  It also updates the reader index of
  partially flushed buffer.
  - Make both NioSocketChannel and EpollSocketChannel use it to reduce
    code duplication
  - Replace EpollSocketChannel.updateOutboundBuffer()
- Refactor EpollSocketChannel.doWrite() for simplicity
  - Split doWrite() into doWriteSingle() and doWriteMultiple()
- Do not add a zero-length buffer to IovArray
- Do not perform any real I/O when the size of IovArray is 0

Result:

Another regression is gone.
2014-08-01 16:58:12 -07:00
Norman Maurer
d9934e5fb4 Remove duplicated code 2014-07-31 18:10:11 -07:00
Norman Maurer
d10983b7f4 [#2720] Check if /proc/sys/net/core/somaxconn exists before try to parse it
Motivation:

As /proc/sys/net/core/somaxconn does not exists on non-linux platforms you see a noisy stacktrace when debug level is enabled while the static method of NetUtil is executed.

Modifications:

Check if the file exists before try to parse it.

Result:

Less noisy logging on non-linux platforms.
2014-07-31 18:05:18 -07:00
Trustin Lee
91639b3dbf Use our own URL shortener wherever possible 2014-07-31 17:05:54 -07:00
Trustin Lee
d6f0d12a86 Fix a bug in ChannelOutboundBuffer.nioBuffers()
Related issue: #2717, #2710, #2704, #2693

Motivation:

When ChannelOutboundBuffer.nioBuffers() iterates over the linked list of
entries, it is not supposed to visit unflushed entries, but it does.

Modifications:

- Make sure ChannelOutboundBuffer.nioBuffers() stops the iteration before
  it visits an unflushed entry
- Add isFlushedEntry() to reduce the chance of the similar mistakes

Result:

Another regression is gone.
2014-07-31 15:25:32 -07:00
Trustin Lee
8ee3575e72 Fix a bug in ChannelOutboundBuffer.forEachFlushedMessage()
Motivation:

ChannelOutboundBuffer.forEachFlushedMessage() visits even an unflushed
messages.

Modifications:

Stop the loop if the currently visiting entry is unflushedEntry.

Result:

forEachFlushedMessage() behaves correctly.
2014-07-30 15:36:33 -07:00
Trustin Lee
5e5d1a58fd Overall cleanup
- ChannelOutboundBuffer.Entry.buffers -> bufs for consistency
- Make Native.IOV_MAX final because it's a constant
- Naming changes
  - FlushedMessageProcessor -> MessageProcessor just in case we can
    reuse it for unflushed messages in the future
- Add ChannelOutboundBuffer.Entry.recycle() that does not return the
  next entry, and use it wherever possible
- Javadoc clean-up
2014-07-30 14:57:13 -07:00
Norman Maurer
e282e504f1 Optimize gathering write in the epoll transport
Motivation:

While benchmarking the native transport, I noticed that gathering write
is not as fast as expected.  It was due to the fact that we have to do a
lot of array copies to put the buffer addresses into the iovec struct
array.

Modifications:

Introduce a new class called IovArray, which allows to fill buffers
directly into an off-heap array of iovec structs, so that it can be
passed over to JNI without any extra array copies.

Result:

Big performance improvement when doing gathering writes:

Before:

[nmaurer@xxx]~% wrk/wrk -H 'Host: localhost' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Connection: keep-alive' -d 120 -c 256 -t 16 --pipeline 256  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    23.44ms   16.37ms 259.57ms   91.77%
    Req/Sec   181.99k    31.69k  304.60k    78.12%
  346544071 requests in 2.00m, 46.48GB read
Requests/sec: 2887885.09
Transfer/sec:    396.59MB

After:

[nmaurer@xxx]~% wrk/wrk -H 'Host: localhost' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Connection: keep-alive' -d 120 -c 256 -t 16 --pipeline 256  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.93ms   16.33ms 305.73ms   92.34%
    Req/Sec   194.56k    33.75k  309.33k    77.04%
  369617503 requests in 2.00m, 49.57GB read
Requests/sec: 3080169.65
Transfer/sec:    423.00MB
2014-07-30 14:57:13 -07:00
Trustin Lee
997d8c32d2 Fix a regression caused by 73dfd7c01b
Motivation:

73dfd7c01b introduced various test
failures because:

- EpollSocketChannel.doWrite() raised a NullPointerException when
  notifying the write progress.
- ChannelOutboundBuffer.nioBuffers() did not expand the internal array
  when the pending entries contained more than 1024 buffers, dropping
  the remainder.

Modifications:

- Fix the NPE in EpollSocketChannel by removing an unnecessary progress
  update
- Expand the thread-local buffer array if there is not enough room,
  which was the original behavior dropped by the offending commit

Result:

Regression is gone.
2014-07-30 13:49:17 -07:00
Trustin Lee
07801d7b38 Remove duplicate range check in AbstractByteBuf.skipBytes() 2014-07-29 15:58:38 -07:00
Norman Maurer
73dfd7c01b [#2693] Reduce memory usage of ChannelOutboundBuffer
Motiviation:

ChannelOuboundBuffer uses often too much memory. This is especially a problem if you want to serve a lot of connections. This is due the fact that it uses 2 arrays internally. One if used as a circular buffer and store the Entries that are never released  (ChannelOutboundBuffer is pooled) and one is used to hold the ByteBuffers that are used for gathering writes.

Modifications:

Rewrite ChannelOutboundBuffer to remove these two arrays by:
  - Make Entry recyclable and use it as linked Node
  - Remove the circular buffer which was used for the Entries as we use a Linked-List like structure now
  - Remove the array that did hold the ByteBuffers and replace it by an ByteBuffer array that is hold by a FastThreadLocal. We use a fixed capacity of 1024 here which is fine as we share these anyway.
  - ChannelOuboundBuffer is not recyclable anymore as it is now a "light-weight" object. We recycle the internally used Entries instead.

Result:

Less memory footprint and resource usage. Performance seems to be a bit better but most likely as we not need to expand any arrays anymore.

Benchmark before change:
[nmaurer@xxx]~% wrk/wrk -H 'Host: localhost' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Connection: keep-alive' -d 120 -c 256 -t 16 --pipeline 256  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    26.88ms   67.47ms   1.26s    97.97%
    Req/Sec   191.81k    28.22k  255.63k    83.86%
  364806639 requests in 2.00m, 48.92GB read
Requests/sec: 3040101.23
Transfer/sec:    417.49MB

Benchmark after change:

[nmaurer@xxx]~% wrk/wrk -H 'Host: localhost' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Connection: keep-alive' -d 120 -c 256 -t 16 --pipeline 256  http://xxx:8080/plaintext
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    22.22ms   17.22ms 301.77ms   90.13%
    Req/Sec   194.98k    41.98k  328.38k    70.50%
  371816023 requests in 2.00m, 49.86GB read
Requests/sec: 3098461.44
Transfer/sec:    425.51MB
2014-07-28 15:08:16 -07:00
Norman Maurer
c90de50ea7 Use correct exception message when throw exception from native code
Motivation:

We sometimes not use the correct exception message when throw it from the native code.

Modifications:

Fixed the message.

Result:

Correct message in exception
2014-07-28 13:31:26 -07:00
Norman Maurer
35061a4332 [#2692] Allows notify ChannelFutureProgressListener on complete writes
Motivation:

We have some inconsistency when handling writes. Sometimes we call ChannelOutboundBuffer.progress(...) also for complete writes and sometimes not. We should call it always.

Modifications:

Correctly call ChannelOuboundBuffer.progress(...) for complete and incomplete writes.

Result:

Consistent behavior
2014-07-28 04:12:59 -07:00
Norman Maurer
d989b24351 [#2662] Fix race in cancellation of TimerTasks which could let to NPE
Motivation:

Due some race-condition while handling canellation of TimerTasks it was possibleto corrupt the linked-list structure that is represent by HashedWheelBucket and so produce a NPE.

Modification:

Fix the problem by adding another MpscLinkedQueue which holds the cancellation tasks and process them on each tick. This allows to use no synchronization / locking at all while introduce a latency of max 1 tick before the TimerTask can be GC'ed.

Result:

No more NPE
2014-07-25 06:34:49 +02:00
Norman Maurer
f5faada77c [#2705] Call fireChannelReadComplete() if channelActive(...) decodes messages in ReplayingDecoder / ByteToMessageDecoder
Motivation:

In ReplayingDecoder / ByteToMessageDecoder channelInactive(...) method we try to decode a last time and fire all decoded messages throw the pipeline before call ctx.fireChannelInactive(...). To keep the correct order of events we also need to call ctx.fireChannelReadComplete() if we read anything.

Modifications:

- Channel channelInactive(...) to call ctx.fireChannelReadComplete() if something was decoded
- Move out.recycle() to finally block

Result:

Correct order of events.
2014-07-24 14:33:56 +02:00
Willem Jiang
ce069e2dc4 Updated the ChannelGroup JavaDoc by removing b.releaseExternalResources(); 2014-07-24 10:55:22 +02:00
Trustin Lee
08c87c6256 Reduce the default initial capacity of ChannelOutboundBuffer
Motivation:

ChannelOutboundBuffer is basically a circular array queue of its entry
objects.  Once an entry is created in the array, it is never nulled out
to reduce the allocation cost.

However, because it is a circular queue, the array almost always ends up
with as many entry instances as the size of the array, regardless of the
number of pending writes.

At worst case, a channel might have only 1 pending writes at maximum
while creating 32 entry objects, where 32 is the initial capacity of the
array.

Modifications:

- Reduce the initial capacity of the circular array queue to 4.
- Make the initial capacity of the circular array queue configurable

Result:

We spend 4 times less memory for entry objects under certain
circumstances.
2014-07-22 13:38:24 -07:00
Trustin Lee
ed304b42f5 Add a link to the 'native transports' page 2014-07-21 12:54:43 -07:00
Osvaldo Doederlein
0ae7f2f5e1 Fixes and improvements to IntObjectHashMap. Related to [#2659]
- Rewrite with linear probing, no state array, compaction at cleanup
- Optimize keys() and values() to not use reflection
- Optimize hashCode() and equals() for efficient iteration
- Fixed equals() to not return true for equals(null)
- Optimize iterator to not allocate new Entry at each next()
- Added toString()
- Added some new unit tests
2014-07-21 16:44:19 +02:00
Norman Maurer
e25891964c [#2675] Replace synchronization performed on util.concurrent instance in TrafficCounter
Motivation:

Message from FindBugs:
This method performs synchronization an object that is an instance of a class from the java.util.concurrent package (or its subclasses). Instances of these classes have their own concurrency control mechanisms that are orthogonal to the synchronization provided by the Java keyword synchronized. For example, synchronizing on an AtomicBoolean will not prevent other threads from modifying the AtomicBoolean.
Such code may be correct, but should be carefully reviewed and documented, and may confuse people who have to maintain the code at a later date.

Modification:

Use synchronized(this)

Result:

Less confusing code
2014-07-21 08:21:27 +02:00
Jeff Pinner
6d0233d3bd SPDY: fix pushed response NullPointerException 2014-07-21 07:59:25 +02:00
Norman Maurer
eb34cbb2d8 [#2685] Epoll transport should use GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical
Motivation:

At the moment we use Get*ArrayElement all the time in the epoll transport which may be wasteful as the JVM may do a memory copy for this. For code-path that will get executed fast (without blocking) we should better make use of GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical as this signal the JVM that we not want to do any memory copy if not really needed. It is important to only do this on non-blocking code-path as this may even suspend the GC to disallow the JVM to move the arrays around.

See also http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical

Modification:

Make use of GetPrimitiveArrayCritical / ReleasePrimitiveArrayCritical as replacement for Get*ArrayElement / Release*ArrayElement where possible.

Result:

Better performance due less memory copies.
2014-07-21 07:07:09 +02:00
Norman Maurer
028128993d [#2684] EpollSocketChannel gathering writes should take fast-path if possible
Motivation:

In EpollSocketchannel.writeBytesMultiple(...) we loop over all buffers to see if we need to adjust the readerIndex for incomplete writes. We can skip this if we know that everything was written (a.k.a complete write).

Modification:

Use fast-path if all bytes are written and so no need to loop over buffers

Result:

Fast write path for the average use.
2014-07-21 06:43:49 +02:00
Norman Maurer
e7310cc4c0 Only try gathering writes if we have more then one buffer to write. Part of [#2680]. 2014-07-20 20:00:21 +02:00
Norman Maurer
cb2246ee07 [#2680] ChannelOutboundBuffer.nioBuffers() should always return non-null array as stated in javadocs
Motivation:

At the moment ChannelOutboundBuffer.nioBuffers() returns null if something is contained in the ChannelOutboundBuffer which is not a ByteBuf. This is a problem for two reasons:
 1 - In the javadocs we state that it will never return null
 2 - We may do a not optimal write as there may be things that could be written via gathering writes

Modifications:

Change ChannelOutboundBuffer.nioBuffers() to never return null but have it contain all ByteBuffer that were found before the non ByteBuf. This way we can do a gathering write and also conform to the javadocs.

Result:

Better speed and also correct implementation in terms of the api.
2014-07-20 19:13:48 +02:00
Idel Pivnitskiy
dd026eb60a Fix NPE problems
Motivation:

Now Netty has a few problems with null values.

Modifications:

- Check File in DiskFileUpload.toString().
If File is null we will get NPE when calling toString() method.
- Check Result<String> in MqttDecoder.decodeConnectionPayload(...).
- Check Unsafe before calling unsafe.getClass() in PlatformDependent0 static block.
- Removed unnecessary null check in WebSocket08FrameEncoder.encode(...).
Because msg.content() can not return null.
- Removed unnecessary null checks in ConcurrentHashMapV8.removeTreeNode(TreeNode<K,V>).
- Removed unnecessary null check in OioDatagramChannel.doReadMessages(List<Object>).
Because tmpPacket.getSocketAddress() always returns new SocketAddress instance.
- Removed unnecessary null check in OioServerSocketChannel.doReadMessages(List<Object>).
Because socket.accept() always returns new Socket instance.
- Pass Unpooled.buffer(0) instead of null inside CloseWebSocketFrame(boolean, int) constructor.
If we will pass null we will get NPE in super class constructor.
- Added throw new IllegalStateException in GlobalEventExecutor.awaitInactivity(long, TimeUnit) if it will be called before GlobalEventExecutor.execute(Runnable).
Because now we will get NPE. IllegalStateException will be better in this case.
- Fixed null check in OpenSslServerContext.setTicketKeys(byte[]).
Now we throw new NPE if byte[] is not null.

Result:

Added new null checks when it is necessary, removed unnecessary null checks and fixed some NPE problems.
2014-07-20 12:56:21 +02:00
Idel Pivnitskiy
13569481bf Small fixes and improvements
Motivation:

Fix some typos in Netty.

Modifications:

- Fix potentially dangerous use of non-short-circuit logic in Recycler.transfer(Stack<?>).
- Removed double 'the the' in javadoc of EmbeddedChannel.
- Write to log an exception message if we can not get SOMAXCONN in the NetUtil's static block.
2014-07-20 09:36:57 +02:00
Idel Pivnitskiy
a7f0fdfa9c Fixes for compression codecs
Motivation:

Fixed founded mistakes in compression codecs.

Modifications:

- Changed return type of ZlibUtil.inflaterException() from CompressionException to DecompressionException
- Updated @throws in javadoc of JZlibDecoder to throw DecompressionException instead of CompressionException
- Fixed JdkZlibDecoder to throw DecompressionException instead of CompressionException
- Removed unnecessary empty lines in JdkZlibEncoder and JZlibEncoder
- Removed public modifier from Snappy class
- Added MAX_UNCOMPRESSED_DATA_SIZE constant in SnappyFramedDecoder
- Used in.readableBytes() instead of (in.writerIndex() - in.readerIndex()) in SnappyFramedDecoder
- Added private modifier for enum ChunkType in SnappyFramedDecoder

Result:

Fixed sum overflow in Bzip2HuffmanAllocator, improved exceptions in ZlibDecoder implementations, hid Snappy class
2014-07-20 09:34:31 +02:00
Idel Pivnitskiy
01b11ca2cb Small performance improvements
Modifications:

- Added a static modifier for CompositeByteBuf.Component.
This class is an inner class, but does not use its embedded reference to the object which created it. This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary.
A boxed primitive is created from a String, just to extract the unboxed primitive value.
- Removed unnecessary checks if file exists before call mkdirs() in NativeLibraryLoader and PlatformDependent.
Because the method mkdirs() has this check inside.

Conflicts:
	codec-http/src/main/java/io/netty/handler/codec/http/multipart/DiskAttribute.java
	codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeAggregator.java
	codec-stomp/src/main/java/io/netty/handler/codec/stomp/StompSubframeDecoder.java
2014-07-20 09:29:33 +02:00