Skip to content

Commit c1ad4ba

Browse files
wllenyjjiangliu
authored andcommitted
async_file: improved async file implement
Currently, the io-uring crate has implemented functions such as readv/readv_at etc, so there is no need to use RawFd to implement. Signed-off-by: wanglei01 <[email protected]>
1 parent 11ab2ee commit c1ad4ba

File tree

1 file changed

+13
-57
lines changed

1 file changed

+13
-57
lines changed

src/common/async_file.rs

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub enum File {
1919
Tokio(tokio::fs::File),
2020
#[cfg(target_os = "linux")]
2121
/// Tokio-uring asynchronous `File`.
22-
Uring(RawFd),
22+
Uring(tokio_uring::fs::File),
2323
}
2424

2525
impl File {
@@ -44,13 +44,7 @@ impl File {
4444
.create(create)
4545
.open(path)
4646
.await
47-
.map(|v| {
48-
// Convert the tokio_uring::fs::File object into RawFd(): v.into_raw_fd().
49-
let file = File::Uring(v.as_raw_fd());
50-
std::mem::forget(v);
51-
file
52-
}),
53-
_ => panic!("should not happen"),
47+
.map(File::Uring),
5448
}
5549
}
5650

@@ -69,15 +63,7 @@ impl File {
6963
(res, bufs[0])
7064
}
7165
#[cfg(target_os = "linux")]
72-
File::Uring(fd) => {
73-
// Safety: we rely on tokio_uring::fs::File internal implementation details.
74-
// It should be implemented as self.async_try_clone().await.unwrap().read_at,
75-
// but that causes two more syscalls.
76-
let file = unsafe { tokio_uring::fs::File::from_raw_fd(*fd) };
77-
let res = file.read_at(buf, offset).await;
78-
std::mem::forget(file);
79-
res
80-
}
66+
File::Uring(f) => f.read_at(buf, offset).await,
8167
}
8268
}
8369

@@ -95,15 +81,7 @@ impl File {
9581
(res, bufs)
9682
}
9783
#[cfg(target_os = "linux")]
98-
File::Uring(fd) => {
99-
// Safety: we rely on tokio_uring::fs::File internal implementation details.
100-
// It should be implemented as self.async_try_clone().await.unwrap().readv_at,
101-
// but that causes two more syscalls.
102-
let file = unsafe { tokio_uring::fs::File::from_raw_fd(*fd) };
103-
let res = file.readv_at(bufs, offset).await;
104-
std::mem::forget(file);
105-
res
106-
}
84+
File::Uring(f) => f.readv_at(bufs, offset).await,
10785
}
10886
}
10987

@@ -122,15 +100,7 @@ impl File {
122100
(res, bufs[0])
123101
}
124102
#[cfg(target_os = "linux")]
125-
File::Uring(fd) => {
126-
// Safety: we rely on tokio_uring::fs::File internal implementation details.
127-
// It should be implemented as self.async_try_clone().await.unwrap().write_at,
128-
// but that causes two more syscalls.
129-
let file = unsafe { tokio_uring::fs::File::from_raw_fd(*fd) };
130-
let res = file.write_at(buf, offset).await;
131-
std::mem::forget(file);
132-
res
133-
}
103+
File::Uring(f) => f.write_at(buf, offset).await,
134104
}
135105
}
136106

@@ -148,15 +118,7 @@ impl File {
148118
(res, bufs)
149119
}
150120
#[cfg(target_os = "linux")]
151-
File::Uring(fd) => {
152-
// Safety: we rely on tokio_uring::fs::File internal implementation details.
153-
// It should be implemented as self.async_try_clone().await.unwrap().writev_at,
154-
// but that causes two more syscalls.
155-
let file = unsafe { tokio_uring::fs::File::from_raw_fd(*fd) };
156-
let res = file.writev_at(bufs, offset).await;
157-
std::mem::forget(file);
158-
res
159-
}
121+
File::Uring(f) => f.writev_at(bufs, offset).await,
160122
}
161123
}
162124

@@ -174,13 +136,16 @@ impl File {
174136
match self {
175137
File::Tokio(f) => f.try_clone().await.map(File::Tokio),
176138
#[cfg(target_os = "linux")]
177-
File::Uring(fd) => {
139+
File::Uring(f) => {
178140
// Safe because file.as_raw_fd() is valid RawFd and we have checked the result.
179-
let fd = unsafe { libc::dup(*fd) };
141+
let fd = unsafe { libc::dup(f.as_raw_fd()) };
180142
if fd < 0 {
181143
Err(std::io::Error::last_os_error())
182144
} else {
183-
Ok(File::Uring(fd))
145+
// Safe because we dup a new raw fd.
146+
Ok(File::Uring(unsafe {
147+
tokio_uring::fs::File::from_raw_fd(fd)
148+
}))
184149
}
185150
}
186151
}
@@ -192,7 +157,7 @@ impl AsRawFd for File {
192157
match self {
193158
File::Tokio(f) => f.as_raw_fd(),
194159
#[cfg(target_os = "linux")]
195-
File::Uring(fd) => *fd,
160+
File::Uring(f) => f.as_raw_fd(),
196161
}
197162
}
198163
}
@@ -204,15 +169,6 @@ impl Debug for File {
204169
}
205170
}
206171

207-
impl Drop for File {
208-
fn drop(&mut self) {
209-
#[cfg(target_os = "linux")]
210-
if let File::Uring(fd) = self {
211-
let _ = unsafe { tokio_uring::fs::File::from_raw_fd(*fd) };
212-
}
213-
}
214-
}
215-
216172
/// A simple wrapper over posix `preadv` to deal with `FileVolatileBuf`.
217173
pub fn preadv(fd: RawFd, bufs: &mut [FileVolatileBuf], offset: u64) -> std::io::Result<usize> {
218174
let iov: Vec<IoSliceMut> = bufs.iter().map(|v| v.io_slice_mut()).collect();

0 commit comments

Comments
 (0)