Source file
src/runtime/netpoll_aix.go
1
2
3
4
5 package runtime
6
7 import (
8 "runtime/internal/atomic"
9 "unsafe"
10 )
11
12
13
14
15
16
17
18
19 var libc_poll libFunc
20
21
22 func poll(pfds *pollfd, npfds uintptr, timeout uintptr) (int32, int32) {
23 r, err := syscall3(&libc_poll, uintptr(unsafe.Pointer(pfds)), npfds, timeout)
24 return int32(r), int32(err)
25 }
26
27
28 type pollfd struct {
29 fd int32
30 events int16
31 revents int16
32 }
33
34 const _POLLIN = 0x0001
35 const _POLLOUT = 0x0002
36 const _POLLHUP = 0x2000
37 const _POLLERR = 0x4000
38
39 var (
40 pfds []pollfd
41 pds []*pollDesc
42 mtxpoll mutex
43 mtxset mutex
44 rdwake int32
45 wrwake int32
46 pendingUpdates int32
47
48 netpollWakeSig atomic.Uint32
49 )
50
51 func netpollinit() {
52
53 r, w, errno := nonblockingPipe()
54 if errno != 0 {
55 throw("netpollinit: failed to create pipe")
56 }
57 rdwake = r
58 wrwake = w
59
60
61 pfds = make([]pollfd, 1, 128)
62
63
64 pfds[0].fd = rdwake
65 pfds[0].events = _POLLIN
66
67 pds = make([]*pollDesc, 1, 128)
68 pds[0] = nil
69 }
70
71 func netpollIsPollDescriptor(fd uintptr) bool {
72 return fd == uintptr(rdwake) || fd == uintptr(wrwake)
73 }
74
75
76 func netpollwakeup() {
77 if pendingUpdates == 0 {
78 pendingUpdates = 1
79 b := [1]byte{0}
80 write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1)
81 }
82 }
83
84 func netpollopen(fd uintptr, pd *pollDesc) int32 {
85 lock(&mtxpoll)
86 netpollwakeup()
87
88 lock(&mtxset)
89 unlock(&mtxpoll)
90
91 pd.user = uint32(len(pfds))
92 pfds = append(pfds, pollfd{fd: int32(fd)})
93 pds = append(pds, pd)
94 unlock(&mtxset)
95 return 0
96 }
97
98 func netpollclose(fd uintptr) int32 {
99 lock(&mtxpoll)
100 netpollwakeup()
101
102 lock(&mtxset)
103 unlock(&mtxpoll)
104
105 for i := 0; i < len(pfds); i++ {
106 if pfds[i].fd == int32(fd) {
107 pfds[i] = pfds[len(pfds)-1]
108 pfds = pfds[:len(pfds)-1]
109
110 pds[i] = pds[len(pds)-1]
111 pds[i].user = uint32(i)
112 pds = pds[:len(pds)-1]
113 break
114 }
115 }
116 unlock(&mtxset)
117 return 0
118 }
119
120 func netpollarm(pd *pollDesc, mode int) {
121 lock(&mtxpoll)
122 netpollwakeup()
123
124 lock(&mtxset)
125 unlock(&mtxpoll)
126
127 switch mode {
128 case 'r':
129 pfds[pd.user].events |= _POLLIN
130 case 'w':
131 pfds[pd.user].events |= _POLLOUT
132 }
133 unlock(&mtxset)
134 }
135
136
137 func netpollBreak() {
138
139 if !netpollWakeSig.CompareAndSwap(0, 1) {
140 return
141 }
142
143 b := [1]byte{0}
144 write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1)
145 }
146
147
148
149
150
151
152
153
154 func netpoll(delay int64) gList {
155 var timeout uintptr
156 if delay < 0 {
157 timeout = ^uintptr(0)
158 } else if delay == 0 {
159
160 return gList{}
161 } else if delay < 1e6 {
162 timeout = 1
163 } else if delay < 1e15 {
164 timeout = uintptr(delay / 1e6)
165 } else {
166
167
168 timeout = 1e9
169 }
170 retry:
171 lock(&mtxpoll)
172 lock(&mtxset)
173 pendingUpdates = 0
174 unlock(&mtxpoll)
175
176 n, e := poll(&pfds[0], uintptr(len(pfds)), timeout)
177 if n < 0 {
178 if e != _EINTR {
179 println("errno=", e, " len(pfds)=", len(pfds))
180 throw("poll failed")
181 }
182 unlock(&mtxset)
183
184
185 if timeout > 0 {
186 return gList{}
187 }
188 goto retry
189 }
190
191 if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 {
192 if delay != 0 {
193
194
195
196 var b [1]byte
197 for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 {
198 }
199 netpollWakeSig.Store(0)
200 }
201
202
203 n--
204 }
205 var toRun gList
206 for i := 1; i < len(pfds) && n > 0; i++ {
207 pfd := &pfds[i]
208
209 var mode int32
210 if pfd.revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 {
211 mode += 'r'
212 pfd.events &= ^_POLLIN
213 }
214 if pfd.revents&(_POLLOUT|_POLLHUP|_POLLERR) != 0 {
215 mode += 'w'
216 pfd.events &= ^_POLLOUT
217 }
218 if mode != 0 {
219 pds[i].setEventErr(pfd.revents == _POLLERR)
220 netpollready(&toRun, pds[i], mode)
221 n--
222 }
223 }
224 unlock(&mtxset)
225 return toRun
226 }
227
View as plain text