Fixed threading and add shutdown control for threads via sleep
This commit is contained in:
1 parent
e50298a306
commit
1268af4131
8 files changed
+162
-107
No files matched your search
@@ -4,47 +4,55 @@ import carpet.script.Context;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.Tokenizer;
|
||||
import carpet.script.exception.ExitStatement;
|
||||
import carpet.script.exception.ExpressionException;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ThreadValue extends Value
|
||||
{
|
||||
private CompletableFuture<Value> taskFuture;
|
||||
private long id;
|
||||
private final CompletableFuture<Value> taskFuture;
|
||||
private final long id;
|
||||
private static long sequence = 0L;
|
||||
private static final Map<Value,ThreadPoolExecutor> executorServices = new HashMap<>();
|
||||
private static final Map<Value, Object> locks = new ConcurrentHashMap<>();
|
||||
|
||||
public ThreadValue(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<LazyValue> args)
|
||||
{
|
||||
id = sequence++;
|
||||
taskFuture = CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
return function.lazyEval(ctx, Context.NONE, expr, token, args).evalValue(ctx);
|
||||
}
|
||||
catch (ExpressionException exc)
|
||||
{
|
||||
ctx.host.handleExpressionException("Thread failed", exc);
|
||||
return Value.NULL;
|
||||
}
|
||||
},
|
||||
executorServices.computeIfAbsent(pool, (v) -> (ThreadPoolExecutor)Executors.newCachedThreadPool())
|
||||
);
|
||||
ExecutorService executor = ctx.host.getExecutor(pool);
|
||||
if (executor == null)
|
||||
{
|
||||
// app is shutting down - no more threads can be spawned.
|
||||
taskFuture = CompletableFuture.completedFuture(Value.NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
taskFuture = CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
return function.lazyEval(ctx, Context.NONE, expr, token, args).evalValue(ctx);
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
// app stopped
|
||||
return exit.retval;
|
||||
}
|
||||
catch (ExpressionException exc)
|
||||
{
|
||||
ctx.host.handleExpressionException("Thread failed", exc);
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
},
|
||||
ctx.host.getExecutor(pool)
|
||||
);
|
||||
}
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
@@ -71,6 +79,11 @@ public class ThreadValue extends Value
|
||||
{
|
||||
return taskFuture.get();
|
||||
}
|
||||
catch (ExitStatement exit)
|
||||
{
|
||||
taskFuture.complete(exit.retval);
|
||||
return exit.retval;
|
||||
}
|
||||
catch (InterruptedException | ExecutionException e)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -104,47 +117,6 @@ public class ThreadValue extends Value
|
||||
return Long.hashCode(id);
|
||||
}
|
||||
|
||||
public static int taskCount()
|
||||
{
|
||||
return executorServices.values().stream().map(ThreadPoolExecutor::getActiveCount).reduce(0, Integer::sum);
|
||||
}
|
||||
|
||||
public static int taskCount(Value pool)
|
||||
{
|
||||
if (executorServices.containsKey(pool))
|
||||
{
|
||||
return executorServices.get(pool).getActiveCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Object getLock(Value name)
|
||||
{
|
||||
return locks.computeIfAbsent(name, (n) -> new Object());
|
||||
}
|
||||
|
||||
|
||||
public static void shutdown()
|
||||
{
|
||||
for (ExecutorService exec : executorServices.values())
|
||||
{
|
||||
exec.shutdown();
|
||||
try
|
||||
{
|
||||
exec.awaitTermination(5000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (InterruptedException ignored)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
exec.shutdownNow();
|
||||
}
|
||||
}
|
||||
executorServices.clear();
|
||||
locks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user