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> {12x34
Ok(Notifier {35
fd: File::open("/dev/null")?.into(),12x36
registered: None,12x37
})38
}12x39
40
pub fn notify(&self) -> Result<()> {21x41
let Some((token, kqfd)) = &self.registered else {21x42
return Err(ErrorKind::NotFound.into());43
};44
let event = libc::kevent {21x45
ident: self.fd.as_raw_fd() as _,21x46
filter: libc::EVFILT_USER,21x47
flags: libc::EV_ADD | libc::EV_RECEIPT,21x48
fflags: libc::NOTE_TRIGGER,21x49
data: 0,21x50
udata: token.0 as _,21x51
};21x52
ffi!(unsafe { libc::kevent(kqfd.as_raw_fd(), &event, 1, null_mut(), 0, null()) })?;21x53
Ok(())21x54
}21x55
}56
57
impl Source for Notifier {58
fn register(&mut self, registry: &Registry, token: Token, _: Interest) -> Result<()> {12x59
let event = libc::kevent {12x60
ident: self.fd.as_raw_fd() as _,12x61
filter: libc::EVFILT_USER,12x62
flags: libc::EV_ADD | libc::EV_CLEAR | libc::EV_RECEIPT,12x63
fflags: 0,12x64
data: 0,12x65
udata: null_mut(),12x66
};12x67
68
let kqfd = registry.as_raw_fd();12x69
let kqfd = ffi!(unsafe { libc::dup(kqfd) })?;12x70
let kqfd = unsafe { OwnedFd::from_raw_fd(kqfd) };12x71
72
ffi!(unsafe { libc::kevent(kqfd.as_raw_fd(), &event, 1, null_mut(), 0, null()) })?;12x73
self.registered = Some((token, kqfd));12x74
Ok(())12x75
}12x76
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