Netty

Clone Tools
  • last updated a few seconds ago
Constraints
Constraints: committers
 
Constraints: files
Constraints: dates
Fixing minor typo in FastThreadLocal javadoc.

Fixing minor typo in FastThreadLocal javadoc.

Allow to override how headers are encoded

Motivation:

Even if its against the HTTP RFC there are situations where it may be useful to use other chars then US_ASCII in the headers. We should allow to make it possible by allow the user to override the how headers are encoded.

Modifications:

- Add encodeHeaders(...) method and so allow to override it.

Result:

It's now possible to encode headers with other charset then US_ASCII by just extend the encoder and override the encodeHeaders(...) method.

Allow to override how headers are encoded

Motivation:

Even if its against the HTTP RFC there are situations where it may be useful to use other chars then US_ASCII in the headers. We should allow to make it possible by allow the user to override the how headers are encoded.

Modifications:

- Add encodeHeaders(...) method and so allow to override it.

Result:

It's now possible to encode headers with other charset then US_ASCII by just extend the encoder and override the encodeHeaders(...) method.

Allow to override how headers are encoded

Motivation:

Even if its against the HTTP RFC there are situations where it may be useful to use other chars then US_ASCII in the headers. We should allow to make it possible by allow the user to override the how headers are encoded.

Modifications:

- Add encodeHeaders(...) method and so allow to override it.

Result:

It's now possible to encode headers with other charset then US_ASCII by just extend the encoder and override the encodeHeaders(...) method.

Make PendingWriteQueue.recycle() update its state before triggering an event

Related: #3212

Motivation:

PendingWriteQueue.recycle() updates its data structure after triggering

a channelWritabilityChanged() event. It causes a rare corruption such as

double free when channelWritabilityChanged() method accesses the

PendingWriteQueue.

Modifications:

Update the state of PendingWriteQueue before triggering an event.

Result:

Fix a rare double-free problem

Make PendingWriteQueue.recycle() update its state before triggering an event

Related: #3212

Motivation:

PendingWriteQueue.recycle() updates its data structure after triggering

a channelWritabilityChanged() event. It causes a rare corruption such as

double free when channelWritabilityChanged() method accesses the

PendingWriteQueue.

Modifications:

Update the state of PendingWriteQueue before triggering an event.

Result:

Fix a rare double-free problem

Make PendingWriteQueue.recycle() update its state before triggering an event

Related: #3212

Motivation:

PendingWriteQueue.recycle() updates its data structure after triggering

a channelWritabilityChanged() event. It causes a rare corruption such as

double free when channelWritabilityChanged() method accesses the

PendingWriteQueue.

Modifications:

Update the state of PendingWriteQueue before triggering an event.

Result:

Fix a rare double-free problem

Fix AbstractDiskHttpData int conversion from long

Motivations:

The chunkSize might be oversized after comparison (size being > of int

capacity) if file size is bigger than an integer.

Modifications:

Change it to long.

Result:

There is no more int oversized.

Same fix for 4.1 and Master

Fix AbstractDiskHttpData int conversion from long

Motivations:

The chunkSize might be oversized after comparison (size being > of int

capacity) if file size is bigger than an integer.

Modifications:

Change it to long.

Result:

There is no more int oversized.

Same fix for 4.1 and Master

Fix AbstractDiskHttpData int conversion from long

Motivations:

The chunkSize might be oversized after comparison (size being > of int

capacity) if file size is bigger than an integer.

Modifications:

Change it to long.

Result:

There is no more int oversized.

Same fix for 4.1 and Master

Fix AbstractDiskHttpData int conversion from long

Motivations:

The chunkSize might be oversized after comparison (size being > of int capacity) if file size is bigger than an integer.

Modifications:

Changing the type to long fix the issue.

Result:

There is no more int oversized.

Trigger exceptionCaught() when VoidChannelPromise fails

Related: #3190

Motivation:

When an outbound handler method raises an exception, its promise is

marked as failed. If the promise is done already, the exception is

logged.

When the promise is void, exceptionCaught() must be triggered to notify

a user. However, ChannelHandlerInvokerUtil simply swallows it.

Modifications:

Do not swallow an exception when the promise is void.

Result:

A user who uses a void promise for an outbound operation will be

notified on failure.

Trigger exceptionCaught() when VoidChannelPromise fails

Related: #3190

Motivation:

When an outbound handler method raises an exception, its promise is

marked as failed. If the promise is done already, the exception is

logged.

When the promise is void, exceptionCaught() must be triggered to notify

a user. However, ChannelHandlerInvokerUtil simply swallows it.

Modifications:

Do not swallow an exception when the promise is void.

Result:

A user who uses a void promise for an outbound operation will be

notified on failure.

Trigger exceptionCaught() when VoidChannelPromise fails

Related: #3190

Motivation:

When an outbound handler method raises an exception, its promise is

marked as failed. If the promise is done already, the exception is

logged.

