mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Repeatedly check status while trying to lock for shutdown
Closes gh-36260
This commit is contained in:
+28
-7
@@ -27,6 +27,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -1070,11 +1071,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isStartupShutdownThreadStuck()) {
|
||||
active.set(false);
|
||||
if (!tryLockForShutdown()) {
|
||||
return;
|
||||
}
|
||||
startupShutdownLock.lock();
|
||||
try {
|
||||
doClose();
|
||||
}
|
||||
@@ -1087,6 +1086,30 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to acquire the common startup/shutdown lock, backing out if
|
||||
* the main startup/shutdown thread is stuck or on interruption.
|
||||
* @see #isStartupShutdownThreadStuck()
|
||||
*/
|
||||
private boolean tryLockForShutdown() {
|
||||
try {
|
||||
while (!this.startupShutdownLock.tryLock(100, TimeUnit.MILLISECONDS)) {
|
||||
if (!this.active.get() || this.closed.get()) {
|
||||
return false;
|
||||
}
|
||||
if (isStartupShutdownThreadStuck()) {
|
||||
this.active.set(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether an active startup/shutdown thread is currently stuck,
|
||||
* for example, through a {@code System.exit} call in a user component.
|
||||
@@ -1098,7 +1121,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
activeThread.interrupt();
|
||||
try {
|
||||
// Leave just a little bit of time for the interruption to show effect
|
||||
Thread.sleep(1);
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
@@ -1120,12 +1143,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
if (isStartupShutdownThreadStuck()) {
|
||||
this.active.set(false);
|
||||
if (!tryLockForShutdown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startupShutdownLock.lock();
|
||||
try {
|
||||
this.startupShutdownThread = Thread.currentThread();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user