Piotr OsiewiczRust 1.85 (#25272)e4e758d1 year agoHistory
107 lines · 2.8 KB · Rust
RawDownload
#![allow(non_upper_case_globals)]#![allow(non_camel_case_types)]#![allow(non_snake_case)] use crate::{PlatformDispatcher, TaskLabel};use async_task::Runnable;use objc::{    class, msg_send,    runtime::{BOOL, YES},    sel, sel_impl,};use parking::{Parker, Unparker};use parking_lot::Mutex;use std::{    ffi::c_void,    ptr::{addr_of, NonNull},    sync::Arc,    time::Duration,}; /// All items in the generated file are marked as pub, so we're gonna wrap it in a separate mod to prevent/// these pub items from leaking into public API.pub(crate) mod dispatch_sys {    include!(concat!(env!("OUT_DIR"), "/dispatch_sys.rs"));} use dispatch_sys::*;pub(crate) fn dispatch_get_main_queue() -> dispatch_queue_t {    addr_of!(_dispatch_main_q) as *const _ as dispatch_queue_t} pub(crate) struct MacDispatcher {    parker: Arc<Mutex<Parker>>,} impl Default for MacDispatcher {    fn default() -> Self {        Self::new()    }} impl MacDispatcher {    pub fn new() -> Self {        MacDispatcher {            parker: Arc::new(Mutex::new(Parker::new())),        }    }} impl PlatformDispatcher for MacDispatcher {    fn is_main_thread(&self) -> bool {        let is_main_thread: BOOL = unsafe { msg_send![class!(NSThread), isMainThread] };        is_main_thread == YES    }     fn dispatch(&self, runnable: Runnable, _: Option<TaskLabel>) {        unsafe {            dispatch_async_f(                dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH.try_into().unwrap(), 0),                runnable.into_raw().as_ptr() as *mut c_void,                Some(trampoline),            );        }    }     fn dispatch_on_main_thread(&self, runnable: Runnable) {        unsafe {            dispatch_async_f(                dispatch_get_main_queue(),                runnable.into_raw().as_ptr() as *mut c_void,                Some(trampoline),            );        }    }     fn dispatch_after(&self, duration: Duration, runnable: Runnable) {        unsafe {            let queue =                dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH.try_into().unwrap(), 0);            let when = dispatch_time(DISPATCH_TIME_NOW as u64, duration.as_nanos() as i64);            dispatch_after_f(                when,                queue,                runnable.into_raw().as_ptr() as *mut c_void,                Some(trampoline),            );        }    }     fn park(&self, timeout: Option<Duration>) -> bool {        if let Some(timeout) = timeout {            self.parker.lock().park_timeout(timeout)        } else {            self.parker.lock().park();            true        }    }     fn unparker(&self) -> Unparker {        self.parker.lock().unparker()    }} extern "C" fn trampoline(runnable: *mut c_void) {    let task = unsafe { Runnable::<()>::from_raw(NonNull::new_unchecked(runnable as *mut ())) };    task.run();}