aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Tokle <mortent@yahooinc.com>2023-05-30 09:55:43 +0200
committerGitHub <noreply@github.com>2023-05-30 09:55:43 +0200
commitf7b4da0a647a82b488c3b1ea81e74d6de3ba389a (patch)
tree596b679f247b90f3a981c7eb15d5b7e5b2c51aa7
parent06b722e43cdf32f859cca46a3e85dede876a97e9 (diff)
parent9991a10b1325f2f34a6ac833e468ff0173bb412b (diff)
Merge pull request #27216 from vespa-engine/bjorncs/thread-watchdog
Detect stale threads from context classloader
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java17
1 files changed, 14 insertions, 3 deletions
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java
index f28d5ea2b26..09e52beba59 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ContainerWatchdog.java
@@ -160,8 +160,15 @@ class ContainerWatchdog implements ContainerWatchdogMetrics, AutoCloseable {
record ThreadDetails(Thread thread, Bundle bundle) {}
List<ThreadDetails> staleThreads = new ArrayList<>();
for (Thread t : threads) {
+ // Find threads with context classloader from an uninstalled bundle
+ Bundle b = isClassloaderForUninstalledBundle(t.getContextClassLoader()).orElse(null);
+ if (b != null) {
+ staleThreads.add(new ThreadDetails(t, b));
+ continue;
+ }
+
// Find threads which are sub-classes of java.lang.Thread from an uninstalled bundle
- Bundle b = hasClassloaderForUninstalledBundle(t).orElse(null);
+ b = hasClassloaderForUninstalledBundle(t).orElse(null);
if (b != null) {
staleThreads.add(new ThreadDetails(t, b));
continue;
@@ -201,8 +208,12 @@ class ContainerWatchdog implements ContainerWatchdogMetrics, AutoCloseable {
}
private static Optional<Bundle> hasClassloaderForUninstalledBundle(Object o) {
- if (o.getClass().getClassLoader() instanceof BundleWiringImpl.BundleClassLoader cl) {
- Bundle b = cl.getBundle();
+ return isClassloaderForUninstalledBundle(o.getClass().getClassLoader());
+ }
+
+ private static Optional<Bundle> isClassloaderForUninstalledBundle(ClassLoader cl) {
+ if (cl instanceof BundleWiringImpl.BundleClassLoader bcl) {
+ Bundle b = bcl.getBundle();
if (b.getState() == Bundle.UNINSTALLED) return Optional.of(b);
}
return Optional.empty();