diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e287d35..b58cb0c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,7 @@ jobs: run: | cargo build --features "${{ matrix.lua }},vendored" cargo build --features "${{ matrix.lua }},vendored,async,send,serialize,macros" + cargo build --features "${{ matrix.lua }},vendored,async,serialize,macros,parking_lot" shell: bash - name: Build ${{ matrix.lua }} pkg-config if: ${{ matrix.os == 'ubuntu-20.04' && matrix.lua != 'lua54' }} @@ -128,12 +129,14 @@ jobs: run: | cargo test --features "${{ matrix.lua }},vendored" cargo test --features "${{ matrix.lua }},vendored,async,send,serialize,macros" + cargo test --features "${{ matrix.lua }},vendored,async,serialize,macros,parking_lot" shell: bash - name: Run compile tests (macos lua54) if: ${{ matrix.os == 'macos-latest' && matrix.lua == 'lua54' }} run: | TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored" -- --ignored TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored,async,send,serialize,macros" -- --ignored + TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored,async,serialize,macros,parking_lot" -- --ignored shell: bash test_with_sanitizer: diff --git a/Cargo.toml b/Cargo.toml index 2340747..7446e48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ with async/await features and support of writing native Lua modules in Rust. """ [package.metadata.docs.rs] -features = ["lua54", "vendored", "async", "send", "serialize", "macros"] +features = ["lua54", "vendored", "async", "send", "serialize", "macros", "parking_lot"] rustdoc-args = ["--cfg", "docsrs"] [workspace] @@ -53,6 +53,7 @@ futures-task = { version = "0.3.5", optional = true } futures-util = { version = "0.3.5", optional = true } serde = { version = "1.0", optional = true } erased-serde = { version = "0.3", optional = true } +parking_lot = { version = "0.12", optional = true } [build-dependencies] cc = { version = "1.0" } diff --git a/src/userdata_impl.rs b/src/userdata_impl.rs index a535245..9ab3757 100644 --- a/src/userdata_impl.rs +++ b/src/userdata_impl.rs @@ -246,11 +246,23 @@ impl<'lua, T: 'static + UserData> StaticUserDataMethods<'lua, T> { let ud = ud.try_lock().map_err(|_| Error::UserDataBorrowError)?; method(lua, &ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = get_userdata_ref::>>(lua.state)?; + let ud = ud.try_lock().ok_or(Error::UserDataBorrowError)?; + method(lua, &ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) + } Some(id) if id == TypeId::of::>>() => { let ud = get_userdata_ref::>>(lua.state)?; let ud = ud.try_read().map_err(|_| Error::UserDataBorrowError)?; method(lua, &ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = get_userdata_ref::>>(lua.state)?; + let ud = ud.try_read().ok_or(Error::UserDataBorrowError)?; + method(lua, &ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) + } _ => Err(Error::UserDataTypeMismatch), } } @@ -297,14 +309,24 @@ impl<'lua, T: 'static + UserData> StaticUserDataMethods<'lua, T> { } Some(id) if id == TypeId::of::>>() => { let ud = get_userdata_mut::>>(lua.state)?; - let mut ud = - ud.try_lock().map_err(|_| Error::UserDataBorrowMutError)?; + let mut ud = ud.try_lock().map_err(|_| Error::UserDataBorrowError)?; + method(lua, &mut ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) + } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = get_userdata_mut::>>(lua.state)?; + let mut ud = ud.try_lock().ok_or(Error::UserDataBorrowError)?; method(lua, &mut ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) } Some(id) if id == TypeId::of::>>() => { let ud = get_userdata_mut::>>(lua.state)?; - let mut ud = - ud.try_write().map_err(|_| Error::UserDataBorrowMutError)?; + let mut ud = ud.try_write().map_err(|_| Error::UserDataBorrowError)?; + method(lua, &mut ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) + } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = get_userdata_mut::>>(lua.state)?; + let mut ud = ud.try_write().ok_or(Error::UserDataBorrowError)?; method(lua, &mut ud, A::from_lua_multi(args, lua)?)?.to_lua_multi(lua) } _ => Err(Error::UserDataTypeMismatch), @@ -354,11 +376,24 @@ impl<'lua, T: 'static + UserData> StaticUserDataMethods<'lua, T> { let ud = ud.try_lock().map_err(|_| Error::UserDataBorrowError)?; Ok(method(lua, ud.clone(), A::from_lua_multi(args, lua)?)) } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = get_userdata_ref::>>(lua.state)?; + let ud = ud.try_lock().ok_or(Error::UserDataBorrowError)?; + Ok(method(lua, ud.clone(), A::from_lua_multi(args, lua)?)) + } Some(id) if id == TypeId::of::>>() => { let ud = get_userdata_ref::>>(lua.state)?; let ud = ud.try_read().map_err(|_| Error::UserDataBorrowError)?; Ok(method(lua, ud.clone(), A::from_lua_multi(args, lua)?)) } + #[cfg(feature = "parking_lot")] + Some(id) if id == TypeId::of::>>() => { + let ud = + get_userdata_ref::>>(lua.state)?; + let ud = ud.try_read().ok_or(Error::UserDataBorrowError)?; + Ok(method(lua, ud.clone(), A::from_lua_multi(args, lua)?)) + } _ => Err(Error::UserDataTypeMismatch), } } @@ -581,3 +616,7 @@ macro_rules! lua_userdata_impl { lua_userdata_impl!(Rc>); lua_userdata_impl!(Arc>); lua_userdata_impl!(Arc>); +#[cfg(feature = "parking_lot")] +lua_userdata_impl!(Arc>); +#[cfg(feature = "parking_lot")] +lua_userdata_impl!(Arc>); diff --git a/tests/userdata.rs b/tests/userdata.rs index c78b1db..ce9d9d0 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -1,4 +1,9 @@ -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::Arc; +#[cfg(not(feature = "parking_lot"))] +use std::sync::{Mutex, RwLock}; + +#[cfg(feature = "parking_lot")] +use parking_lot::{Mutex, RwLock}; #[cfg(not(feature = "send"))] use std::{cell::RefCell, rc::Rc}; @@ -623,7 +628,10 @@ fn test_userdata_wrapped() -> Result<()> { "#, ) .exec()?; + #[cfg(not(feature = "parking_lot"))] assert_eq!(ud2.lock().unwrap().0, 3); + #[cfg(feature = "parking_lot")] + assert_eq!(ud2.lock().0, 3); let ud3 = Arc::new(RwLock::new(MyUserData(3))); globals.set("arc_rwlock_ud", ud3.clone())?; @@ -634,7 +642,10 @@ fn test_userdata_wrapped() -> Result<()> { "#, ) .exec()?; + #[cfg(not(feature = "parking_lot"))] assert_eq!(ud3.read().unwrap().0, 4); + #[cfg(feature = "parking_lot")] + assert_eq!(ud3.read().0, 4); // Test drop globals.set("arc_mutex_ud", Nil)?;