Alioth Code Coverage

notifier_linux.rs56.67%

1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fs::File;
16use std::io::{ErrorKind, Read, Result, Write};
17use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd};
18
19use libc::{EFD_CLOEXEC, EFD_NONBLOCK, eventfd};
20use mio::event::Source;
21use mio::unix::SourceFd;
22use mio::{Interest, Registry, Token};
23
24use crate::ffi;
25
26#[derive(Debug)]
27pub struct Notifier {
28 fd: File,
29}
30
31impl Notifier {
32 pub fn new() -> Result<Self> {8x
33 let fd = ffi!(unsafe { eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK) })?;8x
34 Ok(Notifier {8x
35 fd: unsafe { File::from_raw_fd(fd) },8x
36 })8x
37 }8x
38
39 pub fn notify(&self) -> Result<()> {30x
40 let mut fd = &self.fd;30x
41 let Err(e) = fd.write(&1u64.to_ne_bytes()) else {30x
42 return Ok(());30x
43 };
44 if e.kind() != ErrorKind::WouldBlock {
45 return Err(e);
46 };
47 let mut buf = [0u8; 8];
48 let _ = fd.read(&mut buf)?;
49 let _ = fd.write(&1u64.to_ne_bytes())?;
50 Ok(())
51 }30x
52}
53
54impl Source for Notifier {
55 fn register(&mut self, registry: &Registry, token: Token, interests: Interest) -> Result<()> {8x
56 registry.register(&mut SourceFd(&self.fd.as_raw_fd()), token, interests)8x
57 }8x
58
59 fn reregister(&mut self, registry: &Registry, token: Token, interests: Interest) -> Result<()> {
60 registry.reregister(&mut SourceFd(&self.fd.as_raw_fd()), token, interests)
61 }
62
63 fn deregister(&mut self, registry: &Registry) -> std::io::Result<()> {4x
64 registry.deregister(&mut SourceFd(&self.fd.as_raw_fd()))4x
65 }4x
66}
67
68impl AsFd for Notifier {
69 fn as_fd(&self) -> BorrowedFd<'_> {
70 self.fd.as_fd()
71 }
72}
73