1
1
//! Internal details to be used by instance.rs only
2
2
use std:: borrow:: BorrowMut ;
3
- use std:: cell:: RefCell ;
4
3
use std:: marker:: PhantomData ;
5
4
use std:: ptr:: NonNull ;
6
- use std:: rc:: Rc ;
7
- use std:: sync:: { Arc , RwLock } ;
5
+ use std:: sync:: { Arc , Mutex , RwLock } ;
8
6
9
7
use derivative:: Derivative ;
10
8
use wasmer:: { AsStoreMut , Instance as WasmerInstance , Memory , MemoryView , Value } ;
@@ -106,7 +104,7 @@ pub struct DebugInfo<'a> {
106
104
// /- BEGIN TRAIT END TRAIT \
107
105
// | |
108
106
// 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 ;
110
108
111
109
/// A environment that provides access to the ContextData.
112
110
/// The environment is clonable but clones access the same underlying data.
@@ -117,10 +115,6 @@ pub struct Environment<A, S, Q> {
117
115
data : Arc < RwLock < ContextData < S , Q > > > ,
118
116
}
119
117
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
-
124
118
impl < A : BackendApi , S : Storage , Q : Querier > Clone for Environment < A , S , Q > {
125
119
fn clone ( & self ) -> Self {
126
120
Environment {
@@ -142,15 +136,15 @@ impl<A: BackendApi, S: Storage, Q: Querier> Environment<A, S, Q> {
142
136
}
143
137
}
144
138
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 > > > ) {
146
140
self . with_context_data_mut ( |context_data| {
147
141
context_data. debug_handler = debug_handler;
148
142
} )
149
143
}
150
144
151
- pub fn debug_handler ( & self ) -> Option < Rc < RefCell < DebugHandlerFn > > > {
145
+ pub fn debug_handler ( & self ) -> Option < Arc < Mutex < DebugHandlerFn > > > {
152
146
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
154
148
context_data. debug_handler . clone ( )
155
149
} )
156
150
}
@@ -282,7 +276,7 @@ impl<A: BackendApi, S: Storage, Q: Querier> Environment<A, S, Q> {
282
276
/// Creates a back reference from a contact to its partent instance
283
277
pub fn set_wasmer_instance ( & self , wasmer_instance : Option < NonNull < WasmerInstance > > ) {
284
278
self . with_context_data_mut ( |context_data| {
285
- context_data. wasmer_instance = wasmer_instance;
279
+ context_data. wasmer_instance = wasmer_instance. map ( WasmerRef ) ;
286
280
} ) ;
287
281
}
288
282
@@ -399,9 +393,42 @@ pub struct ContextData<S, Q> {
399
393
storage_readonly : bool ,
400
394
call_depth : usize ,
401
395
querier : Option < Q > ,
402
- debug_handler : Option < Rc < RefCell < DebugHandlerFn > > > ,
396
+ debug_handler : Option < Arc < Mutex < DebugHandlerFn > > > ,
403
397
/// 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 > ) ;
405
432
}
406
433
407
434
impl < S : Storage , Q : Querier > ContextData < S , Q > {
0 commit comments