summaryrefslogtreecommitdiffstats
path: root/contrib/go/_std_1.25/src/runtime/netpoll_kqueue_event.go
blob: 852a00a5d86fa49440973123efeb58e2505028fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 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 | _EV_CLEAR,
	}
	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,
		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 processWakeupEvent(kq int32, isBlocking bool) {
	if !isBlocking {
		// Got a wrong thread, relay
		wakeNetpoll(kq)
	}
}

func netpollIsPollDescriptor(fd uintptr) bool {
	return fd == uintptr(kq)
}