lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Alexander Nasonov wrote:
> Now, to the tricky part. Plain cfunction inside a loop turns off JIT so
> I pass lua_State* pointer from LuaJIT to C before I start a loop and
> then I use the saved pointer when I call a callback function from inside
> the loop via FFI interface.

Well, there's a reason the FFI doesn't provide for a way to access
the current lua_State pointer ... what you're doing is not safe.

> In other words, I call read_char() from the event loop using FFI, which
> eventually calls readline_callback(char *line) and at this point I use
> the saved lua_State* pointer to call lua_cpcall(L, &cpreadline, line).
> 
> Is this valid at all?

Nope, the current lua_State is not in a safe state:

- When the FFI call is compiled, the global state is not in sync
  at all. Calling back into the same Lua state (or any coroutine
  of it) will lead to weird crashes, GC assertions and so on.

- When the FFI call is only interpreted, the global state is in
  sync, but the current Lua thread (coroutine) is not reentrant,
  i.e. you must not use lua_*call on it. It'll cause more subtle
  crashes if you violate this rule.

OTOH, if you ...

- Create an extra coroutine and anchor the Lua thread object
  somewhere

- *and* run your callback only on the associated lua_State pointer

- *and* make sure the FFI call to the outer event loop (or whatever)
  is not compiled,
  
... then this ought to be safe (famous last words).

To make sure the FFI call to the event loop is not JIT-compiled,
use jit.off(func) for the surrounding Lua function.

Another option is to call back into a separate Lua VM instance,
obtained with luaL_newstate() + luaL_openlib(). This is completely
safe, but you'll need to explicitly pass around code and data.
See: http://lua-users.org/lists/lua-l/2011-01/msg01579.html

--Mike