Skip to main content

kioto_uring_executor/
lib.rs

1use std::future::Future;
2use std::sync::mpsc as std_mpsc;
3
4#[cfg(feature = "macros")]
5pub use kioto_uring_executor_macros::{main, test};
6
7mod runtime;
8pub use runtime::{Runtime, SpawnRing};
9
10use runtime::ACTIVE_RUNTIME;
11
12/// Emulates tokio's block_on call
13///
14/// This will spawn a new tokio runtime on the current thread
15pub fn block_on<T: 'static, F: Future<Output = T> + 'static>(task: F) -> T {
16    tokio_uring::start(task)
17}
18
19/// Create a primitive that lets you distribute tasks
20/// across worker threads in a round-robin fashion
21pub fn new_spawn_ring() -> SpawnRing {
22    ACTIVE_RUNTIME.with_borrow(|r| {
23        let inner = r.as_ref().expect("No active runtime").clone();
24
25        SpawnRing::new(inner)
26    })
27}
28
29/// Spawns the task on a random thread
30pub fn spawn<F: Future<Output = ()> + Send + 'static>(task: F) {
31    ACTIVE_RUNTIME.with_borrow(|r| r.as_ref().expect("No active runtime").spawn(task))
32}
33
34/// Spawns the task on a specific thread
35pub fn spawn_at<F: Future<Output = ()> + Send + 'static>(offset: usize, task: F) {
36    ACTIVE_RUNTIME.with_borrow(|r| {
37        r.as_ref()
38            .expect("No active runtime")
39            .spawn_at(offset, task)
40    })
41}
42
43/// Emulates tokio's block_on call
44///
45/// This will use an existing exeuctor
46pub fn block_on_runtime<T: Send + 'static, F: Future<Output = T> + Send + 'static>(task: F) -> T {
47    ACTIVE_RUNTIME.with_borrow(|r| r.as_ref().expect("No active runtime").block_on(task))
48}
49
50/// Emulates tokio's block_on call
51///
52/// # Safety
53/// Make sure task is Send before polled for the first time
54/// (Can be not Send afterwards)
55pub unsafe fn unsafe_block_on_runtime<T: 'static, F: Future<Output = T> + 'static>(task: F) -> T {
56    let (sender, receiver) = std_mpsc::channel();
57
58    unsafe_spawn(async move {
59        let res = task.await;
60        sender.send(res).expect("Notification failed");
61    });
62
63    receiver.recv().expect("Failed to wait for task")
64}
65
66/// # Safety
67///
68/// Make sure task is Send before polled for the first time
69/// (Can be not Send afterwards)
70pub unsafe fn unsafe_spawn<F: Future<Output = ()> + 'static>(task: F) {
71    ACTIVE_RUNTIME.with_borrow(|r| r.as_ref().expect("No active runtime").unsafe_spawn(task))
72}
73
74/// # Safety
75///
76/// Make sure task is Send before polled for the first time
77/// (Can be not Send afterwards)
78pub unsafe fn unsafe_spawn_at<F: Future<Output = ()> + 'static>(offset: usize, task: F) {
79    ACTIVE_RUNTIME.with_borrow(|r| {
80        r.as_ref()
81            .expect("No active runtime")
82            .unsafe_spawn_at(offset, task)
83    })
84}