Skip to content

Commit

Permalink
Make Store Send and Sync (#566)
Browse files Browse the repository at this point in the history
* make Arena<Idx, T> Send and Sync independent of Idx

* make InstructionPtr Send but not Sync

* add compile-time test to assert that Store is Send + Sync if T: Send+Sync

* add more docs to unsafe Send impl of InstructionPtr

* apply rustfmt
  • Loading branch information
Robbepop authored Nov 18, 2022
1 parent 93c1596 commit 44419e0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
6 changes: 6 additions & 0 deletions crates/arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ pub struct Arena<Idx, T> {
marker: PhantomData<Idx>,
}

/// `Arena` does not store `Idx` therefore it is `Send` without its bound.
unsafe impl<Idx, T> Send for Arena<Idx, T> where T: Send {}

/// `Arena` does not store `Idx` therefore it is `Sync` without its bound.
unsafe impl<Idx, T> Sync for Arena<Idx, T> where T: Send {}

impl<Idx, T> Default for Arena<Idx, T> {
fn default() -> Self {
Self::new()
Expand Down
10 changes: 10 additions & 0 deletions crates/wasmi/src/engine/code_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ pub struct InstructionPtr {
ptr: *const Instruction,
}

/// It is safe to send an [`InstructionPtr`] to another thread.
///
/// The access to the pointed-to [`Instruction`] is read-only and
/// [`Instruction`] itself is [`Send`].
///
/// However, it is not safe to share an [`InstructionPtr`] between threads
/// due to their [`InstructionPtr::offset`] method which relinks the
/// internal pointer and is not synchronized.
unsafe impl Send for InstructionPtr {}

impl InstructionPtr {
/// Creates a new [`InstructionPtr`] for `instr`.
#[inline]
Expand Down
10 changes: 10 additions & 0 deletions crates/wasmi/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ pub struct Store<T> {
user_state: T,
}

#[test]
fn test_store_is_send_sync() {
const _: () = {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
let _ = assert_send::<Store<()>>;
let _ = assert_sync::<Store<()>>;
};
}

impl<T> Store<T> {
/// Creates a new store.
pub fn new(engine: &Engine, user_state: T) -> Self {
Expand Down

0 comments on commit 44419e0

Please sign in to comment.