From 4b1ec671e244292322be8dbc883eb12d70098c30 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Sat, 25 Nov 2023 18:58:35 +0200 Subject: [PATCH] fix: micro tasks not handled properly --- src/me/topchetoeu/jscript/engine/Engine.java | 33 ++++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/me/topchetoeu/jscript/engine/Engine.java b/src/me/topchetoeu/jscript/engine/Engine.java index a5c7dc6..5dde3da 100644 --- a/src/me/topchetoeu/jscript/engine/Engine.java +++ b/src/me/topchetoeu/jscript/engine/Engine.java @@ -2,7 +2,7 @@ package me.topchetoeu.jscript.engine; import java.util.HashMap; import java.util.TreeSet; -import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.PriorityBlockingQueue; import me.topchetoeu.jscript.Filename; import me.topchetoeu.jscript.Location; @@ -35,18 +35,25 @@ public class Engine implements DebugController { } } - private static class Task { + private static class Task implements Comparable { public final FunctionValue func; public final Object thisArg; public final Object[] args; public final DataNotifier notifier = new DataNotifier<>(); public final Context ctx; + public final boolean micro; - public Task(Context ctx, FunctionValue func, Object thisArg, Object[] args) { + public Task(Context ctx, FunctionValue func, Object thisArg, Object[] args, boolean micro) { this.ctx = ctx; this.func = func; this.thisArg = thisArg; this.args = args; + this.micro = micro; + } + + @Override + public int compareTo(Task other) { + return Integer.compare(this.micro ? 0 : 1, other.micro ? 0 : 1); } } @@ -62,8 +69,7 @@ public class Engine implements DebugController { private DebugController debugger; private Thread thread; - private LinkedBlockingDeque macroTasks = new LinkedBlockingDeque<>(); - private LinkedBlockingDeque microTasks = new LinkedBlockingDeque<>(); + private PriorityBlockingQueue tasks = new PriorityBlockingQueue<>(); public boolean attachDebugger(DebugController debugger) { if (!debugging || this.debugger != null) return false; @@ -91,18 +97,12 @@ public class Engine implements DebugController { } } public void run(boolean untilEmpty) { - while (!untilEmpty || !macroTasks.isEmpty()) { + while (!untilEmpty || !tasks.isEmpty()) { try { - runTask(macroTasks.take()); - - while (!microTasks.isEmpty()) { - runTask(microTasks.take()); - } + runTask(tasks.take()); } catch (InterruptedException | InterruptException e) { - for (var msg : macroTasks) { - msg.notifier.error(new InterruptException(e)); - } + for (var msg : tasks) msg.notifier.error(new InterruptException(e)); break; } } @@ -127,9 +127,8 @@ public class Engine implements DebugController { } public Awaitable pushMsg(boolean micro, Context ctx, FunctionValue func, Object thisArg, Object ...args) { - var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args); - if (micro) microTasks.addLast(msg); - else macroTasks.addLast(msg); + var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args, micro); + tasks.add(msg); return msg.notifier; } public Awaitable pushMsg(boolean micro, Context ctx, Filename filename, String raw, Object thisArg, Object ...args) {