私は、プレイヤーがゲーム内のコンピューターでスクリプトを実行できるゲーム メカニクスを試しています。スクリプトの実行は、ゲームプレイ レベルで 1 ティックあたりの命令数にリソースが制限されます。
次の概念実証は、任意のユーザー コードのサンドボックス化とスロットリングの基本レベルを示しています。巧妙に作成されていない「ユーザー入力」の約 250 命令を正常に実行し、コルーチンを破棄します。残念ながら、Java プロセスは決して終了しません。少し調べてLuaThread
みると、コルーチン用に LuaJ によって作成された が永遠にぶら下がっていることがわかります。
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
ドキュメントは、再開不可能と見なされるコルーチンがガベージ コレクションされ、OrphanedThread
例外がスローされ、LuaThread
終了することを通知することを示唆していますが、これは決して起こりません。私の質問は2つの部分に分かれています:
- この動作を引き起こすために根本的に間違ったことをしていますか?
- そうでない場合、この状況にどのように対処すればよいですか?
LuaThread
ソースからは、Java でへの参照を取得できれば、interrupt()
. これは良い考えですか?
参考:Lua / Java / LuaJ - 無限ループとスレッドの処理または中断
編集: LuaJ SourceForge にバグ レポートを投稿しました。根本的な問題 (Lua 仕様のようにスレッドがガベージ コレクションされない) について説明し、それを回避するいくつかの方法を提案します。