2016-04-03 16 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の関数から返すことができるようにする必要があるということです。言い換えれば、私は基本的に、ルアスレッドに例外をスローさせ、最初に戻り、その関数を実行したことを忘れるようにします。

これは可能ですか?

私は働くかもしれないと思ったことの1つは、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--; 
    } 
} 
関連する問題