notifier_macos.rs92.16%
1
// Copyright 2025 Google LLC2
//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 at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// 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 and13
// limitations under the License.14
15
use std::fs::File;16
use std::io::{ErrorKind, Result};17
use std::os::fd::{FromRawFd, OwnedFd};18
use std::os::unix::io::AsRawFd;19
use std::ptr::{null, null_mut};20
21
use mio::event::Source;22
use mio::{Interest, Registry, Token};23
24
use crate::ffi;25
26
#[derive(Debug)]27
pub struct Notifier {28
fd: OwnedFd,29
registered: Option<(Token, OwnedFd)>,30
}31
32
impl Notifier {33
pub fn new() -> Result<Self> {24x34
Ok(Notifier {35
fd: File::open("/dev/null")?.into(),24x36
registered: None,24x37
})38
}24x39
40
pub fn notify(&self) -> Result<()> {29x41
let Some((token, kqfd)) = &self.registered else {29x42
return Err(ErrorKind::NotFound.into());43
};44
let event = libc::kevent {29x45
ident: self.fd.as_raw_fd() as _,29x46
filter: libc::EVFILT_USER,29x47
flags: libc::EV_ADD | libc::EV_RECEIPT,29x48
fflags: libc::NOTE_TRIGGER,29x49
data: 0,29x50
udata: token.0 as _,29x51
};29x52
ffi!(unsafe { libc::kevent(kqfd.as_raw_fd(), &event, 1, null_mut(), 0, null()) })?;29x53
Ok(())29x54
}29x55
}56
57
impl Source for Notifier {58
fn register(&mut self, registry: &Registry, token: Token, _: Interest) -> Result<()> {24x59
let event = libc::kevent {24x60
ident: self.fd.as_raw_fd() as _,24x61
filter: libc::EVFILT_USER,24x62
flags: libc::EV_ADD | libc::EV_CLEAR | libc::EV_RECEIPT,24x63
fflags: 0,24x64
data: 0,24x65
udata: null_mut(),24x66
};24x67
68
let kqfd = registry.as_raw_fd();24x69
let kqfd = ffi!(unsafe { libc::dup(kqfd) })?;24x70
let kqfd = unsafe { OwnedFd::from_raw_fd(kqfd) };24x71
72
ffi!(unsafe { libc::kevent(kqfd.as_raw_fd(), &event, 1, null_mut(), 0, null()) })?;24x73
self.registered = Some((token, kqfd));24x74
Ok(())24x75
}24x76
77
fn deregister(&mut self, registry: &Registry) -> Result<()> {2x78
let event = libc::kevent {2x79
ident: self.fd.as_raw_fd() as _,2x80
filter: libc::EVFILT_USER,2x81
flags: libc::EV_DELETE | libc::EV_RECEIPT,2x82
fflags: 0,2x83
data: 0,2x84
udata: null_mut(),2x85
};2x86
87
let kqfd = registry.as_raw_fd();2x88
89
ffi!(unsafe { libc::kevent(kqfd, &event, 1, null_mut(), 0, null()) })?;2x90
self.registered = None;2x91
Ok(())2x92
}2x93
94
fn reregister(&mut self, _: &Registry, _: Token, _: Interest) -> Result<()> {95
Err(ErrorKind::Unsupported.into())96
}97
}98