Merge pull request #4101 from eclipse/jetty-9.4.x-4096-ReservedThreadExecutor_stop

Issue #4096 - allow thread to exit ReservedThreadExecutor on stop
This commit is contained in:
Lachlan 2019-10-01 15:44:37 +10:00 committed by GitHub
commit 4fff51361d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 12 deletions

View File

@ -155,6 +155,7 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
public void doStart() throws Exception
{
_lease = ThreadPoolBudget.leaseFrom(getExecutor(), this, _capacity);
_size.set(0);
super.doStart();
}
@ -163,15 +164,29 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
{
if (_lease != null)
_lease.close();
super.doStop();
while (true)
{
int size = _size.get();
// If no reserved threads left try setting size to -1 to
// atomically prevent other threads adding themselves to stack.
if (size == 0 && _size.compareAndSet(size, -1))
break;
ReservedThread thread = _stack.pollFirst();
if (thread == null)
break;
{
// Reserved thread must have incremented size but not yet added itself to queue.
// We will spin until it is added.
Thread.yield(); // TODO: use Thread.onSpinWait() in jetty-10
continue;
}
_size.decrementAndGet();
thread.stop();
}
super.doStop();
}
@Override
@ -276,11 +291,12 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
if (LOG.isDebugEnabled())
LOG.debug("{} waiting", this);
Runnable task = null;
while (task == null)
while (true)
{
boolean idle = false;
if (!isRunning())
return STOP;
boolean idle = false;
try (Locker.Lock lock = _locker.lock())
{
if (_task == null)
@ -297,8 +313,16 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
LOG.ignore(e);
}
}
task = _task;
_task = null;
else
{
Runnable task = _task;
_task = null;
if (LOG.isDebugEnabled())
LOG.debug("{} task={}", this, task);
return task;
}
}
if (idle)
@ -313,11 +337,6 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
tryExecute(STOP);
}
}
if (LOG.isDebugEnabled())
LOG.debug("{} task={}", this, task);
return task;
}
@Override
@ -330,6 +349,8 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
while (true)
{
int size = _size.get();
if (size < 0)
return;
if (size >= _capacity)
{
if (LOG.isDebugEnabled())