jetty-9: changed the way changes are run.
Before: changes were submitted, but if this happened in the selector thread, then they were executed immediately. This lead to recursion: the run of a change submitted another change, which was run, which submitted a change, etc. To avoid StackOverFlowException, a ForkInvoker was used, breaking the stack after 4 recursive calls. The reason for this was to avoid to queue a change that could have been run in place, but costs probably it costs more than what it saves. Current: changes are now always queued. This avoids recursion and the need for a ForkInvoker, making the code simpler. Instead of recursing we now iterate over the queue of changes.
This commit is contained in:
parent
8253a31614
commit
84a1cff26e
|
@ -40,7 +40,6 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.util.ForkInvoker;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -303,7 +302,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
*/
|
||||
public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dumpable
|
||||
{
|
||||
private final ForkInvoker<Runnable> invoker = new ManagedSelectorInvoker();
|
||||
private final Queue<Runnable> _changes = new ConcurrentLinkedQueue<>();
|
||||
private final int _id;
|
||||
private Selector _selector;
|
||||
|
@ -335,16 +333,18 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
|
||||
/**
|
||||
* <p>Submits a change to be executed in the selector thread.</p>
|
||||
* <p>Changes may be submitted from any thread, and if they are submitted from a thread different
|
||||
* from the selector thread, they are queued for execution, and the selector thread woken up
|
||||
* <p>Changes may be submitted from any thread, and the selector thread woken up
|
||||
* (if necessary) to execute the change.</p>
|
||||
*
|
||||
* @param change the change to submit
|
||||
* @return true if the change has been executed, false if it has been queued for later execution
|
||||
*/
|
||||
public boolean submit(Runnable change)
|
||||
public void submit(Runnable change)
|
||||
{
|
||||
return !invoker.invoke(change);
|
||||
_changes.offer(change);
|
||||
LOG.debug("Queued change {}", change);
|
||||
boolean wakeup = _needsWakeup;
|
||||
if (wakeup)
|
||||
wakeup();
|
||||
}
|
||||
|
||||
private void runChanges()
|
||||
|
@ -534,8 +534,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
|
||||
public void destroyEndPoint(EndPoint endPoint)
|
||||
{
|
||||
// TODO
|
||||
|
||||
LOG.debug("Destroyed {}", endPoint);
|
||||
Connection connection = endPoint.getConnection();
|
||||
if (connection != null)
|
||||
|
@ -606,38 +604,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
|
|||
selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1);
|
||||
}
|
||||
|
||||
private class ManagedSelectorInvoker extends ForkInvoker<Runnable>
|
||||
{
|
||||
private ManagedSelectorInvoker()
|
||||
{
|
||||
super(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean condition()
|
||||
{
|
||||
return Thread.currentThread() != _thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fork(Runnable change)
|
||||
{
|
||||
_changes.offer(change);
|
||||
LOG.debug("Queued change {}", change);
|
||||
boolean wakeup = _needsWakeup;
|
||||
if (wakeup)
|
||||
wakeup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(Runnable change)
|
||||
{
|
||||
LOG.debug("Submitted change {}", change);
|
||||
runChanges();
|
||||
runChange(change);
|
||||
}
|
||||
}
|
||||
|
||||
private class DumpKeys implements Runnable
|
||||
{
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
|
Loading…
Reference in New Issue