blob: d5f783e607e8469a45a399965e7daa65b34196f3 [file] [log] [blame] [edit]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd
package runtime
// Magic number of identifier used for EVFILT_USER.
// This number had zero Google results when it's created.
// That way, people will be directed here when this number
// get printed somehow and they search for it.
const kqIdent = 0xee1eb9f4
func addWakeupEvent(kq int32) {
ev := keventt{
ident: kqIdent,
filter: _EVFILT_USER,
flags: _EV_ADD,
}
for {
n := kevent(kq, &ev, 1, nil, 0, nil)
if n == 0 {
break
}
if n == -_EINTR {
// All changes contained in the changelist should have been applied
// before returning EINTR. But let's be skeptical and retry it anyway,
// to make a 100% commitment.
continue
}
println("runtime: kevent for EVFILT_USER failed with", -n)
throw("runtime: kevent failed")
}
}
func wakeNetpoll(kq int32) {
ev := keventt{
ident: kqIdent,
filter: _EVFILT_USER,
flags: _EV_ENABLE,
fflags: _NOTE_TRIGGER,
}
for {
n := kevent(kq, &ev, 1, nil, 0, nil)
if n == 0 {
break
}
if n == -_EINTR {
// Check out the comment in addWakeupEvent.
continue
}
println("runtime: netpollBreak write failed with", -n)
throw("runtime: netpollBreak write failed")
}
}
func isWakeup(ev *keventt) bool {
if ev.filter == _EVFILT_USER {
if ev.ident == kqIdent {
return true
}
println("runtime: netpoll: break fd ready for", ev.ident)
throw("runtime: netpoll: break fd ready for something unexpected")
}
return false
}
func drainWakeupEvent(kq int32) {
ev := keventt{
ident: kqIdent,
filter: _EVFILT_USER,
flags: _EV_DISABLE,
}
kevent(kq, &ev, 1, nil, 0, nil)
}
func netpollIsPollDescriptor(fd uintptr) bool {
return fd == uintptr(kq)
}