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 
283277pub  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  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