Issue #3361 thread safe addHandler

Updates from review:
 - no return from finally

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2019-03-21 10:31:08 +11:00
parent 265afacd3f
commit 944636176f
1 changed files with 12 additions and 10 deletions

View File

@ -37,17 +37,17 @@ import org.eclipse.jetty.util.log.Log;
*/ */
public class SerializedExecutor implements Executor public class SerializedExecutor implements Executor
{ {
private final AtomicReference<Link> _last = new AtomicReference<>(); final AtomicReference<Link> _tail = new AtomicReference<>();
@Override @Override
public void execute(Runnable task) public void execute(Runnable task)
{ {
Link link = new Link(task); Link link = new Link(task);
Link secondLast = _last.getAndSet(link); Link lastButOne = _tail.getAndSet(link);
if (secondLast==null) if (lastButOne==null)
run(link); run(link);
else else
secondLast._next.lazySet(link); lastButOne._next.lazySet(link);
} }
protected void onError(Runnable task, Throwable t) protected void onError(Runnable task, Throwable t)
@ -57,7 +57,7 @@ public class SerializedExecutor implements Executor
private void run(Link link) private void run(Link link)
{ {
while(true) while(link!=null)
{ {
try try
{ {
@ -69,10 +69,12 @@ public class SerializedExecutor implements Executor
} }
finally finally
{ {
// Are we are not the current last Link? // Are we the current the last Link?
if (!_last.compareAndSet(link, null)) if (_tail.compareAndSet(link, null))
link = null;
else
{ {
// continue running the list, but may need to wait for the next link // not the last task, so its next link will eventually be set
Link next = link._next.get(); Link next = link._next.get();
while (next == null) while (next == null)
{ {
@ -87,8 +89,8 @@ public class SerializedExecutor implements Executor
private class Link private class Link
{ {
private final Runnable _task; final Runnable _task;
private final AtomicReference<Link> _next = new AtomicReference<>(); final AtomicReference<Link> _next = new AtomicReference<>();
public Link(Runnable task) public Link(Runnable task)
{ {