Avoid StackOverflowErrors when submitting changes.
These were possible on a busy server, when many new connections are created, and each triggers read interest: one connection submits the read interest change, then runs the changes, finds that another connections is created, runs it, which schedule a read interest change, and so on. Now the code is simpler, and while we always offer to the queue, it may even be faster.
This commit is contained in:
parent
78dfd287e3
commit
ddca8bc327
|
@ -362,25 +362,11 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
*/
|
||||
public void submit(Runnable change)
|
||||
{
|
||||
if (isSelectorThread())
|
||||
{
|
||||
if (_state.get() == State.PROCESS)
|
||||
{
|
||||
// We are processing, so lets handle existing changes
|
||||
runChanges();
|
||||
// and then directly run the passed change without queueing it
|
||||
runChange(change);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We must be iterating in CHANGES or MORE_CHANGES
|
||||
// state, so just append to the queue to preserve order.
|
||||
_changes.offer(change);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise we have to queue the change and possibly wakeup the selector
|
||||
// This method may be called from the selector thread, and therefore
|
||||
// we could directly run the change without queueing, but this may
|
||||
// lead to stack overflows on a busy server, so we always offer the
|
||||
// change to the queue and process the state.
|
||||
|
||||
_changes.offer(change);
|
||||
LOG.debug("Queued change {}", change);
|
||||
|
||||
|
@ -414,7 +400,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runChanges()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue