Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(68)

Delta Between Two Patch Sets: src/pkg/net/fd_linux.go

Issue 6460108: net: epoll dispatcher 2
Left Patch Set: diff -r ac1b735e8753 https://go.googlecode.com/hg/ Created 11 years, 7 months ago
Right Patch Set: diff -r f2755950769b https://dvyukov%40google.com@code.google.com/p/go/ Created 11 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/net/fd_unix.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // +build none
6
5 package net 7 package net
6 8
7 import ( 9 import (
10 //"fmt"
8 "errors" 11 "errors"
9 "io" 12 "io"
10 "os" 13 "os"
11 "sync" 14 "sync"
12 "syscall" 15 "syscall"
13 "time"
14 "unsafe"
15 ) 16 )
16 17
17 // Network file descriptor. 18 // Network file descriptor.
18 type netFD struct { 19 type netFD struct {
19 // locking/lifetime of sysfd 20 // locking/lifetime of sysfd
20 sysmu sync.Mutex 21 sysmu sync.Mutex
21 sysref int 22 sysref int
22 closing bool 23 closing bool
23 pdesc uintptr 24 pdesc uintptr
24 25
25 // immutable until Close 26 // immutable until Close
26 sysfd int 27 sysfd int
27 family int 28 family int
28 sotype int 29 sotype int
29 isConnected bool 30 isConnected bool
30 sysfile *os.File 31 sysfile *os.File
31 net string 32 net string
32 laddr Addr 33 laddr Addr
33 raddr Addr 34 raddr Addr
34 35
35 » // owned by client 36 » rio sync.Mutex
36 » rdeadline int64 37 » wio sync.Mutex
37 » rio sync.Mutex 38 » rblock bool
38 » wdeadline int64 39 » wblock bool
39 » wio sync.Mutex
40 } 40 }
41 41
42 func runtime_initPollServer() 42 func runtime_initPollServer()
43 func runtime_initFD(fd int) uintptr, error 43 func runtime_initFD(fd int) (uintptr, error)
44 func runtime_closeFD(desc uintptr) 44 func runtime_closeFD(desc uintptr)
45 func runtime_waitFD(desc uintptr, mode int32) 45 func runtime_waitFD(desc uintptr, mode int) int32
46 func runtime_resetFD(desc uintptr, mode int)
47 func runtime_setDeadlineFD(desc uintptr, d int64, mode int)
46 func runtime_unblockFD(desc uintptr) 48 func runtime_unblockFD(desc uintptr)
47 49
48 /* 50 func waitFD(fd *netFD, mode int) error {
49 type pollServer struct { 51 » interr := runtime_waitFD(fd.pdesc, mode)
50 » epfd int 52 » if interr == 0 {
51 » mu sync.Mutex 53 » » return nil
52 » cache *pDesc 54 » }
53 } 55 » if interr == 1 {
54
55 type pDesc struct {
56 » next *pDesc
57 » rc chan struct{}
58 » wc chan struct{}
59 }
60
61 func newPollServer() (s *pollServer, err error) {
62 » s = new(pollServer)
63 » if s.epfd, err = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC); err != nil {
64 » » if err != syscall.ENOSYS {
65 » » » return nil, os.NewSyscallError("epoll_create1", err)
66 » » }
67 » » // The arg to epoll_create is a hint to the kernel
68 » » // about the number of FDs we will care about.
69 » » // We don't know, and since 2.6.8 the kernel ignores it anyhow.
70 » » if s.epfd, err = syscall.EpollCreate(16); err != nil {
71 » » » return nil, os.NewSyscallError("epoll_create", err)
72 » » }
73 » » syscall.CloseOnExec(s.epfd)
74 » }
75 » go s.Loop()
76 » return s, nil
77 }
78
79 func (s *pollServer) AddFD(fd *netFD, mode int) error {
80 » c := fd.pdesc.rc
81 » d := fd.rdeadline
82 » if mode == 'w' {
83 » » c = fd.pdesc.wc
84 » » d = fd.wdeadline
85 » }
86 » <-c
87 » if fd.closing { //!!! mutex
88 return errClosing 56 return errClosing
89 } 57 }
90 » if d != 0 && d <= time.Now().Unix() { 58 » if interr == 2 {
91 return errTimeout 59 return errTimeout
92 } 60 }
93 » return nil 61 » panic("net: unknown error code from waitFD()")
94 } 62 }
95 63
96 func (s *pollServer) Evict(fd *netFD) { 64 func waitRead(fd *netFD) error {
97 » if fd.pdesc != nil { 65 » return waitFD(fd, 'r')
98 » » select { 66 }
99 » » case fd.pdesc.rc <- struct{}{}: 67
100 » » default: 68 func waitWrite(fd *netFD) error {
101 » » } 69 » return waitFD(fd, 'w')
102 » » select { 70 }
103 » » case fd.pdesc.wc <- struct{}{}:
104 » » default:
105 » » }
106 » }
107 }
108
109 func (s *pollServer) Loop() {
110 » var events [10]syscall.EpollEvent
111 » epfd := s.epfd
112 » for {
113 » » n, err := syscall.EpollWait(epfd, events[:], -1)
114 » » if err != nil {
115 » » » if err == syscall.EAGAIN || err == syscall.EINTR {
116 » » » » continue
117 » » » }
118 » » » println("pollServer:", err.Error())
119 » » » return
120 » » }
121 » » for i := 0; i < n; i++ {
122 » » » ev := events[i]
123 » » » pdesc := (*pDesc)(unsafe.Pointer(uintptr(uint64(ev.Fd) | (uint64(ev.Pad) << 32))))
124 » » » if (ev.Events & (syscall.EPOLLIN | syscall.EPOLLRDHUP)) != 0 {
125 » » » » select {
126 » » » » case pdesc.rc <- struct{}{}:
127 » » » » default:
128 » » » » }
129 » » » }
130 » » » if (ev.Events & (syscall.EPOLLOUT | syscall.EPOLLRDHUP)) != 0 {
131 » » » » select {
132 » » » » case pdesc.wc <- struct{}{}:
133 » » » » default:
134 » » » » }
135 » » » }
136 » » }
137 » }
138 }
139
140 func (s *pollServer) WaitRead(fd *netFD) error {
141 » return s.AddFD(fd, 'r')
142 }
143
144 func (s *pollServer) WaitWrite(fd *netFD) error {
145 » return s.AddFD(fd, 'w')
146 }
147 */
148 71
149 var onceStartServer sync.Once 72 var onceStartServer sync.Once
150 73
151 func newFD(fd, family, sotype int, net string) (*netFD, error) { 74 func newFD(fd, family, sotype int, net string) (*netFD, error) {
152 onceStartServer.Do(runtime_initPollServer) 75 onceStartServer.Do(runtime_initPollServer)
153 if err := syscall.SetNonblock(fd, true); err != nil { 76 if err := syscall.SetNonblock(fd, true); err != nil {
154 return nil, err 77 return nil, err
155 } 78 }
156 netfd := &netFD{ 79 netfd := &netFD{
157 sysfd: fd, 80 sysfd: fd,
158 family: family, 81 family: family,
159 sotype: sotype, 82 sotype: sotype,
160 net: net, 83 net: net,
161 } 84 }
162 » netfd.pdesc, err := runtime_initFD(fd) 85 » desc, err := runtime_initFD(fd)
163 if err != nil { 86 if err != nil {
164 return nil, err 87 return nil, err
165 } 88 }
166 » return netfd, nil 89 » netfd.pdesc = desc
167
168 /*
169 » s := pollserver
170 » s.mu.Lock()
171 » if s.cache != nil {
172 » » netfd.pdesc = s.cache
173 » » s.cache = netfd.pdesc.next
174 » }
175 » s.mu.Unlock()
176 » if netfd.pdesc != nil {
177 » » select {
178 » » case <-netfd.pdesc.rc:
179 » » default:
180 » » }
181 » » select {
182 » » case <-netfd.pdesc.wc:
183 » » default:
184 » » }
185 » } else {
186 » » netfd.pdesc = new(pDesc)
187 » » netfd.pdesc.rc = make(chan struct{}, 1)
188 » » netfd.pdesc.wc = make(chan struct{}, 1)
189 » }
190 » var ev syscall.EpollEvent
191 » ev.Fd = int32(uintptr(unsafe.Pointer(netfd.pdesc)))
192 » ev.Pad = int32(uintptr(unsafe.Pointer(netfd.pdesc)) >> 32)
193 » ev.Events = uint32(syscall.EPOLLIN) | uint32(syscall.EPOLLOUT) | uint32( syscall.EPOLLRDHUP) | uint32(-syscall.EPOLLET)
194 » if err := syscall.EpollCtl(s.epfd, syscall.EPOLL_CTL_ADD, fd, &ev); err != nil {
195 » » return nil, err
196 » }
197 */
198 return netfd, nil 90 return netfd, nil
199 } 91 }
200 92
201 func (fd *netFD) setAddr(laddr, raddr Addr) { 93 func (fd *netFD) setAddr(laddr, raddr Addr) {
202 fd.laddr = laddr 94 fd.laddr = laddr
203 fd.raddr = raddr 95 fd.raddr = raddr
204 var ls, rs string 96 var ls, rs string
205 if laddr != nil { 97 if laddr != nil {
206 ls = laddr.String() 98 ls = laddr.String()
207 } 99 }
208 if raddr != nil { 100 if raddr != nil {
209 rs = raddr.String() 101 rs = raddr.String()
210 } 102 }
211 fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net+":"+ls+"->"+rs) 103 fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net+":"+ls+"->"+rs)
212 } 104 }
213 105
214 func (fd *netFD) connect(ra syscall.Sockaddr) error { 106 func (fd *netFD) connect(ra syscall.Sockaddr) error {
215 for { 107 for {
216 err := syscall.Connect(fd.sysfd, ra) 108 err := syscall.Connect(fd.sysfd, ra)
217 if err == nil { 109 if err == nil {
218 break 110 break
219 } else if err == syscall.EINPROGRESS || err == syscall.EALREADY { 111 } else if err == syscall.EINPROGRESS || err == syscall.EALREADY {
220 fd.wio.Lock() 112 fd.wio.Lock()
221 » » » err = pollserver.WaitWrite(fd) 113 » » » err = waitWrite(fd)
222 fd.wio.Unlock() 114 fd.wio.Unlock()
223 if err != nil { 115 if err != nil {
224 return err 116 return err
225 } 117 }
226 } else { 118 } else {
227 return err 119 return err
228 } 120 }
229 } 121 }
230 return nil 122 return nil
231 } 123 }
(...skipping 26 matching lines...) Expand all
258 if fd == nil { 150 if fd == nil {
259 return 151 return
260 } 152 }
261 fd.sysmu.Lock() 153 fd.sysmu.Lock()
262 fd.sysref-- 154 fd.sysref--
263 if fd.closing && fd.sysref == 0 && fd.sysfile != nil { 155 if fd.closing && fd.sysref == 0 && fd.sysfile != nil {
264 fd.sysfile.Close() 156 fd.sysfile.Close()
265 fd.sysfile = nil 157 fd.sysfile = nil
266 fd.sysfd = -1 158 fd.sysfd = -1
267 runtime_closeFD(fd.pdesc) 159 runtime_closeFD(fd.pdesc)
268 /*
269 if fd.pdesc != nil {
270 p := pollserver
271 p.mu.Lock()
272 fd.pdesc.next = p.cache
273 p.cache = fd.pdesc
274 p.mu.Unlock()
275 fd.pdesc = nil
276 }
277 */
278 } 160 }
279 fd.sysmu.Unlock() 161 fd.sysmu.Unlock()
280 } 162 }
281 163
282 func (fd *netFD) Close() error { 164 func (fd *netFD) Close() error {
283 if err := fd.incref(true); err != nil { 165 if err := fd.incref(true); err != nil {
284 return err 166 return err
285 } 167 }
286 // Unblock any I/O. Once it all unblocks and returns, 168 // Unblock any I/O. Once it all unblocks and returns,
287 // so that it cannot be referring to fd.sysfd anymore, 169 // so that it cannot be referring to fd.sysfd anymore,
(...skipping 20 matching lines...) Expand all
308 func (fd *netFD) CloseRead() error { 190 func (fd *netFD) CloseRead() error {
309 return fd.shutdown(syscall.SHUT_RD) 191 return fd.shutdown(syscall.SHUT_RD)
310 } 192 }
311 193
312 func (fd *netFD) CloseWrite() error { 194 func (fd *netFD) CloseWrite() error {
313 return fd.shutdown(syscall.SHUT_WR) 195 return fd.shutdown(syscall.SHUT_WR)
314 } 196 }
315 197
316 func (fd *netFD) Read(p []byte) (n int, err error) { 198 func (fd *netFD) Read(p []byte) (n int, err error) {
317 fd.rio.Lock() 199 fd.rio.Lock()
318 » defer fd.rio.Unlock() 200 » //defer fd.rio.Unlock()
319 » if err := fd.incref(false); err != nil { 201 » if err := fd.incref(false); err != nil {
320 » » return 0, err 202 » » fd.rio.Unlock()
321 » } 203 » » return 0, err //!!! does not wrap into OpError
322 » defer fd.decref() 204 » }
205 » //defer fd.decref()
206 » if fd.rblock {
207 » » //println(fd, "reset rblock and wait")
208 » » fd.rblock = false
209 » » err = waitRead(fd)
210 » » //println(fd, "ready")
211 » » if err != nil {
212 » » » fd.decref()
213 » » » fd.rio.Unlock()
214 » » » return 0, &OpError{"read", fd.net, fd.raddr, err}
215 » » }
216 » } else {
217 » » //println(fd, "reset fd")
218 » » runtime_resetFD(fd.pdesc, 'r')
219 » }
323 for { 220 for {
324 n, err = syscall.Read(int(fd.sysfd), p) 221 n, err = syscall.Read(int(fd.sysfd), p)
222 /*
223 if n > 0 && err == nil {
224 fmt.Printf("READ %p %v:\n%v\n", fd, n, string(p[:n]))
225 for i := 0; i < n; i++ {
226 if i == 0 {
227 fmt.Printf("\t\"")
228 }
229 c1 := p[i] >> 4
230 r1 := c1 + '0'
231 if c1 >=10 {
232 r1 = c1 - 10 + 'A'
233 }
234 c2 := p[i] % 16
235 r2 := c2 + '0'
236 if c2 >=10 {
237 r2 = c2 - 10 + 'A'
238 }
239 s := [2]byte{byte(r1), byte(r2)}
240 fmt.Printf("\\x%v", string(s[:]))
241 if (i+1) % 20 == 0 {
242 fmt.Printf("\"\n\t\"")
243 }
244 }
245 fmt.Printf("\n")
246 }
247 */
325 if err == syscall.EAGAIN { 248 if err == syscall.EAGAIN {
326 » » » err = errTimeout 249 » » » //println(fd, "wait")
327 » » » if fd.rdeadline >= 0 { 250 » » » if err = waitRead(fd); err == nil {
328 » » » » if err = pollserver.WaitRead(fd); err == nil { 251 » » » » //println(fd, "ready")
329 » » » » » continue 252 » » » » continue
330 » » » » }
331 } 253 }
332 } 254 }
333 if err != nil { 255 if err != nil {
334 n = 0 256 n = 0
335 } else if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRA M { 257 } else if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRA M {
336 err = io.EOF 258 err = io.EOF
337 } 259 }
260 if err == nil && fd.sotype == syscall.SOCK_STREAM && n > 0 && n < len(p) {
261 //println(fd, "set rblock")
262 //fd.rblock = true
263 }
338 break 264 break
339 } 265 }
340 if err != nil && err != io.EOF { 266 if err != nil && err != io.EOF {
341 err = &OpError{"read", fd.net, fd.raddr, err} 267 err = &OpError{"read", fd.net, fd.raddr, err}
342 } 268 }
269 //println(fd, "result", n, err)
270 fd.decref()
271 fd.rio.Unlock()
343 return 272 return
344 } 273 }
345 274
346 func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { 275 func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
347 fd.rio.Lock() 276 fd.rio.Lock()
348 defer fd.rio.Unlock() 277 defer fd.rio.Unlock()
349 if err := fd.incref(false); err != nil { 278 if err := fd.incref(false); err != nil {
350 return 0, nil, err 279 return 0, nil, err
351 } 280 }
352 defer fd.decref() 281 defer fd.decref()
353 for { 282 for {
354 n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) 283 n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
355 if err == syscall.EAGAIN { 284 if err == syscall.EAGAIN {
356 » » » err = errTimeout 285 » » » if err = waitRead(fd); err == nil {
357 » » » if fd.rdeadline >= 0 { 286 » » » » continue
358 » » » » if err = pollserver.WaitRead(fd); err == nil {
359 » » » » » continue
360 » » » » }
361 } 287 }
362 } 288 }
363 if err != nil { 289 if err != nil {
364 n = 0 290 n = 0
365 } 291 }
366 break 292 break
367 } 293 }
368 if err != nil && err != io.EOF { 294 if err != nil && err != io.EOF {
369 err = &OpError{"read", fd.net, fd.laddr, err} 295 err = &OpError{"read", fd.net, fd.laddr, err}
370 } 296 }
371 return 297 return
372 } 298 }
373 299
374 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) { 300 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) {
375 fd.rio.Lock() 301 fd.rio.Lock()
376 defer fd.rio.Unlock() 302 defer fd.rio.Unlock()
377 if err := fd.incref(false); err != nil { 303 if err := fd.incref(false); err != nil {
378 return 0, 0, 0, nil, err 304 return 0, 0, 0, nil, err
379 } 305 }
380 defer fd.decref() 306 defer fd.decref()
381 for { 307 for {
382 n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0) 308 n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
383 if err == syscall.EAGAIN { 309 if err == syscall.EAGAIN {
384 » » » err = errTimeout 310 » » » if err = waitRead(fd); err == nil {
385 » » » if fd.rdeadline >= 0 { 311 » » » » continue
386 » » » » if err = pollserver.WaitRead(fd); err == nil {
387 » » » » » continue
388 » » » » }
389 } 312 }
390 } 313 }
391 if err == nil && n == 0 { 314 if err == nil && n == 0 {
392 err = io.EOF 315 err = io.EOF
393 } 316 }
394 break 317 break
395 } 318 }
396 if err != nil && err != io.EOF { 319 if err != nil && err != io.EOF {
397 err = &OpError{"read", fd.net, fd.laddr, err} 320 err = &OpError{"read", fd.net, fd.laddr, err}
398 return 321 return
399 } 322 }
400 return 323 return
401 } 324 }
402 325
403 func (fd *netFD) Write(p []byte) (int, error) { 326 func (fd *netFD) Write(p []byte) (int, error) {
404 fd.wio.Lock() 327 fd.wio.Lock()
405 » defer fd.wio.Unlock() 328 » //defer fd.wio.Unlock()
406 » if err := fd.incref(false); err != nil { 329 » if err := fd.incref(false); err != nil {
330 » » fd.wio.Unlock()
407 return 0, err 331 return 0, err
408 } 332 }
409 » defer fd.decref() 333 » //defer fd.decref()
410 if fd.sysfile == nil { 334 if fd.sysfile == nil {
335 fd.decref()
336 fd.wio.Unlock()
411 return 0, syscall.EINVAL 337 return 0, syscall.EINVAL
412 } 338 }
413 339
414 var err error 340 var err error
415 nn := 0 341 nn := 0
342 runtime_resetFD(fd.pdesc, 'w')
416 for { 343 for {
417 var n int 344 var n int
418 n, err = syscall.Write(int(fd.sysfd), p[nn:]) 345 n, err = syscall.Write(int(fd.sysfd), p[nn:])
346 /*
347 if n > 0 && err == nil {
348 fmt.Printf("WRITE %p %v:\n%v\n", fd, n, string(p[nn:nn+n ]))
349 for i := 0; i < n; i++ {
350 if i == 0 {
351 fmt.Printf("\t\"")
352 }
353 c1 := p[nn+i] >> 4
354 r1 := c1 + '0'
355 if c1 >=10 {
356 r1 = c1 - 10 + 'A'
357 }
358 c2 := p[nn+i] % 16
359 r2 := c2 + '0'
360 if c2 >=10 {
361 r2 = c2 - 10 + 'A'
362 }
363 s := [2]byte{byte(r1), byte(r2)}
364 fmt.Printf("\\x%v", string(s[:]))
365 if (i+1) % 20 == 0 {
366 fmt.Printf("\"\n\t\"")
367 }
368 }
369 fmt.Printf("\n")
370 }
371 */
419 if n > 0 { 372 if n > 0 {
420 nn += n 373 nn += n
421 } 374 }
422 if nn == len(p) { 375 if nn == len(p) {
423 break 376 break
424 } 377 }
425 if err == syscall.EAGAIN { 378 if err == syscall.EAGAIN {
426 » » » err = errTimeout 379 » » » if err = waitWrite(fd); err == nil {
427 » » » if fd.wdeadline >= 0 { 380 » » » » continue
428 » » » » if err = pollserver.WaitWrite(fd); err == nil {
429 » » » » » continue
430 » » » » }
431 } 381 }
432 } 382 }
433 if err != nil { 383 if err != nil {
434 n = 0 384 n = 0
435 break 385 break
436 } 386 }
437 if n == 0 { 387 if n == 0 {
438 err = io.ErrUnexpectedEOF 388 err = io.ErrUnexpectedEOF
439 break 389 break
440 } 390 }
441 } 391 }
442 if err != nil { 392 if err != nil {
443 err = &OpError{"write", fd.net, fd.raddr, err} 393 err = &OpError{"write", fd.net, fd.raddr, err}
444 } 394 }
395 fd.decref()
396 fd.wio.Unlock()
445 return nn, err 397 return nn, err
446 } 398 }
447 399
448 func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) { 400 func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
449 fd.wio.Lock() 401 fd.wio.Lock()
450 defer fd.wio.Unlock() 402 defer fd.wio.Unlock()
451 if err := fd.incref(false); err != nil { 403 if err := fd.incref(false); err != nil {
452 return 0, err 404 return 0, err
453 } 405 }
454 defer fd.decref() 406 defer fd.decref()
455 for { 407 for {
456 err = syscall.Sendto(fd.sysfd, p, 0, sa) 408 err = syscall.Sendto(fd.sysfd, p, 0, sa)
457 if err == syscall.EAGAIN { 409 if err == syscall.EAGAIN {
458 » » » err = errTimeout 410 » » » if err = waitWrite(fd); err == nil {
459 » » » if fd.wdeadline >= 0 { 411 » » » » continue
460 » » » » if err = pollserver.WaitWrite(fd); err == nil {
461 » » » » » continue
462 » » » » }
463 } 412 }
464 } 413 }
465 break 414 break
466 } 415 }
467 if err == nil { 416 if err == nil {
468 n = len(p) 417 n = len(p)
469 } else { 418 } else {
470 err = &OpError{"write", fd.net, fd.raddr, err} 419 err = &OpError{"write", fd.net, fd.raddr, err}
471 } 420 }
472 return 421 return
473 } 422 }
474 423
475 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) { 424 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) {
476 fd.wio.Lock() 425 fd.wio.Lock()
477 defer fd.wio.Unlock() 426 defer fd.wio.Unlock()
478 if err := fd.incref(false); err != nil { 427 if err := fd.incref(false); err != nil {
479 return 0, 0, err 428 return 0, 0, err
480 } 429 }
481 defer fd.decref() 430 defer fd.decref()
482 for { 431 for {
483 err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0) 432 err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
484 if err == syscall.EAGAIN { 433 if err == syscall.EAGAIN {
485 » » » err = errTimeout 434 » » » if err = waitWrite(fd); err == nil {
486 » » » if fd.wdeadline >= 0 { 435 » » » » continue
487 » » » » if err = pollserver.WaitWrite(fd); err == nil {
488 » » » » » continue
489 » » » » }
490 } 436 }
491 } 437 }
492 break 438 break
493 } 439 }
494 if err == nil { 440 if err == nil {
495 n = len(p) 441 n = len(p)
496 oobn = len(oob) 442 oobn = len(oob)
497 } else { 443 } else {
498 err = &OpError{"write", fd.net, fd.raddr, err} 444 err = &OpError{"write", fd.net, fd.raddr, err}
499 } 445 }
(...skipping 10 matching lines...) Expand all
510 // It is okay to hold the lock across syscall.Accept 456 // It is okay to hold the lock across syscall.Accept
511 // because we have put fd.sysfd into non-blocking mode. 457 // because we have put fd.sysfd into non-blocking mode.
512 var s int 458 var s int
513 var rsa syscall.Sockaddr 459 var rsa syscall.Sockaddr
514 for { 460 for {
515 syscall.ForkLock.RLock() 461 syscall.ForkLock.RLock()
516 s, rsa, err = syscall.Accept(fd.sysfd) 462 s, rsa, err = syscall.Accept(fd.sysfd)
517 if err != nil { 463 if err != nil {
518 syscall.ForkLock.RUnlock() 464 syscall.ForkLock.RUnlock()
519 if err == syscall.EAGAIN { 465 if err == syscall.EAGAIN {
520 » » » » err = errTimeout 466 » » » » fd.rio.Lock()
521 » » » » if fd.rdeadline >= 0 { 467 » » » » err = waitRead(fd)
522 » » » » » fd.rio.Lock() 468 » » » » fd.rio.Unlock()
523 » » » » » err = pollserver.WaitRead(fd) 469 » » » » if err == nil {
524 » » » » » fd.rio.Unlock() 470 » » » » » continue
525 » » » » » if err == nil {
526 » » » » » » continue
527 » » » » » }
528 } 471 }
529 } else if err == syscall.ECONNABORTED { 472 } else if err == syscall.ECONNABORTED {
530 // This means that a socket on the listen queue was closed 473 // This means that a socket on the listen queue was closed
531 // before we Accept()ed it; it's a silly error, so try again. 474 // before we Accept()ed it; it's a silly error, so try again.
532 continue 475 continue
533 } 476 }
534 return nil, &OpError{"accept", fd.net, fd.laddr, err} 477 return nil, &OpError{"accept", fd.net, fd.laddr, err}
535 } 478 }
536 break 479 break
537 } 480 }
(...skipping 23 matching lines...) Expand all
561 if err = syscall.SetNonblock(ns, false); err != nil { 504 if err = syscall.SetNonblock(ns, false); err != nil {
562 return nil, &OpError{"setnonblock", fd.net, fd.laddr, err} 505 return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
563 } 506 }
564 507
565 return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil 508 return os.NewFile(uintptr(ns), fd.sysfile.Name()), nil
566 } 509 }
567 510
568 func closesocket(s int) error { 511 func closesocket(s int) error {
569 return syscall.Close(s) 512 return syscall.Close(s)
570 } 513 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b