diff --git a/100_core/src/gplx/core/threads/Thread_adp.java b/100_core/src/gplx/core/threads/Thread_adp.java index b1e5451e9..82fceb28e 100644 --- a/100_core/src/gplx/core/threads/Thread_adp.java +++ b/100_core/src/gplx/core/threads/Thread_adp.java @@ -1,23 +1,32 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012-2017 gnosygnu@gmail.com - -XOWA is licensed under the terms of the General Public License (GPL) Version 3, -or alternatively under the terms of the Apache License Version 2.0. - -You may use XOWA according to either of these licenses as is most appropriate -for your project on a case-by-case basis. - -The terms of each license can be found in the source code repository: - -GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt -Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt -*/ -package gplx.core.threads; import gplx.*; import gplx.core.*; -import java.lang.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.core.threads; + +import gplx.Cancelable; +import gplx.Cancelable_; +import gplx.Err_; +import gplx.GfoMsg; +import gplx.GfoMsg_; +import gplx.Gfo_invk; +import gplx.Gfo_invk_; +import gplx.Gfo_log_; + public class Thread_adp implements Runnable { - private final String thread_name; private final Cancelable cxl; private final boolean cxlable; - private final Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg; + private final String thread_name; private final Cancelable cxl; private final boolean cxlable; + private final Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg; private Thread thread; @gplx.Internal protected Thread_adp(String thread_name, Cancelable cxl, Gfo_invk invk_itm, String invk_cmd, GfoMsg invk_msg) { this.thread_name = thread_name; this.cxl = cxl; this.cxlable = cxl != Cancelable_.Never; @@ -28,6 +37,7 @@ public class Thread_adp implements Runnable { public boolean Thread__cancelable() {return cxlable;} public boolean Thread__is_alive() {return thread == null ? false : thread.isAlive();} public void Thread__interrupt() {thread.interrupt();} + public void Thread__stop() {thread.stop();} public void run() { try { Gfo_invk_.Invk_by_msg(invk_itm, invk_cmd, invk_msg); @@ -37,8 +47,8 @@ public class Thread_adp implements Runnable { } } public void Thread__start() { - this.thread = (thread_name == null) ? new Thread(this) : new Thread(this, thread_name); + this.thread = (thread_name == null) ? new Thread(this) : new Thread(this, thread_name); thread.start(); - } - public static final Thread_adp Noop = new Thread_adp(Thread_adp_.Name_null, Cancelable_.Never, Gfo_invk_.Noop, "", GfoMsg_.Null); + } + public static final Thread_adp Noop = new Thread_adp(Thread_adp_.Name_null, Cancelable_.Never, Gfo_invk_.Noop, "", GfoMsg_.Null); } diff --git a/100_core/src/gplx/core/threads/Thread_adp_.java b/100_core/src/gplx/core/threads/Thread_adp_.java index 50abbf34b..49197038a 100644 --- a/100_core/src/gplx/core/threads/Thread_adp_.java +++ b/100_core/src/gplx/core/threads/Thread_adp_.java @@ -1,28 +1,36 @@ -/* -XOWA: the XOWA Offline Wiki Application -Copyright (C) 2012-2017 gnosygnu@gmail.com - -XOWA is licensed under the terms of the General Public License (GPL) Version 3, -or alternatively under the terms of the Apache License Version 2.0. - -You may use XOWA according to either of these licenses as is most appropriate -for your project on a case-by-case basis. - -The terms of each license can be found in the source code repository: - -GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt -Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt -*/ -package gplx.core.threads; import gplx.*; import gplx.core.*; +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2020 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.core.threads; + +import gplx.Cancelable; +import gplx.Cancelable_; +import gplx.Err_; +import gplx.GfoMsg; +import gplx.GfoMsg_; +import gplx.Gfo_invk; + public class Thread_adp_ { public static void Sleep(int milliseconds) { try { Thread.sleep(milliseconds); } catch (InterruptedException e) { throw Err_.new_exc(e, "core", "thread interrupted", "milliseconds", milliseconds); - } + } } - public static Thread_adp Start_by_key(String thread_name, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));} + public static Thread_adp Start_by_key(String thread_name, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));} public static Thread_adp Start_by_val(String thread_name, Gfo_invk invk_itm, String invk_cmd, Object val) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd).Add("v", val));} public static Thread_adp Start_by_msg(String thread_name, Gfo_invk invk_itm, GfoMsg invk_msg) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_msg.Key() , invk_msg);} public static Thread_adp Start_by_key(String thread_name, Cancelable cxl, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, cxl, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));} diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java index 41ef7fa8b..e74df8ee9 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func.java @@ -24,6 +24,7 @@ import gplx.xowa.wikis.nss.*; import gplx.xowa.htmls.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.xtns.pfuncs.*; + public class Scrib_invoke_func extends Pf_func_base { @Override public int Id() {return Xol_kwd_grp_.Id_invoke;} @Override public Pf_func New(int id, byte[] name) {return new Scrib_invoke_func().Name_(name);} @@ -72,11 +73,15 @@ public class Scrib_invoke_func extends Pf_func_base { InvokeInvoker invoker = new InvokeInvoker(core, wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); Thread_adp thread = Thread_adp_.Start_by_key("scribunto", invoker, "default"); while (thread.Thread__is_alive()) { + Thread_adp_.Sleep(10); if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) { - thread.Thread__interrupt(); - throw Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs)); + thread.Thread__stop(); + invoker.Exc = Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs)); } } + if (invoker.Exc != null) { + throw invoker.Exc; + } if (invoke_wkr != null) invoke_wkr.Eval_end(ctx.Page(), mod_name, fnc_name, log_time_bgn); } @@ -131,8 +136,14 @@ public class Scrib_invoke_func extends Pf_func_base { this.mod_raw = mod_raw; this.fnc_name = fnc_name; } + public Exception Exc; public Object Invk(GfsCtx gctx, int ikey, String k, GfoMsg m) { - core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); + try { + core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name); + } + catch (Exception exc) { + this.Exc = exc; + } return null; } }