From 15b5e3e9a2c2d2c43a4da8114fb118cd5382f51a Mon Sep 17 00:00:00 2001 From: LadyCailin Date: Tue, 2 Apr 2024 18:24:42 +0200 Subject: [PATCH] Just run the code if x_run_on_main_thread_now is called on main thread, instead of crashing. --- .../abstraction/bukkit/BukkitConvertor.java | 11 ++++- .../laytonsmith/core/functions/Threading.java | 49 ++++++++++--------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitConvertor.java b/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitConvertor.java index edaba908a..a9f5058a7 100644 --- a/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitConvertor.java +++ b/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitConvertor.java @@ -723,7 +723,16 @@ public T runOnMainThreadAndWait(Callable callable) throws InterruptedExce throw new CancelCommandException(Implementation.GetServerType().getBranding() + " tried to schedule a task while the plugin was disabled (is the server shutting down?).", Target.UNKNOWN); } - return Bukkit.getServer().getScheduler().callSyncMethod(CommandHelperPlugin.self, callable).get(); + + if(Bukkit.isPrimaryThread()) { + try { + return callable.call(); + } catch(Exception e) { + throw new ExecutionException(e); + } + } else { + return Bukkit.getServer().getScheduler().callSyncMethod(CommandHelperPlugin.self, callable).get(); + } } @Override diff --git a/src/main/java/com/laytonsmith/core/functions/Threading.java b/src/main/java/com/laytonsmith/core/functions/Threading.java index 2ab352ac7..afa5ab177 100644 --- a/src/main/java/com/laytonsmith/core/functions/Threading.java +++ b/src/main/java/com/laytonsmith/core/functions/Threading.java @@ -17,7 +17,6 @@ import com.laytonsmith.core.compiler.VariableScope; import com.laytonsmith.core.constructs.CArray; import com.laytonsmith.core.constructs.CBoolean; -import com.laytonsmith.core.constructs.CClosure; import com.laytonsmith.core.constructs.CNull; import com.laytonsmith.core.constructs.CString; import com.laytonsmith.core.constructs.CVoid; @@ -46,7 +45,9 @@ * */ @core -public class Threading { +public final class Threading { + + private Threading() {} public static String docs() { return "This experimental and private API is subject to removal, or incompatible changes, and should not" @@ -76,27 +77,25 @@ public Boolean runAsync() { } @Override - public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException { + public Mixed exec(final Target t, final Environment env, Mixed... args) throws ConfigRuntimeException { final String threadId = args[0].val(); - if(!(args[1].isInstanceOf(CClosure.TYPE))) { - throw new CRECastException("Expected closure for arg 2", t); - } - final CClosure closure = (CClosure) args[1]; + final com.laytonsmith.core.natives.interfaces.Callable closure + = ArgumentValidation.getObject(args[1], t, com.laytonsmith.core.natives.interfaces.Callable.class); Thread th = new Thread("(" + Implementation.GetServerType().getBranding() + ") " + threadId) { @Override public void run() { - DaemonManager dm = environment.getEnv(StaticRuntimeEnv.class).GetDaemonManager(); + DaemonManager dm = env.getEnv(StaticRuntimeEnv.class).GetDaemonManager(); dm.activateThread(Thread.currentThread()); try { - closure.executeCallable(); + closure.executeCallable(env, t); } catch (LoopManipulationException ex) { ConfigRuntimeException.HandleUncaughtException(ConfigRuntimeException.CreateUncatchableException("Unexpected loop manipulation" - + " operation was triggered inside the closure.", t), environment); + + " operation was triggered inside the closure.", t), env); } catch (ConfigRuntimeException ex) { - ConfigRuntimeException.HandleUncaughtException(ex, environment); + ConfigRuntimeException.HandleUncaughtException(ex, env); } catch (CancelCommandException ex) { if(ex.getMessage() != null) { - new Echoes.console().exec(t, environment, new CString(ex.getMessage(), t), CBoolean.FALSE); + new Echoes.console().exec(t, env, new CString(ex.getMessage(), t), CBoolean.FALSE); } } finally { dm.deactivateThread(Thread.currentThread()); @@ -231,17 +230,18 @@ public Boolean runAsync() { } @Override - public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException { - final CClosure closure = ArgumentValidation.getObject(args[0], t, CClosure.class); + public Mixed exec(final Target t, final Environment env, Mixed... args) throws ConfigRuntimeException { + final com.laytonsmith.core.natives.interfaces.Callable closure + = ArgumentValidation.getObject(args[0], t, com.laytonsmith.core.natives.interfaces.Callable.class); StaticLayer.GetConvertor().runOnMainThreadLater( - environment.getEnv(StaticRuntimeEnv.class).GetDaemonManager(), new Runnable() { + env.getEnv(StaticRuntimeEnv.class).GetDaemonManager(), new Runnable() { @Override public void run() { try { - closure.executeCallable(); + closure.executeCallable(env, t); } catch (ConfigRuntimeException e) { - ConfigRuntimeException.HandleUncaughtException(e, environment); + ConfigRuntimeException.HandleUncaughtException(e, env); } catch (ProgramFlowManipulationException e) { // Ignored } @@ -295,8 +295,9 @@ public Boolean runAsync() { } @Override - public Mixed exec(final Target t, final Environment environment, Mixed... args) throws ConfigRuntimeException { - final CClosure closure = ArgumentValidation.getObject(args[0], t, CClosure.class); + public Mixed exec(final Target t, final Environment env, Mixed... args) throws ConfigRuntimeException { + final com.laytonsmith.core.natives.interfaces.Callable closure = ArgumentValidation.getObject(args[0], t, + com.laytonsmith.core.natives.interfaces.Callable.class); Object ret; try { ret = StaticLayer.GetConvertor().runOnMainThreadAndWait(new Callable() { @@ -304,7 +305,7 @@ public Mixed exec(final Target t, final Environment environment, Mixed... args) @Override public Object call() throws Exception { try { - return closure.executeCallable(); + return closure.executeCallable(env, t); } catch (ConfigRuntimeException | ProgramFlowManipulationException e) { return e; } @@ -314,8 +315,8 @@ public Object call() throws Exception { } catch (Exception ex) { throw new RuntimeException(ex); } - if(ret instanceof RuntimeException) { - throw (RuntimeException) ret; + if(ret instanceof RuntimeException runtimeException) { + throw runtimeException; } else { return (Mixed) ret; } @@ -353,7 +354,7 @@ public Version since() { @SelfStatement public static class _synchronized extends AbstractFunction implements VariableScope, BranchStatement { - private static final Map SYNC_OBJECT_MAP = new HashMap(); + private static final Map SYNC_OBJECT_MAP = new HashMap<>(); @Override public Class[] thrown() { @@ -389,7 +390,7 @@ public Mixed execs(Target t, Environment env, Script parent, ParseTree... nodes) // Get the sync object (CArray or String value of the Mixed). Mixed cSyncObject = parent.seval(syncObjectTree, env); - if(cSyncObject instanceof CNull) { + if(cSyncObject instanceof CNull || cSyncObject == null) { throw new CRENullPointerException("Synchronization object may not be null in " + getName() + "().", t); } Object syncObject;