This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new f9fb4f443d Fix NIO2 and virtual threads (NIO2 requires ExecutorService)
f9fb4f443d is described below

commit f9fb4f443d5c6814445a42174288ae549abc83ec
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Dec 8 10:26:49 2023 +0000

    Fix NIO2 and virtual threads (NIO2 requires ExecutorService)
---
 .../tomcat/util/threads/LocalStrings.properties    |  2 +
 .../tomcat/util/threads/VirtualThreadExecutor.java | 63 +++++++++++++++++++++-
 webapps/docs/changelog.xml                         |  9 ++++
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/threads/LocalStrings.properties 
b/java/org/apache/tomcat/util/threads/LocalStrings.properties
index 4b28c96f84..e6999e19e4 100644
--- a/java/org/apache/tomcat/util/threads/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/threads/LocalStrings.properties
@@ -19,3 +19,5 @@ threadPoolExecutor.invalidKeepAlive=Core threads must have 
positive keep alive t
 threadPoolExecutor.queueFull=Queue capacity is full
 threadPoolExecutor.taskRejected=Task [{0}] rejected from [{1}]
 threadPoolExecutor.threadStoppedToAvoidPotentialLeak=Stopping thread [{0}] to 
avoid potential memory leaks after a context was stopped.
+
+vvirtualThreadExecutor.taskRejected=Task [{0}] rejected from [{1}]
\ No newline at end of file
diff --git a/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java 
b/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java
index 0e177fe861..461d16e05f 100644
--- a/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java
+++ b/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java
@@ -16,12 +16,23 @@
  */
 package org.apache.tomcat.util.threads;
 
-import java.util.concurrent.Executor;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tomcat.util.res.StringManager;
 
 /**
  * An executor that uses a new virtual thread for each task.
  */
-public class VirtualThreadExecutor implements Executor {
+public class VirtualThreadExecutor extends AbstractExecutorService {
+
+    private static final StringManager sm = 
StringManager.getManager(VirtualThreadExecutor.class);
+
+    private CountDownLatch shutdown = new CountDownLatch(1);
 
     private Thread.Builder threadBuilder;
 
@@ -31,6 +42,54 @@ public class VirtualThreadExecutor implements Executor {
 
     @Override
     public void execute(Runnable command) {
+        if (isShutdown()) {
+            throw new RejectedExecutionException(
+                    sm.getString("virtualThreadExecutor.taskRejected", 
command.toString(), this.toString()));
+        }
         threadBuilder.start(command);
     }
+
+    @Override
+    public void shutdown() {
+        shutdown.countDown();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The VirtualThreadExecutor does not track in-progress tasks so calling 
this method is equivalent to calling
+     * {@link #shutdown()}.
+     */
+    @Override
+    public List<Runnable> shutdownNow() {
+        shutdown();
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean isShutdown() {
+        return shutdown.getCount() == 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The VirtualThreadExecutor does not track in-progress tasks so calling 
this method is equivalent to calling
+     * {@link #isShutdown()}.
+     */
+    @Override
+    public boolean isTerminated() {
+        return isShutdown();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The VirtualThreadExecutor does not track in-progress tasks so calling 
this method is effectively waiting for
+     * {@link #shutdown()} to be called.
+     */
+    @Override
+    public boolean awaitTermination(long timeout, TimeUnit unit) throws 
InterruptedException {
+        return shutdown.await(timeout, unit);
+    }
 }
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 75f8106c27..73b9aaca03 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,15 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 11.0.0-M16 (markt)" rtext="in development">
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Refactor the <code>VirtualThreadExecutor</code> so that it can be used
+        by the NIO2 connector which was using platform threads even when
+        configured to use virtual threads. (markt)
+      </fix>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 11.0.0-M15 (markt)" rtext="release in progress">
   <subsection name="Catalina">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to