...
Source file src/runtime/netpoll_kqueue.go
1
2
3
4
5
6
7 package runtime
8
9
10
11 import "unsafe"
12
13 var (
14 kq int32 = -1
15 )
16
17 func netpollinit() {
18 kq = kqueue()
19 if kq < 0 {
20 println("runtime: kqueue failed with", -kq)
21 throw("runtime: netpollinit failed")
22 }
23 closeonexec(kq)
24 }
25
26 func netpolldescriptor() uintptr {
27 return uintptr(kq)
28 }
29
30 func netpollopen(fd uintptr, pd *pollDesc) int32 {
31
32
33
34 var ev [2]keventt
35 *(*uintptr)(unsafe.Pointer(&ev[0].ident)) = fd
36 ev[0].filter = _EVFILT_READ
37 ev[0].flags = _EV_ADD | _EV_CLEAR
38 ev[0].fflags = 0
39 ev[0].data = 0
40 ev[0].udata = (*byte)(unsafe.Pointer(pd))
41 ev[1] = ev[0]
42 ev[1].filter = _EVFILT_WRITE
43 n := kevent(kq, &ev[0], 2, nil, 0, nil)
44 if n < 0 {
45 return -n
46 }
47 return 0
48 }
49
50 func netpollclose(fd uintptr) int32 {
51
52
53 return 0
54 }
55
56 func netpollarm(pd *pollDesc, mode int) {
57 throw("runtime: unused")
58 }
59
60
61
62 func netpoll(block bool) gList {
63 if kq == -1 {
64 return gList{}
65 }
66 var tp *timespec
67 var ts timespec
68 if !block {
69 tp = &ts
70 }
71 var events [64]keventt
72 retry:
73 n := kevent(kq, nil, 0, &events[0], int32(len(events)), tp)
74 if n < 0 {
75 if n != -_EINTR {
76 println("runtime: kevent on fd", kq, "failed with", -n)
77 throw("runtime: netpoll failed")
78 }
79 goto retry
80 }
81 var toRun gList
82 for i := 0; i < int(n); i++ {
83 ev := &events[i]
84 var mode int32
85 switch ev.filter {
86 case _EVFILT_READ:
87 mode += 'r'
88
89
90
91
92
93
94
95
96
97
98 if ev.flags&_EV_EOF != 0 {
99 mode += 'w'
100 }
101 case _EVFILT_WRITE:
102 mode += 'w'
103 }
104 if mode != 0 {
105 pd := (*pollDesc)(unsafe.Pointer(ev.udata))
106 pd.everr = false
107 if ev.flags == _EV_ERROR {
108 pd.everr = true
109 }
110 netpollready(&toRun, pd, mode)
111 }
112 }
113 if block && toRun.empty() {
114 goto retry
115 }
116 return toRun
117 }
118
View as plain text