Skip to content

Commit 65352c7

Browse files
sami-danielSami Daniel
authored andcommitted
Simplify and optimize inotify and fanotify read_events APIs
Remove logic with `MaybeUninit` + `copy_nonoverlapping` and use `ptr::read_unaligned`, leaving the code more concise and clean on both sides, without the redundant check using `.min()` Use `Vec::with_capacity(nread / size)` instead of allocating empty space. Useful for increasing performance in case of event bursts. Allocates space to spare, but is still more performant than allocating almost empty space.
1 parent dad24fb commit 65352c7

File tree

2 files changed

+28
-32
lines changed

2 files changed

+28
-32
lines changed

src/sys/fanotify.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::fcntl::OFlag;
1515
use crate::unistd::{close, read, write};
1616
use crate::{NixPath, Result};
1717
use std::marker::PhantomData;
18-
use std::mem::{size_of, MaybeUninit};
18+
use std::mem::{size_of};
1919
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
2020
use std::ptr;
2121

@@ -358,21 +358,18 @@ impl Fanotify {
358358
let metadata_size = size_of::<libc::fanotify_event_metadata>();
359359
const BUFSIZ: usize = 4096;
360360
let mut buffer = [0u8; BUFSIZ];
361-
let mut events = Vec::new();
362361
let mut offset = 0;
363362

364363
let nread = read(&self.fd, &mut buffer)?;
365364

365+
let mut events = Vec::with_capacity(nread / metadata_size);
366+
366367
while (nread - offset) >= metadata_size {
367368
let metadata = unsafe {
368-
let mut metadata =
369-
MaybeUninit::<libc::fanotify_event_metadata>::uninit();
370-
ptr::copy_nonoverlapping(
371-
buffer.as_ptr().add(offset),
372-
metadata.as_mut_ptr().cast(),
373-
(BUFSIZ - offset).min(metadata_size),
374-
);
375-
metadata.assume_init()
369+
ptr::read_unaligned(
370+
buffer.as_ptr().add(offset)
371+
as *const libc::fanotify_event_metadata,
372+
)
376373
};
377374

378375
events.push(FanotifyEvent(metadata));

src/sys/inotify.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use crate::unistd::read;
2828
use crate::NixPath;
2929
use crate::Result;
3030
use cfg_if::cfg_if;
31-
use libc::{c_char, c_int};
32-
use std::ffi::{CStr, OsStr, OsString};
33-
use std::mem::{size_of, MaybeUninit};
31+
use libc::c_int;
32+
use std::ffi::{OsStr, OsString};
33+
use std::mem::size_of;
3434
use std::os::unix::ffi::OsStrExt;
3535
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
3636
use std::ptr;
@@ -204,33 +204,32 @@ impl Inotify {
204204
let header_size = size_of::<libc::inotify_event>();
205205
const BUFSIZ: usize = 4096;
206206
let mut buffer = [0u8; BUFSIZ];
207-
let mut events = Vec::new();
208-
let mut offset = 0;
209207

210208
let nread = read(&self.fd, &mut buffer)?;
211209

210+
let mut events = Vec::with_capacity(nread / header_size);
211+
let mut offset = 0;
212+
212213
while (nread - offset) >= header_size {
213214
let event = unsafe {
214-
let mut event = MaybeUninit::<libc::inotify_event>::uninit();
215-
ptr::copy_nonoverlapping(
216-
buffer.as_ptr().add(offset),
217-
event.as_mut_ptr().cast(),
218-
(BUFSIZ - offset).min(header_size),
219-
);
220-
event.assume_init()
215+
ptr::read_unaligned(
216+
buffer.as_ptr().add(offset)
217+
as *const libc::inotify_event,
218+
)
221219
};
222220

223-
let name = match event.len {
224-
0 => None,
225-
_ => {
226-
let ptr = unsafe {
227-
buffer.as_ptr().add(offset + header_size)
228-
as *const c_char
229-
};
230-
let cstr = unsafe { CStr::from_ptr(ptr) };
221+
let name = if event.len == 0 {
222+
None
223+
} else {
224+
let name_start = offset + header_size;
225+
let name_bytes =
226+
&buffer[name_start..name_start + event.len as usize];
231227

232-
Some(OsStr::from_bytes(cstr.to_bytes()).to_owned())
233-
}
228+
let len = name_bytes
229+
.iter()
230+
.position(|&b| b == 0)
231+
.unwrap_or(name_bytes.len());
232+
Some(OsStr::from_bytes(&name_bytes[..len]).to_owned())
234233
};
235234

236235
events.push(InotifyEvent {

0 commit comments

Comments
 (0)