From d178a7404f8ed3896dbf7b72826aa8ec2438ee61 Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Fri, 25 Aug 2023 09:47:15 -0500 Subject: [PATCH] Allow reaper threads to be started at run time --- ref/pom.xml | 4 ++ .../smallrye/common/ref/PhantomReference.java | 2 +- .../io/smallrye/common/ref/References.java | 46 ++++++++++++++----- .../io/smallrye/common/ref/SoftReference.java | 2 +- .../io/smallrye/common/ref/WeakReference.java | 2 +- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/ref/pom.xml b/ref/pom.xml index 44ef7736..a7ddac7a 100644 --- a/ref/pom.xml +++ b/ref/pom.xml @@ -17,6 +17,10 @@ ${project.groupId} smallrye-common-constraint + + org.graalvm.sdk + graal-sdk + diff --git a/ref/src/main/java/io/smallrye/common/ref/PhantomReference.java b/ref/src/main/java/io/smallrye/common/ref/PhantomReference.java index 67722743..d7a13321 100644 --- a/ref/src/main/java/io/smallrye/common/ref/PhantomReference.java +++ b/ref/src/main/java/io/smallrye/common/ref/PhantomReference.java @@ -36,7 +36,7 @@ public PhantomReference(final T referent, final A attachment, final ReferenceQue * @param reaper the reaper to use */ public PhantomReference(final T referent, final A attachment, final Reaper reaper) { - super(referent, References.ReaperThread.REAPER_QUEUE); + super(referent, References.ReaperThread.getReaperQueue()); this.reaper = reaper; this.attachment = attachment; } diff --git a/ref/src/main/java/io/smallrye/common/ref/References.java b/ref/src/main/java/io/smallrye/common/ref/References.java index 1ac18f1b..52a626e0 100644 --- a/ref/src/main/java/io/smallrye/common/ref/References.java +++ b/ref/src/main/java/io/smallrye/common/ref/References.java @@ -6,6 +6,8 @@ import java.security.PrivilegedAction; import java.util.concurrent.atomic.AtomicInteger; +import org.graalvm.nativeimage.ImageInfo; + import io.smallrye.common.constraint.Assert; /** @@ -17,27 +19,47 @@ private References() { private static final Reference NULL = new StrongReference<>(null); - static final class ReaperThread extends Thread { + static final class BuildTimeHolder { static final ReferenceQueue REAPER_QUEUE = new ReferenceQueue(); + } + + static final class ReaperThread extends Thread { + static ReferenceQueue getReaperQueue() { + return BuildTimeHolder.REAPER_QUEUE; + } static { - final AtomicInteger cnt = new AtomicInteger(1); - final PrivilegedAction action = () -> { - final ReaperThread thr = new ReaperThread(); - thr.setName("Reference Reaper #" + cnt.getAndIncrement()); - thr.setDaemon(true); - thr.start(); - return null; - }; - for (int i = 0; i < 3; i++) { - doPrivileged(action); + if (isBuildTime()) { + // do nothing (class should be reinitialized) + } else { + final AtomicInteger cnt = new AtomicInteger(1); + final PrivilegedAction action = () -> startThreadAction(cnt.getAndIncrement()); + for (int i = 0; i < 3; i++) { + doPrivileged(action); + } + } + } + + private static boolean isBuildTime() { + try { + return ImageInfo.inImageBuildtimeCode(); + } catch (Throwable ignored) { + return false; } } + private static Void startThreadAction(int id) { + final ReaperThread thr = new ReaperThread(); + thr.setName("Reference Reaper #" + id); + thr.setDaemon(true); + thr.start(); + return null; + } + public void run() { for (;;) try { - final java.lang.ref.Reference ref = REAPER_QUEUE.remove(); + final java.lang.ref.Reference ref = ReaperThread.getReaperQueue().remove(); if (ref instanceof CleanerReference) { ((CleanerReference) ref).clean(); } diff --git a/ref/src/main/java/io/smallrye/common/ref/SoftReference.java b/ref/src/main/java/io/smallrye/common/ref/SoftReference.java index 93b82209..211a1d05 100644 --- a/ref/src/main/java/io/smallrye/common/ref/SoftReference.java +++ b/ref/src/main/java/io/smallrye/common/ref/SoftReference.java @@ -55,7 +55,7 @@ public SoftReference(final T referent, final A attachment, final ReferenceQueue< * @param reaper the reaper to use */ public SoftReference(final T referent, final A attachment, final Reaper reaper) { - super(referent, References.ReaperThread.REAPER_QUEUE); + super(referent, References.ReaperThread.getReaperQueue()); this.reaper = reaper; this.attachment = attachment; } diff --git a/ref/src/main/java/io/smallrye/common/ref/WeakReference.java b/ref/src/main/java/io/smallrye/common/ref/WeakReference.java index 688970a2..fc7c33f6 100644 --- a/ref/src/main/java/io/smallrye/common/ref/WeakReference.java +++ b/ref/src/main/java/io/smallrye/common/ref/WeakReference.java @@ -55,7 +55,7 @@ public WeakReference(final T referent, final A attachment, final ReferenceQueue< * @param reaper the reaper to use */ public WeakReference(final T referent, final A attachment, final Reaper reaper) { - super(referent, References.ReaperThread.REAPER_QUEUE); + super(referent, References.ReaperThread.getReaperQueue()); this.attachment = attachment; this.reaper = reaper; }