Skip to content

Add a way to mark things that can only be done on the main thread #27

@madsmtm

Description

@madsmtm

Many things on NSApplication (e.g. -run, ...) require being done on the main thread; this is something we should clearly communicate in the type system!

See the winit code for more examples of where it's required (NSWindow, ...).
See also the following links:

Idea:

// No lifetime information needed; the main thread is static and available through the entire program!
// And even if it wasn't, the marker can't be passed to another thread
struct MainThreadMarker {
   _priv: (),
}

impl !Send for MainThreadMarker {}
impl !Sync for MainThreadMarker {}

impl MainThreadMarker {
    fn new() -> Option<Self> {
        if is_main_thread!() {
            Some(Self {
                _priv: ()
            })
        } else {
            None
        }
    }
    fn new_unchecked() -> Self {
        ...
    }
}

// This is valid to clone because it's still `!Send` and `!Sync`.
impl Clone for MainThreadMarker {...}
impl Copy for MainThreadMarker {}

// Usage
impl NSWindow {
    fn do_thing(_mt: MainThreadMarker) {
        // This action requires the main thread, so we take one as a parameter.
        // It signals clearly to users "hey, this requires the main thread"
    }
}

impl dispatch::Queue {
    fn run_on_main_async(f: impl FnOnce(mt: MainThreadMarker) + Send) {}

    // fn run_on_main_sync ...
}

Queue::run_on_main_async(|mt| {
    ns_window.do_thing(mt);
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions