...
Source file src/pkg/runtime/netpoll_epoll.go
1
2
3
4
5
6
7 package runtime
8
9 import "unsafe"
10
11 func epollcreate(size int32) int32
12 func epollcreate1(flags int32) int32
13
14
15 func epollctl(epfd, op, fd int32, ev *epollevent) int32
16
17
18 func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
19 func closeonexec(fd int32)
20
21 var (
22 epfd int32 = -1
23 )
24
25 func netpollinit() {
26 epfd = epollcreate1(_EPOLL_CLOEXEC)
27 if epfd >= 0 {
28 return
29 }
30 epfd = epollcreate(1024)
31 if epfd >= 0 {
32 closeonexec(epfd)
33 return
34 }
35 println("runtime: epollcreate failed with", -epfd)
36 throw("runtime: netpollinit failed")
37 }
38
39 func netpolldescriptor() uintptr {
40 return uintptr(epfd)
41 }
42
43 func netpollopen(fd uintptr, pd *pollDesc) int32 {
44 var ev epollevent
45 ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
46 *(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
47 return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
48 }
49
50 func netpollclose(fd uintptr) int32 {
51 var ev epollevent
52 return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
53 }
54
55 func netpollarm(pd *pollDesc, mode int) {
56 throw("runtime: unused")
57 }
58
59
60
61 func netpoll(block bool) gList {
62 if epfd == -1 {
63 return gList{}
64 }
65 waitms := int32(-1)
66 if !block {
67 waitms = 0
68 }
69 var events [128]epollevent
70 retry:
71 n := epollwait(epfd, &events[0], int32(len(events)), waitms)
72 if n < 0 {
73 if n != -_EINTR {
74 println("runtime: epollwait on fd", epfd, "failed with", -n)
75 throw("runtime: netpoll failed")
76 }
77 goto retry
78 }
79 var toRun gList
80 for i := int32(0); i < n; i++ {
81 ev := &events[i]
82 if ev.events == 0 {
83 continue
84 }
85 var mode int32
86 if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
87 mode += 'r'
88 }
89 if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
90 mode += 'w'
91 }
92 if mode != 0 {
93 pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
94 pd.everr = false
95 if ev.events == _EPOLLERR {
96 pd.everr = true
97 }
98 netpollready(&toRun, pd, mode)
99 }
100 }
101 if block && toRun.empty() {
102 goto retry
103 }
104 return toRun
105 }
106
View as plain text