Crate ste[][src]

Documentation Crates Actions Status

A single-threaded executor with some tricks up its sleeve.

This was primarily written for use in rotary as a low-latency way of interacting with a single background thread for audio-related purposes, but is otherwise a general purpose library that can be used by anyone.

Soundness Warning: This crate uses a fair bit of unsafe. Some of the tricks employed needs to be rigirously sanity checked for safety before you can rely on this for production uses.

The default way to access the underlying thread is through the submit method. This blocks the current thread for the duration of the task allowing the background thread to access variables which are in scope. Like n below.

let thread = ste::Thread::new()?;

let mut n = 10;
thread.submit(|| n += 10)?;
assert_eq!(20, n);

thread.join()?;

Restricting which threads can access data

We provide the Tagged container. Things stored in this container may only be accessed by the thread in which the container was created.

It works by associating a tag with the data that is unique to the thread which created it. Any attempt to access the data will check this tag against the tag in the current thread.

struct Foo;

impl Foo {
    fn say_hello(&self) {
        println!("Hello World!");
    }
}

let thread = ste::Thread::new()?;

let foo = thread.submit(|| ste::Tagged::new(Foo))?;
foo.say_hello(); // <- Panics!

thread.join()?;

Using it inside of the thread that created it is fine.

let thread = ste::Thread::new()?;

let foo = thread.submit(|| ste::Tagged::new(Foo))?;

thread.submit(|| {
    foo.say_hello(); // <- OK!
})?;

thread.join()?;

There are some other details you need to know relevant to how to use the Tagged container. See its documentation for more.

Known unsafety and soundness issues

Below you can find a list of known soundness issues this library currently has.

Pointers to stack-local addresses

In order to efficiently share data between a thread calling submit and the background thread, the background thread references a fair bit of stack-local data from the calling thread which involves a fair bit of unsafe.

While it should be possible to make this use safe (as is the hope of this library), it carries a risk that if the background thread were to proceed executing a task that is no longer synchronized properly with a caller of submit it might end up referencing data which is either no longer valid (use after free), or contains something else (dirty).

Soundness issue with tag re-use

Tagged containers currently use a tag based on the address of a slab of allocated memory that is associated with each Thread. If however a Thread is shut down, and a new later recreated, there is a slight risk that this might re-use an existing memory address.

Memory addresses are quite thankful to use, because they’re cheap and quite easy to access. Due to this it might however be desirable to use a generated ID per thread instead which can for example abort a program in case it can’t guarantee uniqueness.

Structs

Builder

The builder for a Thread which can be configured a bit more.

Panicked

Error raised when we try to interact with a background thread that has panicked.

Tagged

An object T which can only be used on the thread with the corresponding tag.

Thread

The handle for a background thread.