从主机取消收益

时间:2016-04-03 16:53:26

标签: c# lua

我有一个使用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。我假设因为脚本当前没有运行,而是屈服。

1 个答案:

答案 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--;
    }
}