Fixed stack overflow error
This commit is contained in:
parent
38943f3d23
commit
4e7852e29e
@ -59,8 +59,20 @@ abstract class NioSocketChannel extends AbstractChannel
|
||||
final Runnable writeTask = new WriteTask();
|
||||
final AtomicInteger writeBufferSize = new AtomicInteger();
|
||||
final Queue<MessageEvent> writeBuffer = new WriteBuffer();
|
||||
boolean wasWritable;
|
||||
boolean mightNeedToNotifyUnwritability;
|
||||
|
||||
/** Previous return value of isWritable() */
|
||||
boolean oldWritable;
|
||||
/**
|
||||
* Set to true if the amount of data in the writeBuffer exceeds
|
||||
* the high water mark, as specified in NioSocketChannelConfig.
|
||||
*/
|
||||
boolean exceededHighWaterMark;
|
||||
/**
|
||||
* true if and only if NioWorker is firing an event which might cause
|
||||
* infinite recursion.
|
||||
*/
|
||||
boolean firingEvent;
|
||||
|
||||
MessageEvent currentWriteEvent;
|
||||
int currentWriteIndex;
|
||||
|
||||
@ -160,7 +172,7 @@ abstract class NioSocketChannel extends AbstractChannel
|
||||
int newWriteBufferSize = writeBufferSize.addAndGet(
|
||||
-((ChannelBuffer) e.getMessage()).readableBytes());
|
||||
if (newWriteBufferSize <= getConfig().getWriteBufferLowWaterMark()) {
|
||||
mightNeedToNotifyUnwritability = true;
|
||||
exceededHighWaterMark = true;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
|
@ -479,25 +479,35 @@ class NioWorker implements Runnable {
|
||||
|
||||
private static void fireChannelInterestChangedIfNecessary(
|
||||
NioSocketChannel channel, boolean open) {
|
||||
int interestOps = channel.getRawInterestOps();
|
||||
boolean wasWritable = channel.wasWritable;
|
||||
boolean writable = channel.wasWritable = open? channel.isWritable() : false;
|
||||
if (wasWritable) {
|
||||
if (writable) {
|
||||
if (channel.mightNeedToNotifyUnwritability) {
|
||||
channel.mightNeedToNotifyUnwritability = false;
|
||||
if (channel.firingEvent) {
|
||||
// Prevent StackOverflowError.
|
||||
return;
|
||||
}
|
||||
|
||||
channel.firingEvent = true;
|
||||
try {
|
||||
int interestOps = channel.getRawInterestOps();
|
||||
boolean wasWritable = channel.oldWritable;
|
||||
boolean writable = channel.oldWritable = open? channel.isWritable() : false;
|
||||
if (wasWritable) {
|
||||
if (writable) {
|
||||
if (channel.exceededHighWaterMark) {
|
||||
channel.exceededHighWaterMark = false;
|
||||
fireChannelInterestChanged(channel, interestOps | Channel.OP_WRITE);
|
||||
fireChannelInterestChanged(channel, interestOps & ~Channel.OP_WRITE);
|
||||
}
|
||||
} else {
|
||||
fireChannelInterestChanged(channel, interestOps | Channel.OP_WRITE);
|
||||
fireChannelInterestChanged(channel, interestOps & ~Channel.OP_WRITE);
|
||||
}
|
||||
} else {
|
||||
fireChannelInterestChanged(channel, interestOps | Channel.OP_WRITE);
|
||||
}
|
||||
} else {
|
||||
if (writable) {
|
||||
fireChannelInterestChanged(channel, interestOps & ~Channel.OP_WRITE);
|
||||
} else {
|
||||
fireChannelInterestChanged(channel, interestOps | Channel.OP_WRITE);
|
||||
if (writable) {
|
||||
fireChannelInterestChanged(channel, interestOps & ~Channel.OP_WRITE);
|
||||
} else {
|
||||
fireChannelInterestChanged(channel, interestOps | Channel.OP_WRITE);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
channel.firingEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user