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