fix: micro tasks not handled properly
This commit is contained in:
parent
b127aadcf6
commit
4b1ec671e2
@ -2,7 +2,7 @@ package me.topchetoeu.jscript.engine;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Filename;
|
import me.topchetoeu.jscript.Filename;
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
@ -35,18 +35,25 @@ public class Engine implements DebugController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Task {
|
private static class Task implements Comparable<Task> {
|
||||||
public final FunctionValue func;
|
public final FunctionValue func;
|
||||||
public final Object thisArg;
|
public final Object thisArg;
|
||||||
public final Object[] args;
|
public final Object[] args;
|
||||||
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
||||||
public final Context ctx;
|
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.ctx = ctx;
|
||||||
this.func = func;
|
this.func = func;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
this.args = args;
|
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 DebugController debugger;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private LinkedBlockingDeque<Task> macroTasks = new LinkedBlockingDeque<>();
|
private PriorityBlockingQueue<Task> tasks = new PriorityBlockingQueue<>();
|
||||||
private LinkedBlockingDeque<Task> microTasks = new LinkedBlockingDeque<>();
|
|
||||||
|
|
||||||
public boolean attachDebugger(DebugController debugger) {
|
public boolean attachDebugger(DebugController debugger) {
|
||||||
if (!debugging || this.debugger != null) return false;
|
if (!debugging || this.debugger != null) return false;
|
||||||
@ -91,18 +97,12 @@ public class Engine implements DebugController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void run(boolean untilEmpty) {
|
public void run(boolean untilEmpty) {
|
||||||
while (!untilEmpty || !macroTasks.isEmpty()) {
|
while (!untilEmpty || !tasks.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
runTask(macroTasks.take());
|
runTask(tasks.take());
|
||||||
|
|
||||||
while (!microTasks.isEmpty()) {
|
|
||||||
runTask(microTasks.take());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException | InterruptException e) {
|
catch (InterruptedException | InterruptException e) {
|
||||||
for (var msg : macroTasks) {
|
for (var msg : tasks) msg.notifier.error(new InterruptException(e));
|
||||||
msg.notifier.error(new InterruptException(e));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,9 +127,8 @@ public class Engine implements DebugController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Awaitable<Object> pushMsg(boolean micro, Context ctx, FunctionValue func, Object thisArg, Object ...args) {
|
public Awaitable<Object> pushMsg(boolean micro, Context ctx, FunctionValue func, Object thisArg, Object ...args) {
|
||||||
var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args);
|
var msg = new Task(ctx == null ? new Context(this) : ctx, func, thisArg, args, micro);
|
||||||
if (micro) microTasks.addLast(msg);
|
tasks.add(msg);
|
||||||
else macroTasks.addLast(msg);
|
|
||||||
return msg.notifier;
|
return msg.notifier;
|
||||||
}
|
}
|
||||||
public Awaitable<Object> pushMsg(boolean micro, Context ctx, Filename filename, String raw, Object thisArg, Object ...args) {
|
public Awaitable<Object> pushMsg(boolean micro, Context ctx, Filename filename, String raw, Object thisArg, Object ...args) {
|
||||||
|
Loading…
Reference in New Issue
Block a user