1// Copyright 2024 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5//go:build darwin || dragonfly || freebsd 6 7package runtime 8 9// Magic number of identifier used for EVFILT_USER. 10// This number had zero Google results when it's created. 11// That way, people will be directed here when this number 12// get printed somehow and they search for it. 13const kqIdent = 0xee1eb9f4 14 15func addWakeupEvent(kq int32) { 16 ev := keventt{ 17 ident: kqIdent, 18 filter: _EVFILT_USER, 19 flags: _EV_ADD, 20 } 21 for { 22 n := kevent(kq, &ev, 1, nil, 0, nil) 23 if n == 0 { 24 break 25 } 26 if n == -_EINTR { 27 // All changes contained in the changelist should have been applied 28 // before returning EINTR. But let's be skeptical and retry it anyway, 29 // to make a 100% commitment. 30 continue 31 } 32 println("runtime: kevent for EVFILT_USER failed with", -n) 33 throw("runtime: kevent failed") 34 } 35} 36 37func wakeNetpoll(kq int32) { 38 ev := keventt{ 39 ident: kqIdent, 40 filter: _EVFILT_USER, 41 flags: _EV_ENABLE, 42 fflags: _NOTE_TRIGGER, 43 } 44 for { 45 n := kevent(kq, &ev, 1, nil, 0, nil) 46 if n == 0 { 47 break 48 } 49 if n == -_EINTR { 50 // Check out the comment in addWakeupEvent. 51 continue 52 } 53 println("runtime: netpollBreak write failed with", -n) 54 throw("runtime: netpollBreak write failed") 55 } 56} 57 58func isWakeup(ev *keventt) bool { 59 if ev.filter == _EVFILT_USER { 60 if ev.ident == kqIdent { 61 return true 62 } 63 println("runtime: netpoll: break fd ready for", ev.ident) 64 throw("runtime: netpoll: break fd ready for something unexpected") 65 } 66 return false 67} 68 69func drainWakeupEvent(kq int32) { 70 ev := keventt{ 71 ident: kqIdent, 72 filter: _EVFILT_USER, 73 flags: _EV_DISABLE, 74 } 75 kevent(kq, &ev, 1, nil, 0, nil) 76} 77 78func netpollIsPollDescriptor(fd uintptr) bool { 79 return fd == uintptr(kq) 80} 81