When the promise is void, exceptionCaught() must be triggered to notify

a user. However, AbstractChannelHandlerContext simply swallows it.

Modifications:

Do not swallow an exception when the promise is void.

Result:

A user who uses a void promise for an outbound operation will be

notified on failure.

Fire channelRead() event immediately in OIO message channels

Related: #3189

Motivation:

OIO transport implementations block for at most 1 second to wait for

additional messages (or accepted connections).

However, because AbstractOioMessageChannel defers the channelRead()

events for the messages read so far until there's nothing to read up to

maxMessagesPerRead, any read operation will be followed by a 1-second

delay.

Modifications:

Fire channelRead() events as soon as doRead() returns so that there is

no 1 second delay between the actual read and the channelRead() event.

Result:

No more weird 1-second delay

Fire channelRead() event immediately in OIO message channels

Related: #3189

Motivation:

OIO transport implementations block for at most 1 second to wait for

additional messages (or accepted connections).

However, because AbstractOioMessageChannel defers the channelRead()

events for the messages read so far until there's nothing to read up to

maxMessagesPerRead, any read operation will be followed by a 1-second

delay.

Modifications:

Fire channelRead() events as soon as doRead() returns so that there is

no 1 second delay between the actual read and the channelRead() event.

Result:

No more weird 1-second delay

Fire channelRead() event immediately in OIO message channels

Related: #3189

Motivation:

OIO transport implementations block for at most 1 second to wait for

additional messages (or accepted connections).

However, because AbstractOioMessageChannel defers the channelRead()

events for the messages read so far until there's nothing to read up to

maxMessagesPerRead, any read operation will be followed by a 1-second

delay.

Modifications:

Fire channelRead() events as soon as doRead() returns so that there is

no 1 second delay between the actual read and the channelRead() event.

Result:

No more weird 1-second delay

Fix Java 6 compatibility issue in DnsNameResolver

Related: #3173

Motivation:

DnsNameResolver was using InetSocketAddress.getHostString() which is

only available since Java 7.

Modifications:

Use InetSocketAddress.getHostName() in lieu of getHostString() when the

current Java version is less than 7.

Result:

DnsNameResolver runs fine on Java 6.

Fix Java 6 compatibility issue in DnsNameResolver

Related: #3173

Motivation:

DnsNameResolver was using InetSocketAddress.getHostString() which is

only available since Java 7.

Modifications:

Use InetSocketAddress.getHostName() in lieu of getHostString() when the

current Java version is less than 7.

Result:

DnsNameResolver runs fine on Java 6.

Change the type of HTTP string properties to AsciiString

Related: #3132

Motivation:

Changing the type of the string properties of HttpVersion and

HttpResponseStatus to AsciiString will give us the performance advantage

when encoding it into the wire.

Modifications:

- Change the type of the following properties to AsciiString:

- HttpVersion.protocolName()

- HttpVersion.text()

- HttpResponseStatus.reasonPhrase()

- Inline their respective encode() methods because they are used only in

the encoders.

- Fix the test failures incurred by the changes above

Result:

Getting close to the machine

Change the type of HttpMethod.name() to AsciiString

Related: #3132

Motivation:

Changing the type of HttpMethod.name() gives us the performance

advantage when encoding it into the wire.

Modifications:

- Change the type of HttpMethod.name()

- Inline HttpMethod.encode() because it's used only in a single place

and it's trivial.

Result:

Getting close to the machine

Refactoring HTTP/2 Flow Control interfaces.

Motivation:

The terminology used with inbound/outbound is a little confusing since

it's not discussed in the spec. We should switch to using local/remote

instead. Also there is some asymmetry between the inbound/outbound

interfaces which could probably be cleaned up.

Modifications:

Changing the interface names and making a common Http2FlowController

interface for most of the methods.

Result:

The HTTP/2 flow control interfaces should be more clear.

  1. … 15 more files in changeset.
Fix a bug where Recycler's capacity can increase beyond its maximum

Related: #3166

Motivation:

When the recyclable object created at one thread is returned at the

other thread, it is stored in a WeakOrderedQueue.

The objects stored in the WeakOrderedQueue is added back to the stack by

WeakOrderedQueue.transfer() when the owner thread ran out of recyclable

objects.

However, WeakOrderedQueue.transfer() does not have any mechanism that

prevents the stack from growing beyond its maximum capacity.

Modifications:

- Make WeakOrderedQueue.transfer() increase the capacity of the stack

only up to its maximum

- Add tests for the cases where the recyclable object is returned at the

non-owner thread

- Fix a bug where Stack.scavengeSome() does not scavenge the objects

when it's the first time it ran out of objects and thus its cursor is

null.

- Overall clean-up of scavengeSome() and transfer()

Result:

The capacity of Stack never increases beyond its maximum.

    • -35
    • +77
    /common/src/main/java/io/netty/util/Recycler.java
Fix a bug where Recycler's capacity can increase beyond its maximum

