Source file
src/runtime/netpoll_kqueue_pipe.go
1
2
3
4
5
6
7 package runtime
8
9 import "unsafe"
10
11
12
13
14
15
16
17
18 var netpollBreakRd, netpollBreakWr uintptr
19
20 func addWakeupEvent(kq int32) {
21 r, w, errno := nonblockingPipe()
22 if errno != 0 {
23 println("runtime: pipe failed with", -errno)
24 throw("runtime: pipe failed")
25 }
26 ev := keventt{
27 filter: _EVFILT_READ,
28 flags: _EV_ADD,
29 }
30 *(*uintptr)(unsafe.Pointer(&ev.ident)) = uintptr(r)
31 n := kevent(kq, &ev, 1, nil, 0, nil)
32 if n < 0 {
33 println("runtime: kevent failed with", -n)
34 throw("runtime: kevent failed")
35 }
36 netpollBreakRd = uintptr(r)
37 netpollBreakWr = uintptr(w)
38 }
39
40 func wakeNetpoll(_ int32) {
41 for {
42 var b byte
43 n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
44 if n == 1 || n == -_EAGAIN {
45 break
46 }
47 if n == -_EINTR {
48 continue
49 }
50 println("runtime: netpollBreak write failed with", -n)
51 throw("runtime: netpollBreak write failed")
52 }
53 }
54
55 func isWakeup(ev *keventt) bool {
56 if uintptr(ev.ident) == netpollBreakRd {
57 if ev.filter == _EVFILT_READ {
58 return true
59 }
60 println("runtime: netpoll: break fd ready for", ev.filter)
61 throw("runtime: netpoll: break fd ready for something unexpected")
62 }
63 return false
64 }
65
66 func drainWakeupEvent(_ int32) {
67 var buf [16]byte
68 read(int32(netpollBreakRd), noescape(unsafe.Pointer(&buf[0])), int32(len(buf)))
69 }
70
71 func netpollIsPollDescriptor(fd uintptr) bool {
72 return fd == uintptr(kq) || fd == netpollBreakRd || fd == netpollBreakWr
73 }
74
View as plain text