From 2ff7988251716c7e748e7754fed6b2f706fd558f Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 17 Dec 2019 14:41:47 -0400 Subject: [PATCH] resolved joins from main thread as illegal --- .../java/carpet/script/CarpetExpression.java | 15 +++++++-- src/main/java/carpet/script/Expression.java | 12 +++++-- .../java/carpet/script/value/ThreadValue.java | 33 +++---------------- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index e5a27ac0..ea198f30 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -10,6 +10,7 @@ import carpet.script.exception.CarpetExpressionException; import carpet.script.exception.ExitStatement; import carpet.script.exception.ExpressionException; import carpet.script.exception.InternalExpressionException; +import carpet.CarpetSettings; import carpet.script.value.BlockValue; import carpet.script.value.EntityValue; import carpet.script.value.FunctionValue; @@ -19,8 +20,8 @@ import carpet.script.value.NBTSerializableValue; import carpet.script.value.NullValue; import carpet.script.value.NumericValue; import carpet.script.value.StringValue; +import carpet.script.value.ThreadValue; import carpet.script.value.Value; -import carpet.CarpetSettings; import carpet.utils.BlockInfo; import carpet.utils.Messenger; import com.google.common.collect.Sets; @@ -101,7 +102,6 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -3006,6 +3006,17 @@ public class CarpetExpression return (_c, _t) -> res; // pass through for variables }); + //"overidden" native call to cancel if on main thread + this.expr.addLazyFunction("join_task", 1, (c, t, lv) -> { + if (((CarpetContext)c).s.getMinecraftServer().isOnThread()) + throw new InternalExpressionException("'join_task' cannot be called from main thread to avoid deadlocks"); + Value v = lv.get(0).evalValue(c); + if (!(v instanceof ThreadValue)) + throw new InternalExpressionException("'join_task' could only be used with a task value"); + Value ret = ((ThreadValue) v).join(); + return (_c, _t) -> ret; + }); + this.expr.addLazyFunction("logger", 1, (c, t, lv) -> { Value res = lv.get(0).evalValue(c); diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 9af5fa2f..facb3504 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -11,7 +11,13 @@ import carpet.script.Fluff.QuadFunction; import carpet.script.Fluff.QuinnFunction; import carpet.script.Fluff.SexFunction; import carpet.script.Fluff.TriFunction; -import carpet.script.exception.*; +import carpet.script.exception.BreakStatement; +import carpet.script.exception.ContinueStatement; +import carpet.script.exception.ExitStatement; +import carpet.script.exception.ExpressionException; +import carpet.script.exception.InternalExpressionException; +import carpet.script.exception.ReturnStatement; +import carpet.script.exception.ThrowStatement; import carpet.script.value.AbstractListValue; import carpet.script.value.ContainerValueInterface; import carpet.script.value.FunctionSignatureValue; @@ -3040,12 +3046,12 @@ public class Expression implements Cloneable return ((ThreadValue) v).join(); }); - addUnaryFunction("stop_task", (v) -> { + /*addUnaryFunction("stop_task", (v) -> { if (!(v instanceof ThreadValue)) throw new InternalExpressionException("'join_task' could only be used with a task value"); ((ThreadValue) v).stop(); return Value.NULL; - }); + });*/ addUnaryFunction("is_task_completed", (v) -> { if (!(v instanceof ThreadValue)) diff --git a/src/main/java/carpet/script/value/ThreadValue.java b/src/main/java/carpet/script/value/ThreadValue.java index 382cd6b2..667e087a 100644 --- a/src/main/java/carpet/script/value/ThreadValue.java +++ b/src/main/java/carpet/script/value/ThreadValue.java @@ -12,36 +12,24 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; -import java.util.function.Supplier; public class ThreadValue extends Value { private CompletableFuture taskFuture; private long id; private final Object lock; - private final boolean[] started; - private Suppliertask; private static long sequence = 0L; - private static final Map executorServices = new HashMap<>(); public ThreadValue(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx) { id = sequence++; lock = new Object(); - started = new boolean[]{false}; - task = () -> - { - if (!started[0]) - { - started[0] = true; - return function.lazyEval(ctx, Context.NONE, expr, token, Collections.emptyList()).evalValue(ctx); - } - return null; - }; taskFuture = CompletableFuture.supplyAsync( - () -> { synchronized (lock) { return task.get(); } }, - executorServices.computeIfAbsent(pool, (v) -> (ThreadPoolExecutor)Executors.newCachedThreadPool()) + () -> { synchronized (lock) { + return function.lazyEval(ctx, Context.NONE, expr, token, Collections.emptyList()).evalValue(ctx); + } }, + executorServices.computeIfAbsent(pool, (v) -> (ThreadPoolExecutor)Executors.newCachedThreadPool()) ); Thread.yield(); } @@ -60,18 +48,6 @@ public class ThreadValue extends Value public Value join() { - if (!started[0]) - { - synchronized (lock) - { - if (!started[0]) - { - Value res = task.get(); - taskFuture.complete(res); - return res; - } - } - } try { return taskFuture.get(); @@ -93,7 +69,6 @@ public class ThreadValue extends Value { if (!taskFuture.isDone()) { - started[0] = true; taskFuture.complete(Value.NULL); } }