lua-users home
lua-l archive

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


* Sam Roberts:

> But, that *every* DB API doesn't set the L pointer to the state valid
> "at this time" is probably the larger bug.
>
> If you look at:
>
> http://www.lua.org/pil/29.2.html
>
> You'll see that xpu->L is set when the UD is created, but ALSO, that
> it is reset in lxp_parse at every call just before XML_Parse is
> called.

I think the SQLite binding does that, too, and it's not sufficient:
The call into SQLite from the coroutine overwrites the stored L value
with a Lua state that's going to go away, and there's no intervening
call before the next callback (from SQLite) to restore the correct L.

> This guarantees that when XML_Parse calls back, that the L it
> finds in xpu will be valid, and if parse is called from multiple
> coroutines/different L values (like you cleverly arranged in your
> sqlite3 example ;-), it will be OK because L will always point to the
> currently executing lua state.

It's difficult to reproduce this with the expat binding because it's
not expected to be reentrant (it just crashes).  If there was a second
function like parse, I could use the same trick, I think.

Here's the crasher for the LuaExpat binding (the one at
<http://www.keplerproject.org/luaexpat/>, I hope it's related to the
one in PIL):

require"lxp"
local called
callbacks = {
    StartElement = function (parser, name)
        if not called then
	   called = true
	   p:parse("foo")
	end
    end,
}
p = lxp.new(callbacks)
p:parse("<elem1></elem1>")
p:parse()

> At least, thats my reading of it, and I think that the fact that
> luasqlite3 doesn't do this is wrong. Before making a sqlite3 call that
> may result in a callback, and thus use of the sqlite3's context's
> lua_state, it should set the L pointer to the current context.

SQLite already does that.  It doesn't restore the previously stored L
value after the called SQLite API function returns (which would at
least fix this particular breakage, I think), or allocate its own Lua
thread and use it for user-defined functions.  I'm not completely sure
if restoring the L value is sufficient in all cases.