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

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

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