Skip to content

Commit 7c500d8

Browse files
authored
Merge pull request #2096 from hermit-os/fd-enum
refactor(fd): replace `dyn ObjectInterface` with `enum Fd`
2 parents 26927c6 + 1300e33 commit 7c500d8

17 files changed

Lines changed: 255 additions & 152 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ align-address = "0.4"
315315
anstyle = { version = "1", default-features = false }
316316
async-executor = { git = "https://github.com/hermit-os/async-executor.git", branch = "no_std", default-features = false, features = ["static"] }
317317
async-lock = { version = "3.4.2", default-features = false }
318-
async-trait = "0.1.89"
319318
bit_field = "0.10"
320319
bitflags = "2"
321320
build-time = "0.1.3"
322321
crossbeam-utils = { version = "0.8", default-features = false }
322+
delegate = "0.13"
323323
document-features = { version = "0.2", optional = true }
324324
embedded-io = { version = "0.7", features = ["alloc"] }
325325
endian-num = { version = "0.2", optional = true, features = ["linux-types"] }

src/fd/delegate.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
2+
use alloc::sync::Arc;
3+
use core::mem::MaybeUninit;
4+
5+
use delegate::delegate;
6+
7+
use crate::fd::eventfd::EventFd;
8+
#[cfg(feature = "tcp")]
9+
use crate::fd::socket::tcp;
10+
#[cfg(feature = "udp")]
11+
use crate::fd::socket::udp;
12+
#[cfg(feature = "virtio-vsock")]
13+
use crate::fd::socket::vsock;
14+
use crate::fd::stdio::{
15+
GenericStderr, GenericStdin, GenericStdout, UhyveStderr, UhyveStdin, UhyveStdout,
16+
};
17+
use crate::fd::{AccessPermission, ObjectInterface, PollEvent, StatusFlags};
18+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
19+
use crate::fd::{Endpoint, ListenEndpoint, SocketOption};
20+
use crate::fs::mem::{MemDirectoryInterface, RamFileInterface, RomFileInterface};
21+
use crate::fs::uhyve::UhyveFileHandle;
22+
#[cfg(feature = "virtio-fs")]
23+
use crate::fs::virtio_fs::{VirtioFsDirectoryHandle, VirtioFsFileHandle};
24+
use crate::fs::{DirectoryReader, FileAttr, SeekWhence};
25+
use crate::io;
26+
27+
pub(crate) enum Fd {
28+
GenericStdin(GenericStdin),
29+
GenericStdout(GenericStdout),
30+
GenericStderr(GenericStderr),
31+
UhyveStdin(UhyveStdin),
32+
UhyveStdout(UhyveStdout),
33+
UhyveStderr(UhyveStderr),
34+
EventFd(EventFd),
35+
#[cfg(feature = "tcp")]
36+
TcpSocket(tcp::Socket),
37+
#[cfg(feature = "udp")]
38+
UdpSocket(udp::Socket),
39+
#[cfg(feature = "virtio-vsock")]
40+
VsockNullSocket(vsock::NullSocket),
41+
#[cfg(feature = "virtio-vsock")]
42+
VsockSocket(vsock::Socket),
43+
#[cfg(feature = "virtio-fs")]
44+
VirtioFsFileHandle(VirtioFsFileHandle),
45+
#[cfg(feature = "virtio-fs")]
46+
VirtioFsDirectoryHandle(VirtioFsDirectoryHandle),
47+
RomFileInterface(RomFileInterface),
48+
RamFileInterface(RamFileInterface),
49+
MemDirectoryInterface(MemDirectoryInterface),
50+
DirectoryReader(DirectoryReader),
51+
UhyveFileHandle(UhyveFileHandle),
52+
}
53+
54+
macro_rules! fd_from {
55+
() => {};
56+
(
57+
$(#[$meta:meta])*
58+
$ident:ident($ty:ty),
59+
$($rest:tt)*
60+
) => {
61+
$(#[$meta])*
62+
impl From<$ty> for Fd {
63+
fn from(value: $ty) -> Self {
64+
Self::$ident(value)
65+
}
66+
}
67+
68+
fd_from!($($rest)*);
69+
};
70+
}
71+
72+
fd_from! {
73+
GenericStdin(GenericStdin),
74+
GenericStdout(GenericStdout),
75+
GenericStderr(GenericStderr),
76+
UhyveStdin(UhyveStdin),
77+
UhyveStdout(UhyveStdout),
78+
UhyveStderr(UhyveStderr),
79+
EventFd(EventFd),
80+
#[cfg(feature = "tcp")]
81+
TcpSocket(tcp::Socket),
82+
#[cfg(feature = "udp")]
83+
UdpSocket(udp::Socket),
84+
#[cfg(feature = "virtio-vsock")]
85+
VsockNullSocket(vsock::NullSocket),
86+
#[cfg(feature = "virtio-vsock")]
87+
VsockSocket(vsock::Socket),
88+
#[cfg(feature = "virtio-fs")]
89+
VirtioFsFileHandle(VirtioFsFileHandle),
90+
#[cfg(feature = "virtio-fs")]
91+
VirtioFsDirectoryHandle(VirtioFsDirectoryHandle),
92+
RomFileInterface(RomFileInterface),
93+
RamFileInterface(RamFileInterface),
94+
MemDirectoryInterface(MemDirectoryInterface),
95+
DirectoryReader(DirectoryReader),
96+
UhyveFileHandle(UhyveFileHandle),
97+
}
98+
99+
impl ObjectInterface for Fd {
100+
delegate! {
101+
to match self {
102+
Self::GenericStdin(fd) => fd,
103+
Self::GenericStdout(fd) => fd,
104+
Self::GenericStderr(fd) => fd,
105+
Self::UhyveStdin(fd) => fd,
106+
Self::UhyveStdout(fd) => fd,
107+
Self::UhyveStderr(fd) => fd,
108+
Self::EventFd(fd) => fd,
109+
#[cfg(feature = "tcp")]
110+
Self::TcpSocket(fd) => fd,
111+
#[cfg(feature = "udp")]
112+
Self::UdpSocket(fd) => fd,
113+
#[cfg(feature = "virtio-vsock")]
114+
Self::VsockNullSocket(fd) => fd,
115+
#[cfg(feature = "virtio-vsock")]
116+
Self::VsockSocket(fd) => fd,
117+
#[cfg(feature = "virtio-fs")]
118+
Self::VirtioFsFileHandle(fd) => fd,
119+
#[cfg(feature = "virtio-fs")]
120+
Self::VirtioFsDirectoryHandle(fd) => fd,
121+
Self::RomFileInterface(fd) => fd,
122+
Self::RamFileInterface(fd) => fd,
123+
Self::MemDirectoryInterface(fd) => fd,
124+
Self::DirectoryReader(fd) => fd,
125+
Self::UhyveFileHandle(fd) => fd,
126+
} {
127+
async fn poll(&self, event: PollEvent) -> io::Result<PollEvent>;
128+
async fn read(&self, buf: &mut [u8]) -> io::Result<usize>;
129+
async fn write(&self, buf: &[u8]) -> io::Result<usize>;
130+
async fn lseek(&self, offset: isize, whence: SeekWhence) -> io::Result<isize>;
131+
async fn fstat(&self) -> io::Result<FileAttr>;
132+
async fn getdents(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize>;
133+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
134+
async fn accept(&mut self) -> io::Result<(Arc<async_lock::RwLock<Fd>>, Endpoint)>;
135+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
136+
async fn connect(&mut self, endpoint: Endpoint) -> io::Result<()>;
137+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
138+
async fn bind(&mut self, _name: ListenEndpoint) -> io::Result<()>;
139+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
140+
async fn listen(&mut self, _backlog: i32) -> io::Result<()>;
141+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
142+
async fn setsockopt(&self, _opt: SocketOption, _optval: bool) -> io::Result<()>;
143+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
144+
async fn getsockopt(&self, _opt: SocketOption) -> io::Result<bool>;
145+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
146+
async fn getsockname(&self) -> io::Result<Option<Endpoint>>;
147+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
148+
#[allow(dead_code)]
149+
async fn getpeername(&self) -> io::Result<Option<Endpoint>>;
150+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
151+
async fn recvfrom(&self, _buffer: &mut [MaybeUninit<u8>]) -> io::Result<(usize, Endpoint)>;
152+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
153+
async fn sendto(&self, _buffer: &[u8], _endpoint: Endpoint) -> io::Result<usize>;
154+
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
155+
async fn shutdown(&self, _how: i32) -> io::Result<()>;
156+
async fn status_flags(&self) -> io::Result<StatusFlags>;
157+
async fn set_status_flags(&mut self, _status_flags: StatusFlags) -> io::Result<()>;
158+
async fn truncate(&self, _size: usize) -> io::Result<()>;
159+
async fn chmod(&self, _access_permission: AccessPermission) -> io::Result<()>;
160+
async fn isatty(&self) -> io::Result<bool>;
161+
}
162+
}
163+
}

src/fd/eventfd.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use alloc::boxed::Box;
21
use alloc::collections::vec_deque::VecDeque;
32
use core::future::{self, Future};
43
use core::mem;
54
use core::pin::pin;
65
use core::task::{Poll, Waker, ready};
76

87
use async_lock::Mutex;
9-
use async_trait::async_trait;
108

119
use crate::errno::Errno;
1210
use crate::fd::{EventFlags, ObjectInterface, PollEvent};
@@ -44,7 +42,6 @@ impl EventFd {
4442
}
4543
}
4644

47-
#[async_trait]
4845
impl ObjectInterface for EventFd {
4946
async fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
5047
let len = mem::size_of::<u64>();

src/fd/mod.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
use alloc::boxed::Box;
21
use alloc::sync::Arc;
32
use core::future::{self, Future};
43
use core::mem::MaybeUninit;
54
use core::pin::pin;
65
use core::task::Poll::{Pending, Ready};
76
use core::time::Duration;
87

9-
use async_trait::async_trait;
108
#[cfg(feature = "net")]
119
use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
1210

11+
pub(crate) use self::delegate::Fd;
1312
use crate::arch::kernel::core_local::core_scheduler;
1413
use crate::errno::Errno;
1514
use crate::executor::block_on;
1615
use crate::fs::{FileAttr, SeekWhence};
1716
use crate::io;
1817

18+
mod delegate;
1919
mod eventfd;
2020
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
2121
pub(crate) mod socket;
@@ -196,7 +196,6 @@ impl Default for AccessPermission {
196196
}
197197
}
198198

199-
#[async_trait]
200199
pub(crate) trait ObjectInterface: Sync + Send {
201200
/// Check if an IO event is possible
202201
async fn poll(&self, _event: PollEvent) -> io::Result<PollEvent> {
@@ -234,9 +233,7 @@ pub(crate) trait ObjectInterface: Sync + Send {
234233

235234
/// `accept` a connection on a socket
236235
#[cfg(any(feature = "net", feature = "virtio-vsock"))]
237-
async fn accept(
238-
&mut self,
239-
) -> io::Result<(Arc<async_lock::RwLock<dyn ObjectInterface>>, Endpoint)> {
236+
async fn accept(&mut self) -> io::Result<(Arc<async_lock::RwLock<Fd>>, Endpoint)> {
240237
Err(Errno::Inval)
241238
}
242239

@@ -445,18 +442,16 @@ pub fn fstat(fd: RawFd) -> io::Result<FileAttr> {
445442
pub fn eventfd(initval: u64, flags: EventFlags) -> io::Result<RawFd> {
446443
let obj = self::eventfd::EventFd::new(initval, flags);
447444

448-
let fd = core_scheduler().insert_object(Arc::new(async_lock::RwLock::new(obj)))?;
445+
let fd = core_scheduler().insert_object(Arc::new(async_lock::RwLock::new(obj.into())))?;
449446

450447
Ok(fd)
451448
}
452449

453-
pub(crate) fn get_object(fd: RawFd) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
450+
pub(crate) fn get_object(fd: RawFd) -> io::Result<Arc<async_lock::RwLock<Fd>>> {
454451
core_scheduler().get_object(fd)
455452
}
456453

457-
pub(crate) fn insert_object(
458-
obj: Arc<async_lock::RwLock<dyn ObjectInterface>>,
459-
) -> io::Result<RawFd> {
454+
pub(crate) fn insert_object(obj: Arc<async_lock::RwLock<Fd>>) -> io::Result<RawFd> {
460455
core_scheduler().insert_object(obj)
461456
}
462457

@@ -472,7 +467,7 @@ pub(crate) fn dup_object2(fd1: RawFd, fd2: RawFd) -> io::Result<RawFd> {
472467
core_scheduler().dup_object2(fd1, fd2)
473468
}
474469

475-
pub(crate) fn remove_object(fd: RawFd) -> io::Result<Arc<async_lock::RwLock<dyn ObjectInterface>>> {
470+
pub(crate) fn remove_object(fd: RawFd) -> io::Result<Arc<async_lock::RwLock<Fd>>> {
476471
core_scheduler().remove_object(fd)
477472
}
478473

src/fd/socket/tcp.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
use alloc::boxed::Box;
21
use alloc::collections::BTreeSet;
32
use alloc::sync::Arc;
43
use core::future;
54
use core::sync::atomic::{AtomicU16, Ordering};
65
use core::task::Poll;
76

8-
use async_trait::async_trait;
97
use smoltcp::iface;
108
use smoltcp::socket::tcp;
119
use smoltcp::time::Duration;
@@ -14,7 +12,7 @@ use smoltcp::wire::{IpEndpoint, Ipv4Address, Ipv6Address};
1412
use crate::errno::Errno;
1513
use crate::executor::block_on;
1614
use crate::executor::network::{Handle, NIC, wake_network_waker};
17-
use crate::fd::{self, Endpoint, ListenEndpoint, ObjectInterface, PollEvent, SocketOption};
15+
use crate::fd::{self, Endpoint, Fd, ListenEndpoint, ObjectInterface, PollEvent, SocketOption};
1816
use crate::syscalls::socket::Af;
1917
use crate::{DEFAULT_KEEP_ALIVE_INTERVAL, io};
2018

@@ -115,7 +113,6 @@ impl Socket {
115113
}
116114
}
117115

118-
#[async_trait]
119116
impl ObjectInterface for Socket {
120117
async fn poll(&self, event: PollEvent) -> io::Result<PollEvent> {
121118
future::poll_fn(|cx| {
@@ -308,9 +305,7 @@ impl ObjectInterface for Socket {
308305
.await
309306
}
310307

311-
async fn accept(
312-
&mut self,
313-
) -> io::Result<(Arc<async_lock::RwLock<dyn ObjectInterface>>, Endpoint)> {
308+
async fn accept(&mut self) -> io::Result<(Arc<async_lock::RwLock<Fd>>, Endpoint)> {
314309
if !self.is_listen {
315310
self.listen(DEFAULT_BACKLOG).await?;
316311
}
@@ -369,7 +364,7 @@ impl ObjectInterface for Socket {
369364
is_listen: false,
370365
};
371366

372-
Ok((Arc::new(async_lock::RwLock::new(socket)), endpoint))
367+
Ok((Arc::new(async_lock::RwLock::new(socket.into())), endpoint))
373368
}
374369

375370
async fn getpeername(&self) -> io::Result<Option<Endpoint>> {

src/fd/socket/udp.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use alloc::boxed::Box;
21
use core::future;
32
use core::mem::MaybeUninit;
43
use core::task::Poll;
54

6-
use async_trait::async_trait;
75
use smoltcp::socket::udp;
86
use smoltcp::socket::udp::UdpMetadata;
97
use smoltcp::wire::{IpEndpoint, Ipv4Address, Ipv6Address};
@@ -77,7 +75,6 @@ impl Socket {
7775
}
7876
}
7977

80-
#[async_trait]
8178
impl ObjectInterface for Socket {
8279
async fn poll(&self, event: PollEvent) -> io::Result<PollEvent> {
8380
future::poll_fn(|cx| {

0 commit comments

Comments
 (0)