Source file src/runtime/netpoll_kqueue_event.go

     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  
     7  package 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.
    13  const kqIdent = 0xee1eb9f4
    14  
    15  func addWakeupEvent(_ 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  
    37  func 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  
    58  func 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  
    69  func 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  
    78  func netpollIsPollDescriptor(fd uintptr) bool {
    79  	return fd == uintptr(kq)
    80  }
    81  

View as plain text