diff options
author | Morten Tokle <mortent@yahooinc.com> | 2023-05-30 09:55:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-30 09:55:43 +0200 |
commit | f7b4da0a647a82b488c3b1ea81e74d6de3ba389a (patch) | |
tree | 596b679f247b90f3a981c7eb15d5b7e5b2c51aa7 | |
parent | 06b722e43cdf32f859cca46a3e85dede876a97e9 (diff) | |
parent | 9991a10b1325f2f34a6ac833e468ff0173bb412b (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.java | 17 |
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(); |