diff --git a/langlib/lang.__internal/src/main/java/org/ballerinalang/langlib/internal/WorkerChannels.java b/langlib/lang.__internal/src/main/java/org/ballerinalang/langlib/internal/WorkerChannels.java index f42dced134ac..537ef1bb2c66 100644 --- a/langlib/lang.__internal/src/main/java/org/ballerinalang/langlib/internal/WorkerChannels.java +++ b/langlib/lang.__internal/src/main/java/org/ballerinalang/langlib/internal/WorkerChannels.java @@ -22,6 +22,8 @@ import io.ballerina.runtime.internal.scheduling.Strand; import io.ballerina.runtime.internal.scheduling.WorkerDataChannel; +import java.util.Objects; + /** * Native implementation of lang.internal:WorkerChannels. * @@ -35,10 +37,11 @@ public class WorkerChannels { * @param channelIds channel IDs of the channels to be closed */ public static void autoClose(BString[] channelIds) { - Strand parent = Scheduler.getStrand().parent; + Strand currentStrand = Scheduler.getStrand(); + Strand channelHoldingStrand = Objects.requireNonNullElse(currentStrand.parent, currentStrand); for (BString channelId : channelIds) { - String channelName = channelId.getValue() + ":" + (parent.functionInvocation - 1); - WorkerDataChannel workerDataChannel = parent.wdChannels.getWorkerDataChannel(channelName); + String channelName = channelId.getValue() + ":" + (channelHoldingStrand.functionInvocation - 1); + WorkerDataChannel workerDataChannel = channelHoldingStrand.wdChannels.getWorkerDataChannel(channelName); workerDataChannel.autoClose(); } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/ForkInFunctionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/ForkInFunctionTest.java index d233550019dc..99c953ec107d 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/ForkInFunctionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/worker/ForkInFunctionTest.java @@ -63,4 +63,12 @@ public void testForkWithWorkersInSameFunction() { long returnInt = (long) returns; Assert.assertEquals(returnInt, 10); } + + @Test(description = "Test fork within if condition") + public void testForkWithinIfCondition() { + CompileResult result = BCompileUtil.compile("test-src/workers/fork-within-if-condition.bal"); + Object returns = BRunUtil.invoke(result, "testForkWithinIfCondition"); + Assert.assertTrue(returns instanceof Long); + Assert.assertEquals(((Long) returns).intValue(), 1); + } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/workers/fork-within-if-condition.bal b/tests/jballerina-unit-test/src/test/resources/test-src/workers/fork-within-if-condition.bal new file mode 100644 index 000000000000..35ea5d0e30e3 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/workers/fork-within-if-condition.bal @@ -0,0 +1,34 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +function testForkWithinIfCondition() returns int { + boolean isForked = false; + if isForked { + fork { + worker A { + 5 -> B; + string value = <- B; + } + + worker B { + int value = <- A; + "a" -> A; + } + } + return 0; + } + return 1; +}