1

I have a library in Lua that creates and parses data packets for a protocol. When I send a packet out, I'm expecting a reply back from the destination that is then parsed into a table. I'm trying to write a wrapper around this library so that I can make a function call like the following: result = SendUnicast(dest,packetData) and have the parsed response table returned to result.

My problem is two fold: 1) The incoming message comes in asynchronously and on a different thread than the executing script and 2) the next packet I receive isn't necessarily the response for my request, I have to parse the incoming packet and match a sequence id.

The program flow currently looks something like:

[C# UI Thread]

  • Button Click
  • Run Lua Script
    • Call SendUnicast
    • Wait For Response

[C# Data Thread]

  • Incoming Message
    • Pass message to Lua parser function
    • if sequence matches waiting command, store parsed table, resume blocked

[C# UI Thread]

  • Lua scipt returns parsed table

I can't seem to find a good method for blocking the currently executing script (in the UIThread). Creating a coroutine to be called when the message is parsed and then while coroutine.status(co) ~= "dead" seems to kill my lua interpreter.

EDIT

I'm marking BMitch's answer as accepted because it is the correct way to handle this issue. I will warn you, however, that LuaInterface does not support coroutines and I had to add support for them to the C# code myself.

kyork
  • 713
  • 5
  • 14

1 Answers1

2

In the UI thread, run:

while ((status=lua_resume(L_coroutine, 0)) == LUA_YIELD) {
  semaphore_wait(); /* whatever the appropriate C# call is */
}

"Wait for response" should look something like:

while not results[my_result] do
  coroutine.yield()
end

The "incoming message" function should look like the following in Lua:

results[cur_result]=parsed_message

And finally back in C# for the "incoming message", call the appropriate semaphore_post() function.

Sorry if my C# looks terrible, I'm a C programmer on Linux, so I tried to keep that side generic.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • I meant OS threads. I edited my post to make that more clear. I only have one Lua state. I take it Lua doesn't handle it well if you are running code on a state, and then another thread attempts to run other code within that same state? – kyork Jul 13 '11 at 20:02
  • Note, you can use `lua_resume` just as you would a `lua_pcall` but see my question for potential issues that can create: http://stackoverflow.com/questions/6625698/how-to-handle-errors-when-resuming-a-lua-thread-coroutine – BMitch Jul 13 '11 at 20:22
  • I can't seem to find a way in the C# binding (LuaInterface) to interact directly with coroutines. That's a bit of pita. – kyork Jul 13 '11 at 20:49
  • That part is getting out of my expertise, but you may get some help if you add `C#` to your tags. – BMitch Jul 13 '11 at 22:34
  • 1
    Also, since Lua is designed for a single threaded environment, you're going to want to put a mutex/lock around the calls to Lua to avoid the threads corrupting each other's Lua stack. – BMitch Jul 13 '11 at 22:37