nuclei/
handle.rs

1use lever::prelude::*;
2use std::fmt;
3use std::{
4    future::Future,
5    io,
6    ops::{Deref, DerefMut},
7    pin::Pin,
8    sync::Arc,
9};
10
11use crate::syscore::{CompletionChan, StoreFile};
12
13///
14/// Submitted async IO operation type
15pub type AsyncOp<T> = Pin<Box<dyn Future<Output = io::Result<T>>>>;
16
17///
18/// Operation registrar for Proactive IO, represents the outer ring that will send & receive submissions and completions respectively.
19pub trait HandleOpRegisterer {
20    fn read_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>>;
21    fn write_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>>;
22}
23
24///
25/// Handle that manages IO submitted to proactor system.
26///
27/// This handle wraps io element, its' completion channel, if file, file buffers and input output operations
28/// It is single handedly responsible for dispatching correct operations to IO driver.
29/// Speed of IO bound to speed of executor, handle neither interferes with executor nor tightly coupled.
30pub struct Handle<T> {
31    /// IO task element
32    pub(crate) io_task: Option<T>,
33    /// Notification channel
34    pub(crate) chan: Option<CompletionChan>,
35    /// File operation storage
36    pub(crate) store_file: Option<StoreFile>,
37    /// Completion callback for read
38    pub(crate) read: Arc<TTas<Option<AsyncOp<usize>>>>,
39    /// Completion callback for write
40    pub(crate) write: Arc<TTas<Option<AsyncOp<usize>>>>,
41}
42
43unsafe impl<T> Send for Handle<T> {}
44unsafe impl<T> Sync for Handle<T> {}
45
46impl<T> Handle<T> {
47    pub fn get_ref(&self) -> &T {
48        self.io_task.as_ref().unwrap()
49    }
50
51    pub fn get_mut(&mut self) -> &mut T {
52        self.io_task.as_mut().unwrap()
53    }
54
55    pub fn into_inner(mut self) -> T {
56        self.io_task.take().unwrap()
57    }
58
59    // #[cfg(all(feature = "iouring", target_os = "linux"))]
60    // unsafe_unpinned!(store_file: Option<StoreFile>);
61    //
62    // pub(crate) fn get_file(mut self: Pin<&mut Self>) -> &mut Option<StoreFile> {
63    //     self.store_file()
64    // }
65}
66
67impl<T> HandleOpRegisterer for Handle<T> {
68    fn read_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>> {
69        self.read.clone()
70    }
71
72    fn write_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>> {
73        self.write.clone()
74    }
75}
76
77impl<T> HandleOpRegisterer for &Handle<T> {
78    fn read_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>> {
79        self.read.clone()
80    }
81
82    fn write_registerer(&self) -> Arc<TTas<Option<AsyncOp<usize>>>> {
83        self.write.clone()
84    }
85}
86
87impl<T> Deref for Handle<T> {
88    type Target = T;
89
90    fn deref(&self) -> &Self::Target {
91        self.io_task.as_ref().unwrap()
92    }
93}
94
95impl<T> DerefMut for Handle<T> {
96    fn deref_mut(&mut self) -> &mut Self::Target {
97        self.io_task.as_mut().unwrap()
98    }
99}
100
101impl<T: fmt::Debug> fmt::Debug for Handle<T> {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        f.debug_struct("Handle")
104            .field("io_task", self.io_task.as_ref().unwrap())
105            .finish()
106    }
107}