@@ -25,7 +25,7 @@ pub(crate) enum UserDataStorage<T> {
2525pub ( crate ) enum UserDataVariant < T > {
2626 Default ( XRc < UserDataCell < T > > ) ,
2727 #[ cfg( feature = "serde" ) ]
28- Serializable ( XRc < UserDataCell < Box < DynSerialize > > > , bool ) , // bool is `is_sync`
28+ Serializable ( XRc < UserDataCell < Box < DynSerialize > > > ) ,
2929}
3030
3131impl < T > Clone for UserDataVariant < T > {
@@ -34,18 +34,20 @@ impl<T> Clone for UserDataVariant<T> {
3434 match self {
3535 Self :: Default ( inner) => Self :: Default ( XRc :: clone ( inner) ) ,
3636 #[ cfg( feature = "serde" ) ]
37- Self :: Serializable ( inner, is_sync ) => Self :: Serializable ( XRc :: clone ( inner) , * is_sync ) ,
37+ Self :: Serializable ( inner) => Self :: Serializable ( XRc :: clone ( inner) ) ,
3838 }
3939 }
4040}
4141
4242impl < T > UserDataVariant < T > {
4343 #[ inline( always) ]
4444 pub ( super ) fn try_borrow_scoped < R > ( & self , f : impl FnOnce ( & T ) -> R ) -> Result < R > {
45- // We don't need to check for `T: Sync` because when this method is used (internally),
46- // Lua mutex is already locked.
47- // If non-`Sync` userdata is already borrowed by another thread (via `UserDataRef`), it will be
48- // exclusively locked.
45+ // Shared (read) lock is always correct for in-place borrows:
46+ // - this method is called internally while the Lua mutex is held, ensuring exclusive Lua-level
47+ // access per call frame
48+ // - with `send` feature, all owned userdata satisfies `T: Sync`, so simultaneous shared references
49+ // from multiple threads are sound
50+ // - without `send` feature, single-threaded execution makes shared lock safe for any `T`
4951 let _guard = ( self . raw_lock ( ) . try_lock_shared_guarded ( ) ) . map_err ( |_| Error :: UserDataBorrowError ) ?;
5052 Ok ( f ( unsafe { & * self . as_ptr ( ) } ) )
5153 }
@@ -80,7 +82,7 @@ impl<T> UserDataVariant<T> {
8082 Ok ( match self {
8183 Self :: Default ( inner) => XRc :: into_inner ( inner) . unwrap ( ) . value . into_inner ( ) ,
8284 #[ cfg( feature = "serde" ) ]
83- Self :: Serializable ( inner, _ ) => unsafe {
85+ Self :: Serializable ( inner) => unsafe {
8486 let raw = Box :: into_raw ( XRc :: into_inner ( inner) . unwrap ( ) . value . into_inner ( ) ) ;
8587 * Box :: from_raw ( raw as * mut T )
8688 } ,
@@ -92,7 +94,7 @@ impl<T> UserDataVariant<T> {
9294 match self {
9395 Self :: Default ( inner) => XRc :: strong_count ( inner) ,
9496 #[ cfg( feature = "serde" ) ]
95- Self :: Serializable ( inner, _ ) => XRc :: strong_count ( inner) ,
97+ Self :: Serializable ( inner) => XRc :: strong_count ( inner) ,
9698 }
9799 }
98100
@@ -101,7 +103,7 @@ impl<T> UserDataVariant<T> {
101103 match self {
102104 Self :: Default ( inner) => & inner. raw_lock ,
103105 #[ cfg( feature = "serde" ) ]
104- Self :: Serializable ( inner, _ ) => & inner. raw_lock ,
106+ Self :: Serializable ( inner) => & inner. raw_lock ,
105107 }
106108 }
107109
@@ -110,7 +112,7 @@ impl<T> UserDataVariant<T> {
110112 match self {
111113 Self :: Default ( inner) => inner. value . get ( ) ,
112114 #[ cfg( feature = "serde" ) ]
113- Self :: Serializable ( inner, _ ) => unsafe { & mut * * ( inner. value . get ( ) as * mut Box < T > ) } ,
115+ Self :: Serializable ( inner) => unsafe { & mut * * ( inner. value . get ( ) as * mut Box < T > ) } ,
114116 }
115117 }
116118}
@@ -119,24 +121,10 @@ impl<T> UserDataVariant<T> {
119121impl Serialize for UserDataStorage < ( ) > {
120122 fn serialize < S : Serializer > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error > {
121123 match self {
122- Self :: Owned ( variant @ UserDataVariant :: Serializable ( inner, is_sync) ) => unsafe {
123- #[ cfg( feature = "send" ) ]
124- if * is_sync {
125- let _guard = ( variant. raw_lock ( ) . try_lock_shared_guarded ( ) )
126- . map_err ( |_| serde:: ser:: Error :: custom ( Error :: UserDataBorrowError ) ) ?;
127- ( * inner. value . get ( ) ) . serialize ( serializer)
128- } else {
129- let _guard = ( variant. raw_lock ( ) . try_lock_exclusive_guarded ( ) )
130- . map_err ( |_| serde:: ser:: Error :: custom ( Error :: UserDataBorrowError ) ) ?;
131- ( * inner. value . get ( ) ) . serialize ( serializer)
132- }
133- #[ cfg( not( feature = "send" ) ) ]
134- {
135- let _ = is_sync;
136- let _guard = ( variant. raw_lock ( ) . try_lock_shared_guarded ( ) )
137- . map_err ( |_| serde:: ser:: Error :: custom ( Error :: UserDataBorrowError ) ) ?;
138- ( * inner. value . get ( ) ) . serialize ( serializer)
139- }
124+ Self :: Owned ( variant @ UserDataVariant :: Serializable ( inner) ) => unsafe {
125+ let _guard = ( variant. raw_lock ( ) . try_lock_shared_guarded ( ) )
126+ . map_err ( |_| serde:: ser:: Error :: custom ( Error :: UserDataBorrowError ) ) ?;
127+ ( * inner. value . get ( ) ) . serialize ( serializer)
140128 } ,
141129 _ => Err ( serde:: ser:: Error :: custom ( "cannot serialize <userdata>" ) ) ,
142130 }
@@ -201,11 +189,10 @@ impl<T: 'static> UserDataStorage<T> {
201189 #[ inline( always) ]
202190 pub ( crate ) fn new_ser ( data : T ) -> Self
203191 where
204- T : Serialize + crate :: types:: MaybeSend ,
192+ T : Serialize + crate :: types:: MaybeSend + crate :: types :: MaybeSync ,
205193 {
206194 let data = Box :: new ( data) as Box < DynSerialize > ;
207- let is_sync = super :: util:: is_sync :: < T > ( ) ;
208- let variant = UserDataVariant :: Serializable ( XRc :: new ( UserDataCell :: new ( data) ) , is_sync) ;
195+ let variant = UserDataVariant :: Serializable ( XRc :: new ( UserDataCell :: new ( data) ) ) ;
209196 Self :: Owned ( variant)
210197 }
211198
0 commit comments