1
2
3
4
5
6
7 package unix
8
9 import (
10 "sync"
11 )
12
13
14
15
16
17 type EpollEvent struct {
18 Events uint32
19 Fd int32
20 Pad int32
21 }
22
23 const (
24 EPOLLERR = 0x8
25 EPOLLHUP = 0x10
26 EPOLLIN = 0x1
27 EPOLLMSG = 0x400
28 EPOLLOUT = 0x4
29 EPOLLPRI = 0x2
30 EPOLLRDBAND = 0x80
31 EPOLLRDNORM = 0x40
32 EPOLLWRBAND = 0x200
33 EPOLLWRNORM = 0x100
34 EPOLL_CTL_ADD = 0x1
35 EPOLL_CTL_DEL = 0x2
36 EPOLL_CTL_MOD = 0x3
37
38
39
40
41
42
43
44
45 )
46
47
48
49
50
51
52 func epToPollEvt(events uint32) int16 {
53 var ep2p = map[uint32]int16{
54 EPOLLIN: POLLIN,
55 EPOLLOUT: POLLOUT,
56 EPOLLHUP: POLLHUP,
57 EPOLLPRI: POLLPRI,
58 EPOLLERR: POLLERR,
59 }
60
61 var pollEvts int16 = 0
62 for epEvt, pEvt := range ep2p {
63 if (events & epEvt) != 0 {
64 pollEvts |= pEvt
65 }
66 }
67
68 return pollEvts
69 }
70
71
72 func pToEpollEvt(revents int16) uint32 {
73 var p2ep = map[int16]uint32{
74 POLLIN: EPOLLIN,
75 POLLOUT: EPOLLOUT,
76 POLLHUP: EPOLLHUP,
77 POLLPRI: EPOLLPRI,
78 POLLERR: EPOLLERR,
79 }
80
81 var epollEvts uint32 = 0
82 for pEvt, epEvt := range p2ep {
83 if (revents & pEvt) != 0 {
84 epollEvts |= epEvt
85 }
86 }
87
88 return epollEvts
89 }
90
91
92 type epollImpl struct {
93 mu sync.Mutex
94 epfd2ep map[int]*eventPoll
95 nextEpfd int
96 }
97
98
99
100 type eventPoll struct {
101 mu sync.Mutex
102 fds map[int]*EpollEvent
103 }
104
105
106 var impl epollImpl = epollImpl{
107 epfd2ep: make(map[int]*eventPoll),
108 nextEpfd: 0,
109 }
110
111 func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
112 e.mu.Lock()
113 defer e.mu.Unlock()
114 epfd = e.nextEpfd
115 e.nextEpfd++
116
117 e.epfd2ep[epfd] = &eventPoll{
118 fds: make(map[int]*EpollEvent),
119 }
120 return epfd, nil
121 }
122
123 func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
124 return e.epollcreate(4)
125 }
126
127 func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
128 e.mu.Lock()
129 defer e.mu.Unlock()
130
131 ep, ok := e.epfd2ep[epfd]
132 if !ok {
133
134 return EBADF
135 }
136
137 switch op {
138 case EPOLL_CTL_ADD:
139
140
141 if _, ok := ep.fds[fd]; ok {
142 return EEXIST
143 }
144 ep.fds[fd] = event
145 case EPOLL_CTL_MOD:
146 if _, ok := ep.fds[fd]; !ok {
147 return ENOENT
148 }
149 ep.fds[fd] = event
150 case EPOLL_CTL_DEL:
151 if _, ok := ep.fds[fd]; !ok {
152 return ENOENT
153 }
154 delete(ep.fds, fd)
155
156 }
157 return nil
158 }
159
160
161 func (ep *eventPoll) getFds() []int {
162 fds := make([]int, len(ep.fds))
163 for fd := range ep.fds {
164 fds = append(fds, fd)
165 }
166 return fds
167 }
168
169 func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
170 e.mu.Lock()
171 ep, ok := e.epfd2ep[epfd]
172
173 if !ok {
174 e.mu.Unlock()
175 return 0, EBADF
176 }
177
178 pollfds := make([]PollFd, 4)
179 for fd, epollevt := range ep.fds {
180 pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
181 }
182 e.mu.Unlock()
183
184 n, err = Poll(pollfds, msec)
185 if err != nil {
186 return n, err
187 }
188
189 i := 0
190 for _, pFd := range pollfds {
191 if pFd.Revents != 0 {
192 events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
193 i++
194 }
195
196 if i == n {
197 break
198 }
199 }
200
201 return n, nil
202 }
203
204 func EpollCreate(size int) (fd int, err error) {
205 return impl.epollcreate(size)
206 }
207
208 func EpollCreate1(flag int) (fd int, err error) {
209 return impl.epollcreate1(flag)
210 }
211
212 func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
213 return impl.epollctl(epfd, op, fd, event)
214 }
215
216
217
218 func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
219 return impl.epollwait(epfd, events, msec)
220 }
221
View as plain text