2016-04-03 28 views
2

我有一个使用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。结果是拨打lua_error致电SEHException。我假设,因为脚本目前没有运行,但屈服。

回答

0

虽然我没有找到一种方法来擦拭线程的清洁(我不认为这是可能的),但我确实找到了解决方案,以确定lua_newthread的工作原理。

创建线程时,其引用被放在“全局”状态的堆栈上,直到从该处移除后才会被收集。您需要做的所有清理线程的工作是使用lua_remove将其从堆栈中移除。这需要你定期创建新线程,但这对我来说并不是什么大问题。

我现在正在跟踪堆栈中创建的线程和它们的索引,因此无论出于何种原因(取消,错误等)完成它们时,都可以将它们删除。所有其他指数都会更新,因为移除将会改变之后的指数。

if (sessionOver) 
{ 
    lua_remove(GL, thread.StackIndex); 

    foreach (var t in threads) 
    { 
     if (t.StackIndex > thread.StackIndex) 
      t.StackIndex--; 
    } 
}