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(kq int32) {
    16  	ev := keventt{
    17  		ident:  kqIdent,
    18  		filter: _EVFILT_USER,
    19  		flags:  _EV_ADD | _EV_CLEAR,
    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  		fflags: _NOTE_TRIGGER,
    42  	}
    43  	for {
    44  		n := kevent(kq, &ev, 1, nil, 0, nil)
    45  		if n == 0 {
    46  			break
    47  		}
    48  		if n == -_EINTR {
    49  			// Check out the comment in addWakeupEvent.
    50  			continue
    51  		}
    52  		println("runtime: netpollBreak write failed with", -n)
    53  		throw("runtime: netpollBreak write failed")
    54  	}
    55  }
    56  
    57  func isWakeup(ev *keventt) bool {
    58  	if ev.filter == _EVFILT_USER {
    59  		if ev.ident == kqIdent {
    60  			return true
    61  		}
    62  		println("runtime: netpoll: break fd ready for", ev.ident)
    63  		throw("runtime: netpoll: break fd ready for something unexpected")
    64  	}
    65  	return false
    66  }
    67  
    68  func processWakeupEvent(kq int32, isBlocking bool) {
    69  	if !isBlocking {
    70  		// Got a wrong thread, relay
    71  		wakeNetpoll(kq)
    72  	}
    73  }
    74  
    75  func netpollIsPollDescriptor(fd uintptr) bool {
    76  	return fd == uintptr(kq)
    77  }
    78  

View as plain text