Related: #3166

Motivation:

When the recyclable object created at one thread is returned at the

other thread, it is stored in a WeakOrderedQueue.

The objects stored in the WeakOrderedQueue is added back to the stack by

WeakOrderedQueue.transfer() when the owner thread ran out of recyclable

objects.

However, WeakOrderedQueue.transfer() does not have any mechanism that

prevents the stack from growing beyond its maximum capacity.

Modifications:

- Make WeakOrderedQueue.transfer() increase the capacity of the stack

only up to its maximum

- Add tests for the cases where the recyclable object is returned at the

non-owner thread

- Fix a bug where Stack.scavengeSome() does not scavenge the objects

when it's the first time it ran out of objects and thus its cursor is

null.

- Overall clean-up of scavengeSome() and transfer()

Result:

The capacity of Stack never increases beyond its maximum.

    • -35
    • +77
    /common/src/main/java/io/netty/util/Recycler.java
Fix a bug where Recycler's capacity can increase beyond its maximum

Related: #3166

Motivation:

When the recyclable object created at one thread is returned at the

other thread, it is stored in a WeakOrderedQueue.

The objects stored in the WeakOrderedQueue is added back to the stack by

WeakOrderedQueue.transfer() when the owner thread ran out of recyclable

objects.

However, WeakOrderedQueue.transfer() does not have any mechanism that

prevents the stack from growing beyond its maximum capacity.

Modifications:

- Make WeakOrderedQueue.transfer() increase the capacity of the stack

only up to its maximum

- Add tests for the cases where the recyclable object is returned at the

non-owner thread

- Fix a bug where Stack.scavengeSome() does not scavenge the objects

when it's the first time it ran out of objects and thus its cursor is

null.

- Overall clean-up of scavengeSome() and transfer()

Result:

The capacity of Stack never increases beyond its maximum.

    • -35
    • +77
    /common/src/main/java/io/netty/util/Recycler.java
example: memcache: fix set command

Motivation:

The example MemcacheClient set command doesn't work.

Modifications:

Fill the extras field buffer with zeros so that it gets written to the

request payload.

Result:

The example MemcacheClient set command works.

example: memcache: fix set command

Motivation:

The example MemcacheClient set command doesn't work.

Modifications:

Fill the extras field buffer with zeros so that it gets written to the

request payload.

Result:

The example MemcacheClient set command works.

Fix a race condition where handler is removed before unregistration

Related: #3156

Motivation:

Let's say we have a channel with the following pipeline configuration:

HEAD --> [E1] H1 --> [E2] H2 --> TAIL

when the channel is deregistered, the channelUnregistered() methods of

H1 and H2 will be invoked from the executor thread of E1 and E2

respectively. To ensure that the channelUnregistered() methods are

invoked from the correct thread, new one-time tasks will be created

accordingly and be scheduled via Executor.execute(Runnable).

As soon as the one-time tasks are scheduled,

DefaultChannelPipeline.fireChannelUnregistered() will start to remove

all handlers from the pipeline via teardownAll(). This process is

performed in reversed order of event propagation. i.e. H2 is removed

first, and then H1 is removed.

If the channelUnregistered() event has been passed to H2 before H2 is

removed, a user does not see any problem.

If H2 has been removed before channelUnregistered() event is passed to

H2, a user will often see the following confusing warning message:

An exceptionCaught() event was fired, and it reached at the tail of

the pipeline. It usually means the last handler in the pipeline did

not handle the exception.

Modifications:

To ensure that the handlers are removed *after* all events are

propagated, traverse the pipeline in ascending order before performing

the actual removal.

Result:

A user does not get the confusing warning message anymore.

Fix a race condition where handler is removed before unregistration

Related: #3156

Motivation:

Let's say we have a channel with the following pipeline configuration:

HEAD --> [E1] H1 --> [E2] H2 --> TAIL

when the channel is deregistered, the channelUnregistered() methods of

H1 and H2 will be invoked from the executor thread of E1 and E2

respectively. To ensure that the channelUnregistered() methods are

invoked from the correct thread, new one-time tasks will be created

accordingly and be scheduled via Executor.execute(Runnable).

As soon as the one-time tasks are scheduled,

DefaultChannelPipeline.fireChannelUnregistered() will start to remove

all handlers from the pipeline via teardownAll(). This process is

performed in reversed order of event propagation. i.e. H2 is removed

first, and then H1 is removed.

If the channelUnregistered() event has been passed to H2 before H2 is

removed, a user does not see any problem.

If H2 has been removed before channelUnregistered() event is passed to

H2, a user will often see the following confusing warning message:

An exceptionCaught() event was fired, and it reached at the tail of

the pipeline. It usually means the last handler in the pipeline did

not handle the exception.

Modifications:

To ensure that the handlers are removed *after* all events are

propagated, traverse the pipeline in ascending order before performing

the actual removal.

Result:

A user does not get the confusing warning message anymore.