我有一个使用Lua脚本的网络应用程序。在启动应用程序时,我创建一个全局Lua状态并加载包含各种函数的所有脚本文件,并为每个连接的客户端创建一个Lua线程,用于该连接。
// On start
var GL = luaL_newstate();
// register functions...
// load scripts...
// On connection
connection.State = lua_newthread(GL);
当使用脚本的请求进入时,我会获得全局函数并调用它。
var NL = connection.State;
var result = lua_resume(NL, 0);
if (result != 0 && result != LUA_YIELD)
{
// error...
result = 0;
}
if (result == 0)
{
// function returned...
}
现在,有些脚本需要对来自客户端的内容做出响应,所以我会在这些函数中产生,等待它。当响应进入时,脚本将以lua_resume(NL, 1)
恢复。
// Lua
text("How are you?")
local response = select("Good", "Bad")
// Host
private int select(IntPtr L)
{
// send response request...
return lua_yield(L, 1);
}
// On response
lua_pushstring(NL, response);
var result = lua_resume(NL, 1);
// ...
我的问题是我需要能够取消该产量,并从Lua函数返回,而无需在Lua函数中执行任何更多代码,也无需向脚本添加其他代码。换句话说,我基本上想让Lua线程抛出异常,回到开始,忘记它曾经执行过那个函数。
这可能吗?
我认为可能有用的一件事,但没有,正在呼叫lua_error
。结果是SEHException
电话上的lua_error
。我假设因为脚本当前没有运行,而是屈服。
答案 0 :(得分:0)
虽然我没有找到一种方法来擦除线程的清单(我不认为这是可能的),但我确实找到了解决lua_newthread
如何工作的解决方案。
创建线程时,对它的引用被置于“全局”状态的堆栈中,并且在从那里移除之前它不会被收集。清除线程所需要做的就是使用lua_remove
将其从堆栈中删除。这需要你定期创建新的线程,但这对我来说不是什么大问题。
我现在正在跟踪堆栈上创建的线程及其索引,所以当我完成它们时,无论出于何种原因(取消,错误等),我都可以删除它们。所有其他索引都会更新,因为删除会转移之后的索引。
if (sessionOver)
{
lua_remove(GL, thread.StackIndex);
foreach (var t in threads)
{
if (t.StackIndex > thread.StackIndex)
t.StackIndex--;
}
}