Implement it for memory and make Instance Send

This commit is contained in:
Mark McCaskey
2019-09-17 14:58:26 -07:00
parent 9e9343878d
commit 83c3909b00
7 changed files with 37 additions and 24 deletions

View File

@ -54,6 +54,8 @@ pub struct LocalBacking {
pub(crate) internals: Internals, pub(crate) internals: Internals,
} }
unsafe impl Send for LocalBacking {}
impl LocalBacking { impl LocalBacking {
pub(crate) fn new( pub(crate) fn new(
module: &ModuleInner, module: &ModuleInner,
@ -461,6 +463,8 @@ pub struct ImportBacking {
pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, *mut vm::LocalGlobal>, pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, *mut vm::LocalGlobal>,
} }
unsafe impl Send for ImportBacking {}
impl ImportBacking { impl ImportBacking {
pub fn new( pub fn new(
module: &ModuleInner, module: &ModuleInner,

View File

@ -25,8 +25,6 @@ pub enum Export {
Global(Global), Global(Global),
} }
unsafe impl Send for Export {}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FuncPointer(*const vm::Func); pub struct FuncPointer(*const vm::Func);

View File

@ -46,7 +46,8 @@ impl IsExport for Export {
/// ``` /// ```
pub struct ImportObject { pub struct ImportObject {
map: Arc<Mutex<HashMap<String, Box<dyn LikeNamespace + Send>>>>, map: Arc<Mutex<HashMap<String, Box<dyn LikeNamespace + Send>>>>,
pub(crate) state_creator: Option<Arc<dyn Fn() -> (*mut c_void, fn(*mut c_void)) + Send>>, pub(crate) state_creator:
Option<Arc<dyn Fn() -> (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static>>,
pub allow_missing_functions: bool, pub allow_missing_functions: bool,
} }
@ -62,7 +63,7 @@ impl ImportObject {
pub fn new_with_data<F>(state_creator: F) -> Self pub fn new_with_data<F>(state_creator: F) -> Self
where where
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send, F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send + Sync,
{ {
Self { Self {
map: Arc::new(Mutex::new(HashMap::new())), map: Arc::new(Mutex::new(HashMap::new())),

View File

@ -25,6 +25,8 @@ pub(crate) struct InstanceInner {
pub(crate) vmctx: *mut vm::Ctx, pub(crate) vmctx: *mut vm::Ctx,
} }
unsafe impl Send for InstanceInner {}
impl Drop for InstanceInner { impl Drop for InstanceInner {
fn drop(&mut self) { fn drop(&mut self) {
// Drop the vmctx. // Drop the vmctx.

View File

@ -8,12 +8,9 @@ use crate::{
units::Pages, units::Pages,
vm, vm,
}; };
use std::{ use std::{cell::Cell, fmt, mem, sync::Arc};
cell::{Cell, RefCell},
fmt, mem, use std::sync::Mutex as StdMutex;
rc::Rc,
sync::Arc,
};
pub use self::dynamic::DynamicMemory; pub use self::dynamic::DynamicMemory;
pub use self::static_::StaticMemory; pub use self::static_::StaticMemory;
@ -208,14 +205,17 @@ enum UnsharedMemoryStorage {
} }
pub struct UnsharedMemory { pub struct UnsharedMemory {
internal: Rc<UnsharedMemoryInternal>, internal: Arc<UnsharedMemoryInternal>,
} }
struct UnsharedMemoryInternal { struct UnsharedMemoryInternal {
storage: RefCell<UnsharedMemoryStorage>, storage: StdMutex<UnsharedMemoryStorage>,
local: Cell<vm::LocalMemory>, local: Cell<vm::LocalMemory>,
} }
unsafe impl Send for UnsharedMemoryInternal {}
unsafe impl Sync for UnsharedMemoryInternal {}
impl UnsharedMemory { impl UnsharedMemory {
pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
let mut local = vm::LocalMemory { let mut local = vm::LocalMemory {
@ -235,15 +235,15 @@ impl UnsharedMemory {
}; };
Ok(Self { Ok(Self {
internal: Rc::new(UnsharedMemoryInternal { internal: Arc::new(UnsharedMemoryInternal {
storage: RefCell::new(storage), storage: StdMutex::new(storage),
local: Cell::new(local), local: Cell::new(local),
}), }),
}) })
} }
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> { pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
let mut storage = self.internal.storage.borrow_mut(); let mut storage = self.internal.storage.lock().unwrap();
let mut local = self.internal.local.get(); let mut local = self.internal.local.get();
@ -260,7 +260,7 @@ impl UnsharedMemory {
} }
pub fn size(&self) -> Pages { pub fn size(&self) -> Pages {
let storage = self.internal.storage.borrow(); let storage = self.internal.storage.lock().unwrap();
match &*storage { match &*storage {
UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(), UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(),
@ -276,7 +276,7 @@ impl UnsharedMemory {
impl Clone for UnsharedMemory { impl Clone for UnsharedMemory {
fn clone(&self) -> Self { fn clone(&self) -> Self {
UnsharedMemory { UnsharedMemory {
internal: Rc::clone(&self.internal), internal: Arc::clone(&self.internal),
} }
} }
} }
@ -286,11 +286,14 @@ pub struct SharedMemory {
} }
pub struct SharedMemoryInternal { pub struct SharedMemoryInternal {
memory: RefCell<Box<StaticMemory>>, memory: StdMutex<Box<StaticMemory>>,
local: Cell<vm::LocalMemory>, local: Cell<vm::LocalMemory>,
lock: Mutex<()>, lock: Mutex<()>,
} }
unsafe impl Send for SharedMemoryInternal {}
unsafe impl Sync for SharedMemoryInternal {}
impl SharedMemory { impl SharedMemory {
fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
let mut local = vm::LocalMemory { let mut local = vm::LocalMemory {
@ -303,7 +306,7 @@ impl SharedMemory {
Ok(Self { Ok(Self {
internal: Arc::new(SharedMemoryInternal { internal: Arc::new(SharedMemoryInternal {
memory: RefCell::new(memory), memory: StdMutex::new(memory),
local: Cell::new(local), local: Cell::new(local),
lock: Mutex::new(()), lock: Mutex::new(()),
}), }),
@ -313,15 +316,18 @@ impl SharedMemory {
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> { pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
let _guard = self.internal.lock.lock(); let _guard = self.internal.lock.lock();
let mut local = self.internal.local.get(); let mut local = self.internal.local.get();
let pages = self.internal.memory.borrow_mut().grow(delta, &mut local); let mut memory = self.internal.memory.lock().unwrap();
let pages = memory.grow(delta, &mut local);
pages pages
} }
pub fn size(&self) -> Pages { pub fn size(&self) -> Pages {
let _guard = self.internal.lock.lock(); let _guard = self.internal.lock.lock();
self.internal.memory.borrow_mut().size() let memory = self.internal.memory.lock().unwrap();
memory.size()
} }
// This function is scary, because the mutex is not locked here
pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory { pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory {
self.internal.local.as_ptr() self.internal.local.as_ptr()
} }

View File

@ -4,7 +4,7 @@ use errno;
use nix::libc; use nix::libc;
use page_size; use page_size;
use std::ops::{Bound, RangeBounds}; use std::ops::{Bound, RangeBounds};
use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, rc::Rc, slice}; use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, slice, sync::Arc};
unsafe impl Send for Memory {} unsafe impl Send for Memory {}
unsafe impl Sync for Memory {} unsafe impl Sync for Memory {}
@ -14,7 +14,7 @@ pub struct Memory {
ptr: *mut u8, ptr: *mut u8,
size: usize, size: usize,
protection: Protect, protection: Protect,
fd: Option<Rc<RawFd>>, fd: Option<Arc<RawFd>>,
} }
impl Memory { impl Memory {
@ -49,7 +49,7 @@ impl Memory {
ptr: ptr as *mut u8, ptr: ptr as *mut u8,
size: file_len as usize, size: file_len as usize,
protection, protection,
fd: Some(Rc::new(raw_fd)), fd: Some(Arc::new(raw_fd)),
}) })
} }
} }

View File

@ -474,6 +474,8 @@ pub struct ImportedFunc {
pub vmctx: *mut Ctx, pub vmctx: *mut Ctx,
} }
unsafe impl Send for ImportedFunc {}
impl ImportedFunc { impl ImportedFunc {
#[allow(clippy::erasing_op)] // TODO #[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 { pub fn offset_func() -> u8 {