1
2
3
4
5
6
7 package net
8
9 import (
10 "os"
11 "syscall"
12 )
13
14 const (
15 readFlags = syscall.EPOLLIN | syscall.EPOLLRDHUP
16 writeFlags = syscall.EPOLLOUT
17 )
18
19 type pollster struct {
20 epfd int
21
22
23
24 events map[int]uint32
25
26
27
28 waitEventBuf [10]syscall.EpollEvent
29 waitEvents []syscall.EpollEvent
30
31
32
33 ctlEvent syscall.EpollEvent
34 }
35
36 func newpollster() (p *pollster, err os.Error) {
37 p = new(pollster)
38 var e int
39
40
41
42
43 if p.epfd, e = syscall.EpollCreate(16); e != 0 {
44 return nil, os.NewSyscallError("epoll_create", e)
45 }
46 p.events = make(map[int]uint32)
47 return p, nil
48 }
49
50 func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
51
52
53 var already bool
54 p.ctlEvent.Fd = int32(fd)
55 p.ctlEvent.Events, already = p.events[fd]
56 if !repeat {
57 p.ctlEvent.Events |= syscall.EPOLLONESHOT
58 }
59 if mode == 'r' {
60 p.ctlEvent.Events |= readFlags
61 } else {
62 p.ctlEvent.Events |= writeFlags
63 }
64
65 var op int
66 if already {
67 op = syscall.EPOLL_CTL_MOD
68 } else {
69 op = syscall.EPOLL_CTL_ADD
70 }
71 if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 {
72 return false, os.NewSyscallError("epoll_ctl", e)
73 }
74 p.events[fd] = p.ctlEvent.Events
75 return false, nil
76 }
77
78 func (p *pollster) StopWaiting(fd int, bits uint) {
79
80
81 events, already := p.events[fd]
82 if !already {
83 print("Epoll unexpected fd=", fd, "\n")
84 return
85 }
86
87
88
89 if events&syscall.EPOLLONESHOT == 0 {
90 return
91 }
92
93
94
95
96 events &= ^uint32(bits)
97 if int32(events)&^syscall.EPOLLONESHOT != 0 {
98 p.ctlEvent.Fd = int32(fd)
99 p.ctlEvent.Events = events
100 if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_MOD, fd, &p.ctlEvent); e != 0 {
101 print("Epoll modify fd=", fd, ": ", os.Errno(e).String(), "\n")
102 }
103 p.events[fd] = events
104 } else {
105 if e := syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_DEL, fd, nil); e != 0 {
106 print("Epoll delete fd=", fd, ": ", os.Errno(e).String(), "\n")
107 }
108 p.events[fd] = 0, false
109 }
110 }
111
112 func (p *pollster) DelFD(fd int, mode int) {
113
114
115 if mode == 'r' {
116 p.StopWaiting(fd, readFlags)
117 } else {
118 p.StopWaiting(fd, writeFlags)
119 }
120
121
122 i := 0
123 for i < len(p.waitEvents) {
124 if fd == int(p.waitEvents[i].Fd) {
125 copy(p.waitEvents[i:], p.waitEvents[i+1:])
126 p.waitEvents = p.waitEvents[:len(p.waitEvents)-1]
127 } else {
128 i++
129 }
130 }
131 }
132
133 func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
134 for len(p.waitEvents) == 0 {
135 var msec int = -1
136 if nsec > 0 {
137 msec = int((nsec + 1e6 - 1) / 1e6)
138 }
139
140 s.Unlock()
141 n, e := syscall.EpollWait(p.epfd, p.waitEventBuf[0:], msec)
142 s.Lock()
143
144 if e != 0 {
145 if e == syscall.EAGAIN || e == syscall.EINTR {
146 continue
147 }
148 return -1, 0, os.NewSyscallError("epoll_wait", e)
149 }
150 if n == 0 {
151 return -1, 0, nil
152 }
153 p.waitEvents = p.waitEventBuf[0:n]
154 }
155
156 ev := &p.waitEvents[0]
157 p.waitEvents = p.waitEvents[1:]
158
159 fd = int(ev.Fd)
160
161 if ev.Events&writeFlags != 0 {
162 p.StopWaiting(fd, writeFlags)
163 return fd, 'w', nil
164 }
165 if ev.Events&readFlags != 0 {
166 p.StopWaiting(fd, readFlags)
167 return fd, 'r', nil
168 }
169
170
171 events, _ := p.events[fd]
172 if events&writeFlags != 0 {
173 p.StopWaiting(fd, writeFlags)
174 return fd, 'w', nil
175 }
176 p.StopWaiting(fd, readFlags)
177 return fd, 'r', nil
178 }
179
180 func (p *pollster) Close() os.Error {
181 return os.NewSyscallError("close", syscall.Close(p.epfd))
182 }