[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: safely buffering Lua data between (system) threads & lua_States?
- From: "lists@..." <lists@...>
- Date: Fri, 15 Sep 2006 16:36:36 -0700
Hi,
I have a multi-threaded application, with Lua code executing in a
main (system) thread. I'd like to be able to interact with another
(system) thread, ideally with its own Lua state, all in shared
memory. Thread2's lua_State * has a flag to indicate which thread
current owns (may interact with) it. When any thread finds that the
lua_State * is assigned to it, it calls functions / adds values etc.
to it, then switches ownership of the lua_State * to the other
thread; all fine so and thread-safe so far I think.
Unfortunately, this means that there are times at which the main
thread can't access thread2, which I would like to avoid. I had the
idea to 'double buffer' the lua_State *; that is, to have two input
lua_State *s for thread2, and alternately swap which ones are
assigned to the main thread; then in thread2 copy items from
whichever of these input lua_States is locked into thread2's real
lua_State.
So it's a general conceptual question - is this crazy? Is it
workable? How much can I copy Lua data around between distinct
states (assuming thread safety is managed correctly)? Is there a
smarter algorithm for this kind of work?
Pseudocode:
main thread:
L
main thread loop:
lua_State * L = get_first_available_thread2_luastate()
if (L) {
lua_pushthings(L); //etc
setownership(L, thread2); // locks L
}
thread2:
lua_State * L; // thread's main lua state, only accessible here
lua_State * L1, L2; // input states used to receive Lua data from
another thread
thread2 loop:
L = thread2.lua_State;
lua_State * Linput = get_first_locked_thread2_luastate()
if (Linput) {
lua_copythingsintoL(Linput, L); // etc
setownership(Linput, main); // unlocks L
}
lua_callthings(L); //etc
get_first_locked_thread2_luastate() {
return L1.locked ? L1 : L2.locked ? L2 : 0;
}
get_first_available_thread2_luastate() {
return !L1.locked ? L1 : !L2.locked ? L2 : 0;
}
Graham