LEFT | RIGHT |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
LEFT | RIGHT |