Skip to content

Commit

Permalink
Merge pull request #3865 from katzyn/loom
Browse files Browse the repository at this point in the history
Add possibility to enable virtual worker threads in TCP, Web, and PG servers on Java 21+
  • Loading branch information
katzyn committed Aug 8, 2023
2 parents 752b246 + fd022b0 commit fcc5461
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 7 deletions.
4 changes: 4 additions & 0 deletions h2/pom.xml
Expand Up @@ -232,6 +232,10 @@
<directory>src/java10/precompiled</directory>
<targetPath>META-INF/versions/10</targetPath>
</resource>
<resource>
<directory>src/java21/precompiled</directory>
<targetPath>META-INF/versions/21</targetPath>
</resource>
</resources>
<testResources>
<testResource>
Expand Down
4 changes: 4 additions & 0 deletions h2/src/docsrc/html/changelog.html
Expand Up @@ -21,6 +21,10 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>RP #3865: Add possibility to enable virtual worker threads in TCP, Web, and PG servers on Java 21+
</li>
<li>PR #3864: Improve performance of TCP client driver when it is used from virtual threads
</li>
<li>Issue #2665: Parser shouldn't suggest compatibility syntax elements on parsing error
</li>
<li>Issue #3089: GREATEST and LEAST aren't fully compliant with the SQL Standard
Expand Down
Binary file added h2/src/java21/precompiled/org/h2/util/Utils21.class
Binary file not shown.
36 changes: 36 additions & 0 deletions h2/src/java21/src/org/h2/util/Utils21.java
@@ -0,0 +1,36 @@
/*
* Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;

import java.lang.Thread.Builder.OfVirtual;

/**
* Utilities with specialized implementations for Java 21 and later versions.
*
* This class contains basic implementations for older versions of Java and it
* is overridden in multi-release JARs.
*/
public final class Utils21 {

private static final OfVirtual VIRTUAL_THREAD_BUILDER = Thread.ofVirtual();

/**
* Creates a new virtual thread (on Java 21+) for the specified task. Use
* {@link Thread#start()} to schedule the thread to execute. On older
* versions of Java a platform daemon thread is created instead.
*
* @param task
* the object to run
* @return a new thread
*/
public static Thread newVirtualThread(Runnable task) {
return VIRTUAL_THREAD_BUILDER.unstarted(task);
}

private Utils21() {
}

}
14 changes: 14 additions & 0 deletions h2/src/java21/src/org/h2/util/package.html
@@ -0,0 +1,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
and the EPL 1.0 (https://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>

Internal utility classes reimplemented for Java 21 and later versions.

</p></body></html>
15 changes: 13 additions & 2 deletions h2/src/main/org/h2/server/TcpServer.java
Expand Up @@ -26,7 +26,9 @@
import org.h2.util.NetUtils;
import org.h2.util.StringUtils;
import org.h2.util.Tool;
import org.h2.util.Utils;
import org.h2.util.Utils10;
import org.h2.util.Utils21;

/**
* The TCP server implements the native H2 database server protocol.
Expand Down Expand Up @@ -62,6 +64,7 @@ public class TcpServer implements Service {
private boolean allowOthers;
private boolean isDaemon;
private boolean ifExists = true;
private boolean virtualThreads;
private JdbcConnection managementDb;
private PreparedStatement managementDbAdd;
private PreparedStatement managementDbRemove;
Expand Down Expand Up @@ -182,6 +185,8 @@ public void init(String... args) {
allowOthers = true;
} else if (Tool.isOption(a, "-tcpDaemon")) {
isDaemon = true;
} else if (Tool.isOption(a, "-tcpVirtualThreads")) {
virtualThreads = Utils.parseBoolean(args[++i], virtualThreads, true);
} else if (Tool.isOption(a, "-ifExists")) {
ifExists = true;
} else if (Tool.isOption(a, "-ifNotExists")) {
Expand Down Expand Up @@ -256,8 +261,14 @@ public void listen() {
int id = nextThreadId++;
TcpServerThread c = new TcpServerThread(s, this, id);
running.add(c);
Thread thread = new Thread(c, threadName + " thread-" + id);
thread.setDaemon(isDaemon);
Thread thread;
if (virtualThreads) {
thread = Utils21.newVirtualThread(c);
} else {
thread = new Thread(c);
thread.setDaemon(isDaemon);
}
thread.setName(threadName + " thread-" + id);
c.setThread(thread);
thread.start();
}
Expand Down
15 changes: 13 additions & 2 deletions h2/src/main/org/h2/server/pg/PgServer.java
Expand Up @@ -19,7 +19,9 @@
import org.h2.server.Service;
import org.h2.util.NetUtils;
import org.h2.util.Tool;
import org.h2.util.Utils;
import org.h2.util.Utils10;
import org.h2.util.Utils21;
import org.h2.value.TypeInfo;
import org.h2.value.Value;

Expand Down Expand Up @@ -79,6 +81,7 @@ public class PgServer implements Service {
private boolean allowOthers;
private boolean isDaemon;
private boolean ifExists = true;
private boolean virtualThreads;
private String key, keyDatabase;

@Override
Expand All @@ -97,6 +100,8 @@ public void init(String... args) {
allowOthers = true;
} else if (Tool.isOption(a, "-pgDaemon")) {
isDaemon = true;
} else if (Tool.isOption(a, "-pgVirtualThreads")) {
virtualThreads = Utils.parseBoolean(args[++i], virtualThreads, true);
} else if (Tool.isOption(a, "-ifExists")) {
ifExists = true;
} else if (Tool.isOption(a, "-ifNotExists")) {
Expand Down Expand Up @@ -197,8 +202,14 @@ public void listen() {
running.add(c);
int id = pid.incrementAndGet();
c.setProcessId(id);
Thread thread = new Thread(c, threadName + " thread-" + id);
thread.setDaemon(isDaemon);
Thread thread;
if (virtualThreads) {
thread = Utils21.newVirtualThread(c);
} else {
thread = new Thread(c);
thread.setDaemon(isDaemon);
}
thread.setName(threadName + " thread-" + id);
c.setThread(thread);
thread.start();
}
Expand Down
3 changes: 3 additions & 0 deletions h2/src/main/org/h2/server/web/WebServer.java
Expand Up @@ -177,6 +177,7 @@ public class WebServer implements Service {
private ShutdownHandler shutdownHandler;
private Thread listenerThread;
private boolean ifExists = true;
boolean virtualThreads;
private String key;
private boolean allowSecureCreation;
private boolean trace;
Expand Down Expand Up @@ -336,6 +337,8 @@ public void init(String... args) {
setExternalNames(args[++i]);
} else if (Tool.isOption(a, "-webDaemon")) {
isDaemon = true;
} else if (Tool.isOption(a, "-webVirtualThreads")) {
virtualThreads = Utils.parseBoolean(args[++i], virtualThreads, true);
} else if (Tool.isOption(a, "-baseDir")) {
String baseDir = args[++i];
SysProperties.setBaseDir(baseDir);
Expand Down
4 changes: 3 additions & 1 deletion h2/src/main/org/h2/server/web/WebThread.java
Expand Up @@ -25,6 +25,7 @@
import org.h2.util.NetworkConnectionInfo;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.util.Utils21;

/**
* For each connection to a session, an object of this class is created.
Expand All @@ -47,7 +48,8 @@ class WebThread extends WebApp implements Runnable {
WebThread(Socket socket, WebServer server) {
super(server);
this.socket = socket;
thread = new Thread(this, "H2 Console thread");
thread = server.virtualThreads ? Utils21.newVirtualThread(this) : new Thread(this);
thread.setName("H2 Console thread");
}

/**
Expand Down
6 changes: 6 additions & 0 deletions h2/src/main/org/h2/tools/Console.java
Expand Up @@ -117,6 +117,8 @@ public void runTool(String... args) throws SQLException {
i++;
} else if ("-webDaemon".equals(arg)) {
// no parameters
} else if ("-webVirtualThreads".equals(arg)) {
i++;
} else if ("-webSSL".equals(arg)) {
// no parameters
} else if ("-webPort".equals(arg)) {
Expand All @@ -140,6 +142,8 @@ public void runTool(String... args) throws SQLException {
// no parameters
} else if ("-tcpDaemon".equals(arg)) {
// no parameters
} else if ("-tcpVirtualThreads".equals(arg)) {
i++;
} else if ("-tcpSSL".equals(arg)) {
// no parameters
} else if ("-tcpPort".equals(arg)) {
Expand All @@ -163,6 +167,8 @@ public void runTool(String... args) throws SQLException {
// no parameters
} else if ("-pgDaemon".equals(arg)) {
// no parameters
} else if ("-pgVirtualThreads".equals(arg)) {
i++;
} else if ("-pgPort".equals(arg)) {
i++;
} else {
Expand Down
12 changes: 12 additions & 0 deletions h2/src/main/org/h2/tools/Server.java
Expand Up @@ -71,6 +71,8 @@ public Server(Service service, String... args) throws SQLException {
* used together with -webAllowOthers</td></tr>
* <tr><td>[-webDaemon]</td>
* <td>Use a daemon thread</td></tr>
* <tr><td>[-webVirtualThreads &lt;true|false&gt;]</td>
* <td>Use virtual threads (on Java 21+ only)</td></tr>
* <tr><td>[-webPort &lt;port&gt;]</td>
* <td>The port (default: 8082)</td></tr>
* <tr><td>[-webSSL]</td>
Expand All @@ -89,6 +91,8 @@ public Server(Service service, String... args) throws SQLException {
* <td>Allow other computers to connect - see below</td></tr>
* <tr><td>[-tcpDaemon]</td>
* <td>Use a daemon thread</td></tr>
* <tr><td>[-tcpVirtualThreads &lt;true|false&gt;]</td>
* <td>Use virtual threads (on Java 21+ only)</td></tr>
* <tr><td>[-tcpPort &lt;port&gt;]</td>
* <td>The port (default: 9092)</td></tr>
* <tr><td>[-tcpSSL]</td>
Expand All @@ -105,6 +109,8 @@ public Server(Service service, String... args) throws SQLException {
* <td>Allow other computers to connect - see below</td></tr>
* <tr><td>[-pgDaemon]</td>
* <td>Use a daemon thread</td></tr>
* <tr><td>[-pgVirtualThreads &lt;true|false&gt;]</td>
* <td>Use virtual threads (on Java 21+ only)</td></tr>
* <tr><td>[-pgPort &lt;port&gt;]</td>
* <td>The port (default: 5435)</td></tr>
* <tr><td>[-properties "&lt;dir&gt;"]</td>
Expand Down Expand Up @@ -148,6 +154,8 @@ private void verifyArgs(String... args) throws SQLException {
i++;
} else if ("-webDaemon".equals(arg)) {
// no parameters
} else if ("-webVirtualThreads".equals(arg)) {
i++;
} else if ("-webSSL".equals(arg)) {
// no parameters
} else if ("-webPort".equals(arg)) {
Expand All @@ -169,6 +177,8 @@ private void verifyArgs(String... args) throws SQLException {
// no parameters
} else if ("-tcpDaemon".equals(arg)) {
// no parameters
} else if ("-tcpVirtualThreads".equals(arg)) {
i++;
} else if ("-tcpSSL".equals(arg)) {
// no parameters
} else if ("-tcpPort".equals(arg)) {
Expand All @@ -189,6 +199,8 @@ private void verifyArgs(String... args) throws SQLException {
// no parameters
} else if ("-pgDaemon".equals(arg)) {
// no parameters
} else if ("-pgVirtualThreads".equals(arg)) {
i++;
} else if ("-pgPort".equals(arg)) {
i++;
} else {
Expand Down
40 changes: 40 additions & 0 deletions h2/src/main/org/h2/util/Utils21.java
@@ -0,0 +1,40 @@
/*
* Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;

/**
* Utilities with specialized implementations for Java 21 and later versions.
*
* This class contains basic implementations for older versions of Java and it
* is overridden in multi-release JARs.
*/
public final class Utils21 {

/*
* Signatures of methods should match with
* h2/src/java21/src/org/h2/util/Utils21.java and precompiled
* h2/src/java21/precompiled/org/h2/util/Utils21.class.
*/

/**
* Creates a new virtual thread (on Java 21+) for the specified task. Use
* {@link Thread#start()} to schedule the thread to execute. On older
* versions of Java a platform daemon thread is created instead.
*
* @param task
* the object to run
* @return a new thread
*/
public static Thread newVirtualThread(Runnable task) {
Thread thread = new Thread(task);
thread.setDaemon(true);
return thread;
}

private Utils21() {
}

}
2 changes: 1 addition & 1 deletion h2/src/main/org/h2/value/Value.java
Expand Up @@ -2711,7 +2711,7 @@ public boolean containsNull() {
* Scans this and specified values until a first NULL occurrence and returns
* a value where NULL appears earlier, or {@code null} if these two values
* have first NULL on the same position.
*
*
* @param v
* a value of the same data type as this value, must be neither
* equal to nor smaller than nor greater than this value
Expand Down
4 changes: 4 additions & 0 deletions h2/src/tools/org/h2/build/Build.java
Expand Up @@ -557,6 +557,7 @@ private FileList excludeTestMetaInfFiles(FileList files) {
private void addVersions() {
copy("temp/META-INF/versions/9", files("src/java9/precompiled"), "src/java9/precompiled");
copy("temp/META-INF/versions/10", files("src/java10/precompiled"), "src/java10/precompiled");
copy("temp/META-INF/versions/21", files("src/java21/precompiled"), "src/java21/precompiled");
}

/**
Expand Down Expand Up @@ -922,6 +923,9 @@ private void test(boolean ci) {
cp = "src/java9/precompiled" + File.pathSeparator + cp;
if (version >= 10) {
cp = "src/java10/precompiled" + File.pathSeparator + cp;
if (version >= 21) {
cp = "src/java21/precompiled" + File.pathSeparator + cp;
}
}
}
int ret;
Expand Down
2 changes: 1 addition & 1 deletion h2/src/tools/org/h2/build/doc/dictionary.txt
Expand Up @@ -855,4 +855,4 @@ duplicating unnested hardening sticky massacred
bck clo cur hwm materializedview udca vol connectionpooldatasource xadatasource
ampm sssssff sstzh tzs yyyysssss newsequentialid solidus openjdk furthermore ssff secons nashorn fractions
btrim underscores ffl decomposed decomposition subfield infinities retryable salted establish
hatchet fis loom birthdate penrosed eve graalvm roberto polyglot truffle scriptengine
hatchet fis loom birthdate penrosed eve graalvm roberto polyglot truffle scriptengine unstarted

0 comments on commit fcc5461

Please sign in to comment.