11//! Internal details to be used by instance.rs only
22use std:: borrow:: BorrowMut ;
3- use std:: cell:: RefCell ;
43use std:: marker:: PhantomData ;
54use std:: ptr:: NonNull ;
6- use std:: rc:: Rc ;
7- use std:: sync:: { Arc , RwLock } ;
5+ use std:: sync:: { Arc , Mutex , RwLock } ;
86
97use derivative:: Derivative ;
108use wasmer:: { AsStoreMut , Instance as WasmerInstance , Memory , MemoryView , Value } ;
@@ -106,7 +104,7 @@ pub struct DebugInfo<'a> {
106104// /- BEGIN TRAIT END TRAIT \
107105// | |
108106// v v
109- pub type DebugHandlerFn = dyn for <' a , ' b > FnMut ( /* msg */ & ' a str , DebugInfo < ' b > ) ;
107+ pub type DebugHandlerFn = dyn for <' a , ' b > FnMut ( /* msg */ & ' a str , DebugInfo < ' b > ) + Send + Sync ;
110108
111109/// A environment that provides access to the ContextData.
112110/// The environment is clonable but clones access the same underlying data.
@@ -117,10 +115,6 @@ pub struct Environment<A, S, Q> {
117115 data : Arc < RwLock < ContextData < S , Q > > > ,
118116}
119117
120- unsafe impl < A : BackendApi , S : Storage , Q : Querier > Send for Environment < A , S , Q > { }
121-
122- unsafe impl < A : BackendApi , S : Storage , Q : Querier > Sync for Environment < A , S , Q > { }
123-
124118impl < A : BackendApi , S : Storage , Q : Querier > Clone for Environment < A , S , Q > {
125119 fn clone ( & self ) -> Self {
126120 Environment {
@@ -142,15 +136,15 @@ impl<A: BackendApi, S: Storage, Q: Querier> Environment<A, S, Q> {
142136 }
143137 }
144138
145- pub fn set_debug_handler ( & self , debug_handler : Option < Rc < RefCell < DebugHandlerFn > > > ) {
139+ pub fn set_debug_handler ( & self , debug_handler : Option < Arc < Mutex < DebugHandlerFn > > > ) {
146140 self . with_context_data_mut ( |context_data| {
147141 context_data. debug_handler = debug_handler;
148142 } )
149143 }
150144
151- pub fn debug_handler ( & self ) -> Option < Rc < RefCell < DebugHandlerFn > > > {
145+ pub fn debug_handler ( & self ) -> Option < Arc < Mutex < DebugHandlerFn > > > {
152146 self . with_context_data ( |context_data| {
153- // This clone here requires us to wrap the function in Rc instead of Box
147+ // This clone here requires us to wrap the function in Arc instead of Box
154148 context_data. debug_handler . clone ( )
155149 } )
156150 }
@@ -282,7 +276,7 @@ impl<A: BackendApi, S: Storage, Q: Querier> Environment<A, S, Q> {
282276 /// Creates a back reference from a contact to its partent instance
283277 pub fn set_wasmer_instance ( & self , wasmer_instance : Option < NonNull < WasmerInstance > > ) {
284278 self . with_context_data_mut ( |context_data| {
285- context_data. wasmer_instance = wasmer_instance;
279+ context_data. wasmer_instance = wasmer_instance. map ( WasmerRef ) ;
286280 } ) ;
287281 }
288282
@@ -399,9 +393,42 @@ pub struct ContextData<S, Q> {
399393 storage_readonly : bool ,
400394 call_depth : usize ,
401395 querier : Option < Q > ,
402- debug_handler : Option < Rc < RefCell < DebugHandlerFn > > > ,
396+ debug_handler : Option < Arc < Mutex < DebugHandlerFn > > > ,
403397 /// A non-owning link to the wasmer instance
404- wasmer_instance : Option < NonNull < WasmerInstance > > ,
398+ wasmer_instance : Option < WasmerRef > ,
399+ }
400+
401+ /// A non-owning link to the wasmer instance
402+ ///
403+ /// This wrapper type allows us to implement `Send` and `Sync`.
404+ #[ derive( Clone , Copy ) ]
405+ struct WasmerRef ( NonNull < WasmerInstance > ) ;
406+
407+ impl WasmerRef {
408+ pub const unsafe fn as_ref < ' a > ( & self ) -> & ' a WasmerInstance {
409+ self . 0 . as_ref ( )
410+ }
411+ }
412+
413+ //
414+ unsafe impl Send for WasmerRef { }
415+ unsafe impl Sync for WasmerRef { }
416+
417+ /// TODO: SAFETY
418+ // unsafe impl<S: Sync, Q: Sync> Sync for ContextData<S, Q> {}
419+
420+ /// Implementing `Send` is safe here as long as `WasmerInstance` is Send.
421+ /// This is guaranteed by the function definition below.
422+ // unsafe impl<S: Send, Q: Send> Send for ContextData<S, Q> {}
423+
424+ #[ allow( dead_code) ]
425+ fn assert_is_send < T : Send > ( _: PhantomData < T > ) { }
426+ #[ allow( dead_code) ]
427+ fn assert_is_sync < T : Sync > ( _: PhantomData < T > ) { }
428+ #[ allow( dead_code) ]
429+ fn assert_wasmer_instance ( ) {
430+ assert_is_send ( PhantomData :: < WasmerInstance > ) ;
431+ assert_is_sync ( PhantomData :: < WasmerInstance > ) ;
405432}
406433
407434impl < S : Storage , Q : Querier > ContextData < S , Q > {
0 commit comments