Skip to content

Commit

Permalink
Fix edge case when loading many-in-one module from thread without usi…
Browse files Browse the repository at this point in the history
…ng its state.

If Lua previously been initialized in main thread and then new module was loaded from thread
we reuse old state which confuses Lua loader.
  • Loading branch information
khvzak committed Jan 10, 2024
1 parent 12472de commit b9c5960
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
2 changes: 1 addition & 1 deletion mlua_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub fn lua_module(attr: TokenStream, item: TokenStream) -> TokenStream {
unsafe extern "C-unwind" fn #ext_entrypoint_name(state: *mut ::mlua::lua_State) -> ::std::os::raw::c_int {
let lua = ::mlua::Lua::init_from_ptr(state);
lua.skip_memory_check(#skip_memory_check);
lua.entrypoint1(#func_name)
lua.entrypoint1(state, #func_name)
}
};

Expand Down
12 changes: 7 additions & 5 deletions src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,18 +708,20 @@ impl Lua {
// The returned value then pushed onto the stack.
#[doc(hidden)]
#[cfg(not(tarpaulin_include))]
pub unsafe fn entrypoint<'lua, A, R, F>(self, func: F) -> c_int
pub unsafe fn entrypoint<'lua, A, R, F>(self, state: *mut ffi::lua_State, func: F) -> c_int
where
A: FromLuaMulti<'lua>,
R: IntoLua<'lua>,
F: Fn(&'lua Lua, A) -> Result<R> + MaybeSend + 'static,
{
let (state, extra) = (self.state(), self.extra.get());
// It must be safe to drop `self` as in the module mode we keep strong reference to `Lua` in the registry
let extra = self.extra.get();
// `self` is no longer needed and must be dropped at this point to avoid possible memory leak
// in case of longjmp (lua_error) below
drop(self);

callback_error_ext(state, extra, move |nargs| {
let lua: &Lua = mem::transmute((*extra).inner.assume_init_ref());
let _guard = StateGuard::new(&lua.0, state);
let args = A::from_stack_args(nargs, 1, None, lua)?;
func(lua, args)?.push_into_stack(lua)?;
Ok(1)
Expand All @@ -729,12 +731,12 @@ impl Lua {
// A simple module entrypoint without arguments
#[doc(hidden)]
#[cfg(not(tarpaulin_include))]
pub unsafe fn entrypoint1<'lua, R, F>(self, func: F) -> c_int
pub unsafe fn entrypoint1<'lua, R, F>(self, state: *mut ffi::lua_State, func: F) -> c_int
where
R: IntoLua<'lua>,
F: Fn(&'lua Lua) -> Result<R> + MaybeSend + 'static,
{
self.entrypoint(move |lua, _: ()| func(lua))
self.entrypoint(state, move |lua, _: ()| func(lua))
}

/// Skips memory checks for some operations.
Expand Down

0 comments on commit b9c5960

Please sign in to comment.