From 4883378028621712f196065bcd6f2a0f720c3b71 Mon Sep 17 00:00:00 2001 From: warunalakshitha Date: Tue, 8 Oct 2024 16:34:39 +0530 Subject: [PATCH 1/2] Fix profiler test --- .../ballerina/runtime/internal/scheduling/AsyncUtils.java | 2 +- .../java/org/ballerinalang/test/profiler/ProfilerTest.java | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java index 52372ab0e2b6..2ec4586d1860 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java @@ -40,10 +40,10 @@ public class AsyncUtils { public static Object handleNonIsolatedStrand(Strand strand, Supplier resultSupplier) { + // This check required for non strand Threads. boolean runnable = strand.isRunnable(); if (runnable) { strand.yield(); - } Object result = resultSupplier.get(); if (runnable) { diff --git a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/profiler/ProfilerTest.java b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/profiler/ProfilerTest.java index b75810e7b066..a4f7a40658a0 100644 --- a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/profiler/ProfilerTest.java +++ b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/profiler/ProfilerTest.java @@ -137,8 +137,11 @@ public void testProfilerExecutionWithKillSignal() throws BallerinaTestException bMainInstance.waitForLeechers(List.of(beforeExecleechers), 20000); addLogLeechers(afterExecleechers, serverInfoLogReader); Thread.sleep(5000); - long processId = process.pid(); - Runtime.getRuntime().exec("kill -SIGINT " + processId); + ProcessHandle profilerHandle = process.children().findFirst().get().children().findFirst().get(); + long profileId = profilerHandle.pid(); + long balProcessID = profilerHandle.children().findFirst().get().pid(); + Runtime.getRuntime().exec("kill -SIGINT " + balProcessID); + Runtime.getRuntime().exec("kill -SIGINT " + profileId); bMainInstance.waitForLeechers(List.of(afterExecleechers), 20000); process.waitFor(); } catch (InterruptedException | IOException e) { From 3c4094e24b9919da44b064530ed715758ffd7e9f Mon Sep 17 00:00:00 2001 From: warunalakshitha Date: Fri, 11 Oct 2024 15:04:23 +0530 Subject: [PATCH 2/2] Fix strand hang with daemon strand --- .../src/main/java/io/ballerina/runtime/api/Environment.java | 5 +++-- .../java/io/ballerina/runtime/internal/BalEnvironment.java | 5 +++-- .../java/io/ballerina/runtime/internal/lock/BLockStore.java | 2 -- .../io/ballerina/runtime/internal/scheduling/Scheduler.java | 5 ++++- .../io/ballerina/runtime/internal/scheduling/Strand.java | 3 +-- .../main/java/org/ballerinalang/langlib/runtime/Sleep.java | 1 + .../java/org/ballerinalang/test/utils/interop/Utils.java | 1 + 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java index 36abefb03c36..badd1b09ccdb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java @@ -21,6 +21,7 @@ import io.ballerina.runtime.api.types.Parameter; import java.util.Optional; +import java.util.function.Supplier; /** * When this class is used as the first argument of an interop method, Ballerina will inject an instance of @@ -47,9 +48,9 @@ public abstract class Environment { /** * Yield the current execution and run some operation so other non isolated functions can run in asynchronously. * - * @param runnable operation to be executed. + * @param supplier operation to be executed. */ - public abstract void yieldAndRun(Runnable runnable); + public abstract Object yieldAndRun(Supplier supplier); /** * Gets an instance of Ballerina runtime. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java index d0f54c8d8bd4..7ac90bfa6bf7 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java @@ -26,6 +26,7 @@ import io.ballerina.runtime.internal.scheduling.Strand; import java.util.Optional; +import java.util.function.Supplier; /** * When {@link Environment} is used as the first argument of an interop method, Ballerina will inject an instance @@ -69,10 +70,10 @@ public Parameter[] getFunctionPathParameters() { } @Override - public void yieldAndRun(Runnable runnable) { + public Object yieldAndRun(Supplier supplier) { try { strand.yield(); - runnable.run(); + return supplier.get(); } finally { strand.resume(); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/lock/BLockStore.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/lock/BLockStore.java index e5f13f8a4cca..a0d173d5d72a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/lock/BLockStore.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/lock/BLockStore.java @@ -51,10 +51,8 @@ public BLockStore() { */ @SuppressWarnings("unused") public void lock(Strand strand, String lockName) { - strand.yield(); getLockFromMap(lockName).lock(); strand.acquiredLockCount++; - strand.resume(); } /* diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java index 1cedbb3291b2..15cb8415f534 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java @@ -72,7 +72,10 @@ public static Strand getStrand() { if (strand != null) { return strand; } - return daemonStrand; + if (daemonStrand == null) { + return null; + } + return new Strand(null, null, daemonStrand.scheduler, daemonStrand, false, null, null); } public Object call(Module module, String functionName, Strand parentStrand, Object... args) { boolean runnable = parentStrand.isRunnable(); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java index ce9cac2f054b..c876dcfa3d74 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java @@ -91,7 +91,6 @@ public void resume() { checkStrandCancelled(); if (!this.isIsolated && !scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { this.scheduler.globalNonIsolatedLock.lock(); - } } @@ -103,7 +102,7 @@ public void yield() { } public void done() { - if (!isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { + if (!this.isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { scheduler.globalNonIsolatedLock.unlock(); } } diff --git a/langlib/lang.runtime/src/main/java/org/ballerinalang/langlib/runtime/Sleep.java b/langlib/lang.runtime/src/main/java/org/ballerinalang/langlib/runtime/Sleep.java index a5f74d6f322e..6c24bea95c43 100644 --- a/langlib/lang.runtime/src/main/java/org/ballerinalang/langlib/runtime/Sleep.java +++ b/langlib/lang.runtime/src/main/java/org/ballerinalang/langlib/runtime/Sleep.java @@ -49,6 +49,7 @@ public static void sleep(Environment env, BDecimal delaySeconds) { env.yieldAndRun(() -> { try { Thread.sleep(delay); + return null; } catch (InterruptedException e) { throw ErrorCreator.createError(StringUtils.fromString("error occurred during sleep"), e); } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/utils/interop/Utils.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/utils/interop/Utils.java index 4096d13146a2..6f033d47dfda 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/utils/interop/Utils.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/utils/interop/Utils.java @@ -35,6 +35,7 @@ public static void sleep(Environment env, long delayMillis) { env.yieldAndRun(() -> { try { Thread.sleep(delayMillis); + return null; } catch (InterruptedException e) { throw ErrorCreator.createError(e); }