1pub use orb::AsyncRuntime;
22use orb::io::{AsyncFd, AsyncIO};
23pub use orb::runtime::{AsyncExec, AsyncJoiner, ThreadJoiner};
24use orb::time::{AsyncTime, TimeInterval};
25use std::fmt;
26use std::future::Future;
27use std::io;
28use std::net::{SocketAddr, TcpStream};
29use std::ops::Deref;
30use std::os::fd::{AsFd, AsRawFd};
31use std::os::unix::net::UnixStream;
32use std::path::Path;
33use std::pin::Pin;
34use std::sync::Arc;
35use std::task::*;
36use std::time::{Duration, Instant};
37use tokio::runtime::{Builder, Handle, Runtime};
38
39pub struct TokioRT {}
40
41impl AsyncIO for TokioRT {
42 type AsyncFd<T: AsRawFd + AsFd + Send + Sync + 'static> = TokioFD<T>;
43
44 #[inline(always)]
45 async fn connect_tcp(addr: &SocketAddr) -> io::Result<Self::AsyncFd<TcpStream>> {
46 let stream = tokio::net::TcpStream::connect(addr).await?;
47 Self::to_async_fd_rw(stream.into_std()?)
49 }
50
51 #[inline(always)]
52 async fn connect_unix(addr: &Path) -> io::Result<Self::AsyncFd<UnixStream>> {
53 let stream = tokio::net::UnixStream::connect(addr).await?;
54 Self::to_async_fd_rw(stream.into_std()?)
56 }
57
58 #[inline(always)]
59 fn to_async_fd_rd<T: AsRawFd + AsFd + Send + Sync + 'static>(
60 fd: T,
61 ) -> io::Result<Self::AsyncFd<T>> {
62 use tokio::io;
63 Ok(TokioFD(io::unix::AsyncFd::with_interest(fd, io::Interest::READABLE)?))
64 }
65
66 #[inline(always)]
67 fn to_async_fd_rw<T: AsRawFd + AsFd + Send + Sync + 'static>(
68 fd: T,
69 ) -> io::Result<Self::AsyncFd<T>> {
70 use tokio::io;
71 use tokio::io::Interest;
72 Ok(TokioFD(io::unix::AsyncFd::with_interest(fd, Interest::READABLE | Interest::WRITABLE)?))
73 }
74}
75
76impl AsyncTime for TokioRT {
77 type Interval = TokioInterval;
78
79 #[inline(always)]
80 fn sleep(d: Duration) -> impl Future + Send {
81 tokio::time::sleep(d)
82 }
83
84 #[inline(always)]
85 fn interval(d: Duration) -> Self::Interval {
86 let later = tokio::time::Instant::now() + d;
87 TokioInterval(tokio::time::interval_at(later, d))
88 }
89}
90
91impl AsyncRuntime for TokioRT {
92 type Exec = TokioExec;
93
94 fn current() -> Self::Exec {
103 TokioExec::new_current_thread()
104 }
105
106 #[inline(always)]
112 fn one() -> Self::Exec {
113 TokioExec::new_multi_thread(1)
114 }
115
116 #[inline(always)]
124 fn multi(num: usize) -> Self::Exec {
125 TokioExec::new_multi_thread(num)
126 }
127
128 #[inline]
130 fn spawn<F, R>(f: F) -> TokioJoinHandle<R>
131 where
132 F: Future<Output = R> + Send + 'static,
133 R: Send + 'static,
134 {
135 return TokioJoinHandle(tokio::spawn(f));
138 }
139
140 #[inline]
142 fn spawn_detach<F, R>(f: F)
143 where
144 F: Future<Output = R> + Send + 'static,
145 R: Send + 'static,
146 {
147 tokio::spawn(f);
148 }
149
150 #[inline(always)]
151 fn spawn_blocking<F, R>(f: F) -> TokioThreadHandle<R>
152 where
153 F: FnOnce() -> R + Send + 'static,
154 R: Send + 'static,
155 {
156 TokioThreadHandle(tokio::task::spawn_blocking(f))
157 }
158}
159
160pub struct TokioInterval(tokio::time::Interval);
162
163impl TimeInterval for TokioInterval {
164 #[inline]
165 fn poll_tick(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Instant> {
166 let _self = self.get_mut();
167 if let Poll::Ready(i) = _self.0.poll_tick(ctx) {
168 Poll::Ready(i.into_std())
169 } else {
170 Poll::Pending
171 }
172 }
173}
174
175pub struct TokioFD<T: AsRawFd + AsFd + Send + Sync + 'static>(tokio::io::unix::AsyncFd<T>);
177
178impl<T: AsRawFd + AsFd + Send + Sync + 'static> AsyncFd<T> for TokioFD<T> {
179 #[inline(always)]
180 async fn async_read<R>(&self, f: impl FnMut(&T) -> io::Result<R> + Send) -> io::Result<R> {
181 self.0.async_io(tokio::io::Interest::READABLE, f).await
182 }
183
184 #[inline(always)]
185 async fn async_write<R>(&self, f: impl FnMut(&T) -> io::Result<R> + Send) -> io::Result<R> {
186 self.0.async_io(tokio::io::Interest::WRITABLE, f).await
187 }
188}
189
190impl<T: AsRawFd + AsFd + Send + Sync + 'static> Deref for TokioFD<T> {
191 type Target = T;
192
193 #[inline(always)]
194 fn deref(&self) -> &Self::Target {
195 self.0.get_ref()
196 }
197}
198
199pub struct TokioJoinHandle<T>(tokio::task::JoinHandle<T>);
201
202impl<T: Send> AsyncJoiner<T> for TokioJoinHandle<T> {
203 #[inline]
204 fn is_finished(&self) -> bool {
205 self.0.is_finished()
206 }
207
208 #[inline]
209 fn detach(self) {
210 }
213
214 #[inline]
215 fn abort(self) {
216 self.0.abort();
217 }
218
219 #[inline(always)]
220 fn abort_boxed(self: Box<Self>) {
221 self.0.abort();
222 }
223
224 #[inline(always)]
225 fn detach_boxed(self: Box<Self>) {
226 }
229}
230
231impl<T> Future for TokioJoinHandle<T> {
232 type Output = Result<T, ()>;
233
234 #[inline]
235 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
236 let _self = unsafe { self.get_unchecked_mut() };
237 if let Poll::Ready(r) = Pin::new(&mut _self.0).poll(cx) {
238 return Poll::Ready(r.map_err(|_e| ()));
239 }
240 Poll::Pending
241 }
242}
243
244pub struct TokioThreadHandle<T>(tokio::task::JoinHandle<T>);
246
247impl<T> ThreadJoiner<T> for TokioThreadHandle<T> {
248 #[inline]
249 fn is_finished(&self) -> bool {
250 self.0.is_finished()
251 }
252}
253
254impl<T> Future for TokioThreadHandle<T> {
255 type Output = Result<T, ()>;
256
257 #[inline]
258 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
259 let _self = unsafe { self.get_unchecked_mut() };
260 if let Poll::Ready(r) = Pin::new(&mut _self.0).poll(cx) {
261 return Poll::Ready(r.map_err(|_e| ()));
262 }
263 Poll::Pending
264 }
265}
266
267pub enum TokioExec {
269 Runtime(Arc<Runtime>),
272 Handle(Handle),
273}
274
275impl Clone for TokioExec {
276 fn clone(&self) -> Self {
278 match self {
279 Self::Handle(h) => {
280 return Self::Handle(h.clone());
281 }
282 Self::Runtime(rt) => Self::Runtime(rt.clone()),
283 }
284 }
285}
286
287impl TokioExec {
288 #[inline]
290 pub fn new_with_runtime(rt: Runtime) -> Self {
291 Self::Runtime(Arc::new(rt))
292 }
293
294 #[inline]
295 pub fn new_multi_thread(workers: usize) -> Self {
296 let mut builder = Builder::new_multi_thread();
297 if workers > 0 {
298 builder.worker_threads(workers);
299 }
300 let rt = builder.enable_all().build().unwrap();
301 Self::Runtime(Arc::new(rt))
302 }
303
304 #[inline]
305 pub fn new_current_thread() -> Self {
306 let mut builder = Builder::new_current_thread();
307 let rt = builder.enable_all().build().unwrap();
308 Self::Runtime(Arc::new(rt))
309 }
310
311 #[inline]
314 pub fn new_with_handle(handle: Handle) -> Self {
315 Self::Handle(handle)
316 }
317}
318
319impl AsyncExec for TokioExec {
320 type AsyncJoiner<R: Send> = TokioJoinHandle<R>;
321
322 type ThreadJoiner<R: Send> = TokioThreadHandle<R>;
323
324 #[inline]
326 fn spawn<F, R>(&self, f: F) -> TokioJoinHandle<R>
327 where
328 F: Future<Output = R> + Send + 'static,
329 R: Send + 'static,
330 {
331 match self {
334 Self::Runtime(s) => {
335 return TokioJoinHandle(s.spawn(f));
336 }
337 Self::Handle(s) => {
338 return TokioJoinHandle(s.spawn(f));
339 }
340 }
341 }
342
343 #[inline]
345 fn spawn_detach<F, R>(&self, f: F)
346 where
347 F: Future<Output = R> + Send + 'static,
348 R: Send + 'static,
349 {
350 match self {
351 Self::Runtime(s) => {
352 s.spawn(f);
353 }
354 Self::Handle(s) => {
355 s.spawn(f);
356 }
357 }
358 }
359
360 #[inline(always)]
361 fn spawn_blocking<F, R>(&self, f: F) -> TokioThreadHandle<R>
362 where
363 F: FnOnce() -> R + Send + 'static,
364 R: Send + 'static,
365 {
366 match self {
367 Self::Runtime(s) => TokioThreadHandle(s.spawn_blocking(f)),
368 Self::Handle(s) => TokioThreadHandle(s.spawn_blocking(f)),
369 }
370 }
371
372 #[inline]
374 fn block_on<F, R>(&self, f: F) -> R
375 where
376 F: Future<Output = R>,
377 R: 'static,
378 {
379 match self {
380 Self::Runtime(s) => {
381 return s.block_on(f);
382 }
383 Self::Handle(_s) => {
384 panic!("handle is not allowed to block_on");
387 }
388 }
389 }
390}
391
392impl fmt::Debug for TokioExec {
393 #[inline]
394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 match self {
396 Self::Runtime(_) => write!(f, "tokio(rt)"),
397 Self::Handle(_) => write!(f, "tokio(handle)"),
398 }
399 }
400}