From a761f4094bc18190285b4687ec804161fea874b6 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sat, 27 Apr 2024 00:51:49 -0400 Subject: [PATCH] Make State Send and Sync --- src/lref.rs | 2 +- src/state.rs | 9 +++++---- src/table.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/lref.rs b/src/lref.rs index ac5b241..bb18428 100755 --- a/src/lref.rs +++ b/src/lref.rs @@ -20,7 +20,7 @@ impl<'a> Drop for LuaRef<'a> { fn drop(&mut self) { unsafe { if Arc::strong_count(&self.lref) == 1 { - let s = self.state.lua.as_ptr(); + let s = *self.state.lua.as_ptr(); lua::luaL_unref(s, lua::LUA_REGISTRYINDEX, *self.lref); } } diff --git a/src/state.rs b/src/state.rs index bb245ae..2e22a8b 100755 --- a/src/state.rs +++ b/src/state.rs @@ -1,5 +1,5 @@ use core::ffi; -use std::{alloc::{self, Layout}, any::TypeId, cell::RefCell, collections::HashMap, ffi::{CStr, CString}, mem, ptr::{self, NonNull}, str::Utf8Error, sync::Arc}; +use std::{alloc::{self, Layout}, any::TypeId, cell::RefCell, collections::HashMap, ffi::{CStr, CString}, mem, ptr::{self, NonNull}, str::Utf8Error, sync::{atomic::AtomicPtr, Arc}}; use lua::lua_gc; use mlua_sys as lua; @@ -117,7 +117,8 @@ impl ExtraSpace { #[derive(Clone)] pub struct StatePtr { - pub lua: Arc>, + // arc is used here to make self Cloneable + pub lua: Arc>, } pub struct State { @@ -167,7 +168,7 @@ impl State { pub fn new() -> Self { let s = Self { ptr: StatePtr { - lua: Arc::new(unsafe { NonNull::new_unchecked(lua::luaL_newstate()) }) + lua: Arc::new(AtomicPtr::new(unsafe { lua::luaL_newstate() })) } }; @@ -196,7 +197,7 @@ impl State { } pub(crate) fn state_ptr(&self) -> *mut lua::lua_State { - self.ptr.lua.as_ptr() + unsafe { *self.ptr.lua.as_ptr() } } fn alloc_extra_space(&self) { diff --git a/src/table.rs b/src/table.rs index 7324b32..4461c66 100755 --- a/src/table.rs +++ b/src/table.rs @@ -235,6 +235,46 @@ impl<'a> Table<'a> { } } + pub fn raw_seti(&self, key: i64, val: V) -> Result<()> + where + V: AsLua<'a> + { + debug_assert!(key > 0, "Indexes in Lua start at 1"); + + let s = self.state.state_ptr(); + unsafe { + self.state.ensure_stack(2)?; + let _g = StackGuard::new(self.state); + + self.lref.push_to_lua_stack(self.state)?; + val.as_lua(self.state)? + .push_to_lua_stack(self.state)?; + + lua::lua_rawseti(s, -2, key); + } + + Ok(()) + } + + pub fn raw_geti(&self, key: i64) -> Result + where + V: FromLua<'a>, + { + debug_assert!(key > 0, "Indexes in Lua start at 1"); + + let s = self.state.state_ptr(); + unsafe { + self.state.ensure_stack(1)?; + let _g = StackGuard::new(self.state); + + self.lref.push_to_lua_stack(self.state)?; + lua::lua_rawgeti(s, -1, key); + + let val = Value::from_lua_stack(self.state)?; + V::from_lua(self.state, val) + } + } + /// Returns a boolean indicating if this table has a key without calling any meta methods. pub fn raw_has_key(&self, key: K) -> Result where