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

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

Issue 8608044: code review 8608044: net: separate pollster initialization from network file descriptor allocation (Closed)
Left Patch Set: diff -r adc2b4f10096 https://code.google.com/p/go Created 10 years, 7 months ago
Right Patch Set: diff -r edb46df3ae05 https://code.google.com/p/go Created 10 years, 7 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 | « src/pkg/net/fd_unix.go ('k') | src/pkg/net/file_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 2010 The Go Authors. All rights reserved. 1 // Copyright 2010 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 package net 5 package net
6 6
7 import ( 7 import (
8 "errors" 8 "errors"
9 "io" 9 "io"
10 "os" 10 "os"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // implementation of DialTimeout. 60 // implementation of DialTimeout.
61 return resolveAndDialChannel(net, addr, localAddr, deadline) 61 return resolveAndDialChannel(net, addr, localAddr, deadline)
62 } 62 }
63 ra, err := resolveAddr("dial", net, addr, deadline) 63 ra, err := resolveAddr("dial", net, addr, deadline)
64 if err != nil { 64 if err != nil {
65 return nil, err 65 return nil, err
66 } 66 }
67 return dial(net, addr, localAddr, ra, deadline) 67 return dial(net, addr, localAddr, ra, deadline)
68 } 68 }
69 69
70 // Interface for all IO operations. 70 // operation contains superset of data necessary to perform all async IO.
71 type anOpIface interface { 71 type operation struct {
72 » Op() *anOp
73 » Name() string
74 » Submit() error
75 }
76
77 // anOp implements functionality common to all IO operations.
78 // Its beginning must be the same as runtime.net_anOp. Keep these in sync.
79 type anOp struct {
80 // Used by IOCP interface, it must be first field 72 // Used by IOCP interface, it must be first field
81 // of the struct, as our code rely on it. 73 // of the struct, as our code rely on it.
82 o syscall.Overlapped 74 o syscall.Overlapped
83 75
84 // fields used by runtime.netpoll 76 // fields used by runtime.netpoll
85 runtimeCtx uintptr 77 runtimeCtx uintptr
86 mode int32 78 mode int32
87 errno int32 79 errno int32
88 qty uint32 80 qty uint32
89 81
90 » errnoc chan error 82 » // fields used only by net package
83 » mu sync.Mutex
91 fd *netFD 84 fd *netFD
92 } 85 » errc chan error
93 86 » buf syscall.WSABuf
94 func (o *anOp) Init(fd *netFD, mode int32) { 87 » sa syscall.Sockaddr
95 » o.fd = fd 88 » rsa *syscall.RawSockaddrAny
96 » o.mode = mode 89 » rsan int32
97 » o.runtimeCtx = fd.pd.runtimeCtx 90 » handle syscall.Handle
98 » if !canCancelIO { 91 » flags uint32
99 » » var i int 92 }
100 » » if mode == 'r' { 93
101 » » » i = 0 94 func (o *operation) InitBuf(buf []byte) {
102 » » } else {
103 » » » i = 1
104 » » }
105 » » if fd.errnoc[i] == nil {
106 » » » fd.errnoc[i] = make(chan error)
107 » » }
108 » » o.errnoc = fd.errnoc[i]
109 » }
110 }
111
112 func (o *anOp) Op() *anOp {
113 » return o
114 }
115
116 // bufOp is used by IO operations that read / write
117 // data from / to client buffer.
118 type bufOp struct {
119 » anOp
120 » buf syscall.WSABuf
121 }
122
123 func (o *bufOp) Init(fd *netFD, buf []byte, mode int32) {
124 » o.anOp.Init(fd, mode)
125 o.buf.Len = uint32(len(buf)) 95 o.buf.Len = uint32(len(buf))
126 » if len(buf) == 0 { 96 » o.buf.Buf = nil
127 » » o.buf.Buf = nil 97 » if len(buf) != 0 {
128 » } else {
129 o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0])) 98 o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0]))
130 } 99 }
131 } 100 }
132 101
133 // ioSrv executes net IO requests. 102 // ioSrv executes net IO requests.
134 type ioSrv struct { 103 type ioSrv struct {
135 » submchan chan anOpIface // submit IO requests 104 » req chan ioSrvReq
136 » canchan chan anOpIface // cancel IO requests 105 }
106
107 type ioSrvReq struct {
108 » o *operation
109 » submit func(o *operation) error // if nil, cancel the operation
137 } 110 }
138 111
139 // ProcessRemoteIO will execute submit IO requests on behalf 112 // ProcessRemoteIO will execute submit IO requests on behalf
140 // of other goroutines, all on a single os thread, so it can 113 // of other goroutines, all on a single os thread, so it can
141 // cancel them later. Results of all operations will be sent 114 // cancel them later. Results of all operations will be sent
142 // back to their requesters via channel supplied in request. 115 // back to their requesters via channel supplied in request.
143 // It is used only when the CancelIoEx API is unavailable. 116 // It is used only when the CancelIoEx API is unavailable.
144 func (s *ioSrv) ProcessRemoteIO() { 117 func (s *ioSrv) ProcessRemoteIO() {
145 runtime.LockOSThread() 118 runtime.LockOSThread()
146 defer runtime.UnlockOSThread() 119 defer runtime.UnlockOSThread()
147 » for { 120 » for r := range s.req {
148 » » select { 121 » » if r.submit != nil {
149 » » case o := <-s.submchan: 122 » » » r.o.errc <- r.submit(r.o)
150 » » » o.Op().errnoc <- o.Submit() 123 » » } else {
151 » » case o := <-s.canchan: 124 » » » r.o.errc <- syscall.CancelIo(r.o.fd.sysfd)
152 » » » o.Op().errnoc <- syscall.CancelIo(syscall.Handle(o.Op(). fd.sysfd)) 125 » » }
153 » » } 126 » }
154 » } 127 }
155 } 128
156 129 // ExecIO executes a single IO operation o. It submits and cancels
157 // ExecIO executes a single IO operation oi. It submits and cancels
158 // IO in the current thread for systems where Windows CancelIoEx API 130 // IO in the current thread for systems where Windows CancelIoEx API
159 // is available. Alternatively, it passes the request onto 131 // is available. Alternatively, it passes the request onto
160 // runtime netpoll and waits for completion or cancels request. 132 // runtime netpoll and waits for completion or cancels request.
161 func (s *ioSrv) ExecIO(oi anOpIface) (int, error) { 133 func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro r) (int, error) {
162 » var err error 134 » fd := o.fd
163 » o := oi.Op()
164 // Notify runtime netpoll about starting IO. 135 // Notify runtime netpoll about starting IO.
165 » err = o.fd.pd.Prepare(int(o.mode)) 136 » err := fd.pd.Prepare(int(o.mode))
166 » if err != nil { 137 » if err != nil {
167 » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err} 138 » » return 0, &OpError{name, fd.net, fd.laddr, err}
168 } 139 }
169 // Start IO. 140 // Start IO.
170 if canCancelIO { 141 if canCancelIO {
171 » » err = oi.Submit() 142 » » err = submit(o)
172 } else { 143 } else {
173 // Send request to a special dedicated thread, 144 // Send request to a special dedicated thread,
174 // so it can stop the IO with CancelIO later. 145 // so it can stop the IO with CancelIO later.
175 » » s.submchan <- oi 146 » » s.req <- ioSrvReq{o, submit}
176 » » err = <-o.errnoc 147 » » err = <-o.errc
177 } 148 }
178 switch err { 149 switch err {
179 case nil: 150 case nil:
180 // IO completed immediately, but we need to get our completion m essage anyway. 151 // IO completed immediately, but we need to get our completion m essage anyway.
181 case syscall.ERROR_IO_PENDING: 152 case syscall.ERROR_IO_PENDING:
182 // IO started, and we have to wait for its completion. 153 // IO started, and we have to wait for its completion.
183 err = nil 154 err = nil
184 default: 155 default:
185 » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err} 156 » » return 0, &OpError{name, fd.net, fd.laddr, err}
186 } 157 }
187 // Wait for our request to complete. 158 // Wait for our request to complete.
188 » err = o.fd.pd.Wait(int(o.mode)) 159 » err = fd.pd.Wait(int(o.mode))
189 if err == nil { 160 if err == nil {
190 // All is good. Extract our IO results and return. 161 // All is good. Extract our IO results and return.
191 if o.errno != 0 { 162 if o.errno != 0 {
192 err = syscall.Errno(o.errno) 163 err = syscall.Errno(o.errno)
193 » » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err} 164 » » » return 0, &OpError{name, fd.net, fd.laddr, err}
194 } 165 }
195 return int(o.qty), nil 166 return int(o.qty), nil
196 } 167 }
197 // IO is interrupted by "close" or "timeout" 168 // IO is interrupted by "close" or "timeout"
198 netpollErr := err 169 netpollErr := err
199 switch netpollErr { 170 switch netpollErr {
200 case errClosing, errTimeout: 171 case errClosing, errTimeout:
201 // will deal with those. 172 // will deal with those.
202 default: 173 default:
203 panic("net: unexpected runtime.netpoll error: " + netpollErr.Err or()) 174 panic("net: unexpected runtime.netpoll error: " + netpollErr.Err or())
204 } 175 }
205 // Cancel our request. 176 // Cancel our request.
206 if canCancelIO { 177 if canCancelIO {
207 » » err := syscall.CancelIoEx(syscall.Handle(o.Op().fd.sysfd), &o.o) 178 » » err := syscall.CancelIoEx(fd.sysfd, &o.o)
208 // Assuming ERROR_NOT_FOUND is returned, if IO is completed. 179 // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
209 if err != nil && err != syscall.ERROR_NOT_FOUND { 180 if err != nil && err != syscall.ERROR_NOT_FOUND {
210 // TODO(brainman): maybe do something else, but panic. 181 // TODO(brainman): maybe do something else, but panic.
211 panic(err) 182 panic(err)
212 } 183 }
213 } else { 184 } else {
214 » » s.canchan <- oi 185 » » s.req <- ioSrvReq{o, nil}
215 » » <-o.errnoc 186 » » <-o.errc
216 } 187 }
217 // Wait for cancellation to complete. 188 // Wait for cancellation to complete.
218 » o.fd.pd.WaitCanceled(int(o.mode)) 189 » fd.pd.WaitCanceled(int(o.mode))
219 if o.errno != 0 { 190 if o.errno != 0 {
220 err = syscall.Errno(o.errno) 191 err = syscall.Errno(o.errno)
221 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 192 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
222 err = netpollErr 193 err = netpollErr
223 } 194 }
224 » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err} 195 » » return 0, &OpError{name, fd.net, fd.laddr, err}
225 } 196 }
226 // We issued cancellation request. But, it seems, IO operation succeeded 197 // We issued cancellation request. But, it seems, IO operation succeeded
227 // before cancellation request run. We need to treat IO operation as 198 // before cancellation request run. We need to treat IO operation as
228 // succeeded (the bytes are actually sent/recv from network). 199 // succeeded (the bytes are actually sent/recv from network).
229 return int(o.qty), nil 200 return int(o.qty), nil
230 } 201 }
231 202
232 // Start helper goroutines. 203 // Start helper goroutines.
233 var iosrv *ioSrv 204 var iosrv *ioSrv
234 var onceStartServer sync.Once 205 var onceStartServer sync.Once
235 206
236 func startServer() { 207 func startServer() {
237 iosrv = new(ioSrv) 208 iosrv = new(ioSrv)
238 if !canCancelIO { 209 if !canCancelIO {
239 // Only CancelIo API is available. Lets start special goroutine 210 // Only CancelIo API is available. Lets start special goroutine
240 // locked to an OS thread, that both starts and cancels IO. 211 // locked to an OS thread, that both starts and cancels IO.
241 » » iosrv.submchan = make(chan anOpIface) 212 » » iosrv.req = make(chan ioSrvReq)
242 » » iosrv.canchan = make(chan anOpIface)
243 go iosrv.ProcessRemoteIO() 213 go iosrv.ProcessRemoteIO()
244 } 214 }
245 } 215 }
246 216
247 // Network file descriptor. 217 // Network file descriptor.
248 type netFD struct { 218 type netFD struct {
249 // locking/lifetime of sysfd 219 // locking/lifetime of sysfd
250 sysmu sync.Mutex 220 sysmu sync.Mutex
251 sysref int 221 sysref int
252 closing bool 222 closing bool
253 223
254 // immutable until Close 224 // immutable until Close
255 sysfd syscall.Handle 225 sysfd syscall.Handle
256 family int 226 family int
257 sotype int 227 sotype int
258 isConnected bool 228 isConnected bool
259 net string 229 net string
260 laddr Addr 230 laddr Addr
261 raddr Addr 231 raddr Addr
262 » errnoc [2]chan error // read/write submit or cancel operation error s 232
263 233 » rop operation // read operation
264 » // serialize access to Read and Write methods 234 » wop operation // write operation
265 » rio, wio sync.Mutex
266 235
267 // wait server 236 // wait server
268 pd pollDesc 237 pd pollDesc
269 } 238 }
270 239
271 func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) { 240 func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
272 if initErr != nil { 241 if initErr != nil {
273 return nil, initErr 242 return nil, initErr
274 } 243 }
275 onceStartServer.Do(startServer) 244 onceStartServer.Do(startServer)
276 return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, n il 245 return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, n il
277 } 246 }
278 247
279 func (fd *netFD) init() error { 248 func (fd *netFD) init() error {
280 if err := fd.pd.Init(fd); err != nil { 249 if err := fd.pd.Init(fd); err != nil {
281 return err 250 return err
251 }
252 fd.rop.mode = 'r'
253 fd.wop.mode = 'w'
254 fd.rop.fd = fd
255 fd.wop.fd = fd
256 fd.rop.runtimeCtx = fd.pd.runtimeCtx
257 fd.wop.runtimeCtx = fd.pd.runtimeCtx
258 if !canCancelIO {
259 fd.rop.errc = make(chan error)
260 fd.rop.errc = make(chan error)
282 } 261 }
283 return nil 262 return nil
284 } 263 }
285 264
286 func (fd *netFD) setAddr(laddr, raddr Addr) { 265 func (fd *netFD) setAddr(laddr, raddr Addr) {
287 fd.laddr = laddr 266 fd.laddr = laddr
288 fd.raddr = raddr 267 fd.raddr = raddr
289 runtime.SetFinalizer(fd, (*netFD).Close) 268 runtime.SetFinalizer(fd, (*netFD).Close)
290 }
291
292 // Make new connection.
293
294 type connectOp struct {
295 anOp
296 ra syscall.Sockaddr
297 }
298
299 func (o *connectOp) Submit() error {
300 return syscall.ConnectEx(o.fd.sysfd, o.ra, nil, 0, nil, &o.o)
301 }
302
303 func (o *connectOp) Name() string {
304 return "ConnectEx"
305 } 269 }
306 270
307 func (fd *netFD) connect(la, ra syscall.Sockaddr) error { 271 func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
308 if !canUseConnectEx(fd.net) { 272 if !canUseConnectEx(fd.net) {
309 return syscall.Connect(fd.sysfd, ra) 273 return syscall.Connect(fd.sysfd, ra)
310 } 274 }
311 // ConnectEx windows API requires an unconnected, previously bound socke t. 275 // ConnectEx windows API requires an unconnected, previously bound socke t.
312 if la == nil { 276 if la == nil {
313 switch ra.(type) { 277 switch ra.(type) {
314 case *syscall.SockaddrInet4: 278 case *syscall.SockaddrInet4:
315 la = &syscall.SockaddrInet4{} 279 la = &syscall.SockaddrInet4{}
316 case *syscall.SockaddrInet6: 280 case *syscall.SockaddrInet6:
317 la = &syscall.SockaddrInet6{} 281 la = &syscall.SockaddrInet6{}
318 default: 282 default:
319 panic("unexpected type in connect") 283 panic("unexpected type in connect")
320 } 284 }
321 if err := syscall.Bind(fd.sysfd, la); err != nil { 285 if err := syscall.Bind(fd.sysfd, la); err != nil {
322 return err 286 return err
323 } 287 }
324 } 288 }
325 // Call ConnectEx API. 289 // Call ConnectEx API.
326 » var o connectOp 290 » o := &fd.wop
327 » o.Init(fd, 'w') 291 » o.mu.Lock()
328 » o.ra = ra 292 » defer o.mu.Unlock()
329 » _, err := iosrv.ExecIO(&o) 293 » o.sa = ra
294 » _, err := iosrv.ExecIO(o, "ConnectEx", func(o *operation) error {
295 » » return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
296 » })
330 if err != nil { 297 if err != nil {
331 return err 298 return err
332 } 299 }
333 // Refresh socket properties. 300 // Refresh socket properties.
334 return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDAT E_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sy sfd))) 301 return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDAT E_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sy sfd)))
335 } 302 }
336 303
337 // Add a reference to this fd. 304 // Add a reference to this fd.
338 // If closing==true, mark the fd as closing. 305 // If closing==true, mark the fd as closing.
339 // Returns an error if the fd cannot be used. 306 // Returns an error if the fd cannot be used.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 343 }
377 344
378 func (fd *netFD) Close() error { 345 func (fd *netFD) Close() error {
379 if err := fd.incref(true); err != nil { 346 if err := fd.incref(true); err != nil {
380 return err 347 return err
381 } 348 }
382 defer fd.decref() 349 defer fd.decref()
383 // unblock pending reader and writer 350 // unblock pending reader and writer
384 fd.pd.Evict() 351 fd.pd.Evict()
385 // wait for both reader and writer to exit 352 // wait for both reader and writer to exit
386 » fd.rio.Lock() 353 » fd.rop.mu.Lock()
387 » defer fd.rio.Unlock() 354 » fd.wop.mu.Lock()
388 » fd.wio.Lock() 355 » fd.rop.mu.Unlock()
389 » defer fd.wio.Unlock() 356 » fd.wop.mu.Unlock()
390 return nil 357 return nil
391 } 358 }
392 359
393 func (fd *netFD) shutdown(how int) error { 360 func (fd *netFD) shutdown(how int) error {
394 if err := fd.incref(false); err != nil { 361 if err := fd.incref(false); err != nil {
395 return err 362 return err
396 } 363 }
397 defer fd.decref() 364 defer fd.decref()
398 err := syscall.Shutdown(fd.sysfd, how) 365 err := syscall.Shutdown(fd.sysfd, how)
399 if err != nil { 366 if err != nil {
400 return &OpError{"shutdown", fd.net, fd.laddr, err} 367 return &OpError{"shutdown", fd.net, fd.laddr, err}
401 } 368 }
402 return nil 369 return nil
403 } 370 }
404 371
405 func (fd *netFD) CloseRead() error { 372 func (fd *netFD) CloseRead() error {
406 return fd.shutdown(syscall.SHUT_RD) 373 return fd.shutdown(syscall.SHUT_RD)
407 } 374 }
408 375
409 func (fd *netFD) CloseWrite() error { 376 func (fd *netFD) CloseWrite() error {
410 return fd.shutdown(syscall.SHUT_WR) 377 return fd.shutdown(syscall.SHUT_WR)
411 } 378 }
412 379
413 // Read from network.
414
415 type readOp struct {
416 bufOp
417 }
418
419 func (o *readOp) Submit() error {
420 var d, f uint32
421 return syscall.WSARecv(syscall.Handle(o.fd.sysfd), &o.buf, 1, &d, &f, &o .o, nil)
422 }
423
424 func (o *readOp) Name() string {
425 return "WSARecv"
426 }
427
428 func (fd *netFD) Read(buf []byte) (int, error) { 380 func (fd *netFD) Read(buf []byte) (int, error) {
429 if err := fd.incref(false); err != nil { 381 if err := fd.incref(false); err != nil {
430 return 0, err 382 return 0, err
431 } 383 }
432 defer fd.decref() 384 defer fd.decref()
433 » fd.rio.Lock() 385 » o := &fd.rop
434 » defer fd.rio.Unlock() 386 » o.mu.Lock()
435 » var o readOp 387 » defer o.mu.Unlock()
436 » o.Init(fd, buf, 'r') 388 » o.InitBuf(buf)
437 » n, err := iosrv.ExecIO(&o) 389 » n, err := iosrv.ExecIO(o, "WSARecv", func(o *operation) error {
390 » » return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
391 » })
438 if err == nil && n == 0 { 392 if err == nil && n == 0 {
439 err = io.EOF 393 err = io.EOF
440 } 394 }
441 return n, err 395 return n, err
442 }
443
444 // ReadFrom from network.
445
446 type readFromOp struct {
447 bufOp
448 rsa syscall.RawSockaddrAny
449 rsan int32
450 }
451
452 func (o *readFromOp) Submit() error {
453 var d, f uint32
454 return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &o.rsa n, &o.o, nil)
455 }
456
457 func (o *readFromOp) Name() string {
458 return "WSARecvFrom"
459 } 396 }
460 397
461 func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { 398 func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
462 if len(buf) == 0 { 399 if len(buf) == 0 {
463 return 0, nil, nil 400 return 0, nil, nil
464 } 401 }
465 if err := fd.incref(false); err != nil { 402 if err := fd.incref(false); err != nil {
466 return 0, nil, err 403 return 0, nil, err
467 } 404 }
468 defer fd.decref() 405 defer fd.decref()
469 » fd.rio.Lock() 406 » o := &fd.rop
470 » defer fd.rio.Unlock() 407 » o.mu.Lock()
471 » var o readFromOp 408 » defer o.mu.Unlock()
472 » o.Init(fd, buf, 'r') 409 » o.InitBuf(buf)
473 » o.rsan = int32(unsafe.Sizeof(o.rsa)) 410 » n, err = iosrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
474 » n, err = iosrv.ExecIO(&o) 411 » » if o.rsa == nil {
412 » » » o.rsa = new(syscall.RawSockaddrAny)
413 » » }
414 » » o.rsan = int32(unsafe.Sizeof(*o.rsa))
415 » » return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.fla gs, o.rsa, &o.rsan, &o.o, nil)
416 » })
475 if err != nil { 417 if err != nil {
476 return 0, nil, err 418 return 0, nil, err
477 } 419 }
478 sa, _ = o.rsa.Sockaddr() 420 sa, _ = o.rsa.Sockaddr()
479 return 421 return
480 }
481
482 // Write to network.
483
484 type writeOp struct {
485 bufOp
486 }
487
488 func (o *writeOp) Submit() error {
489 var d uint32
490 return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &d, 0, &o.o, nil)
491 }
492
493 func (o *writeOp) Name() string {
494 return "WSASend"
495 } 422 }
496 423
497 func (fd *netFD) Write(buf []byte) (int, error) { 424 func (fd *netFD) Write(buf []byte) (int, error) {
498 if err := fd.incref(false); err != nil { 425 if err := fd.incref(false); err != nil {
499 return 0, err 426 return 0, err
500 } 427 }
501 defer fd.decref() 428 defer fd.decref()
502 » fd.wio.Lock() 429 » o := &fd.wop
503 » defer fd.wio.Unlock() 430 » o.mu.Lock()
504 » var o writeOp 431 » defer o.mu.Unlock()
505 » o.Init(fd, buf, 'w') 432 » o.InitBuf(buf)
506 » return iosrv.ExecIO(&o) 433 » return iosrv.ExecIO(o, "WSASend", func(o *operation) error {
507 } 434 » » return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, n il)
508 435 » })
509 // WriteTo to network.
510
511 type writeToOp struct {
512 » bufOp
513 » sa syscall.Sockaddr
514 }
515
516 func (o *writeToOp) Submit() error {
517 » var d uint32
518 » return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &d, 0, o.sa, &o.o, nil)
519 }
520
521 func (o *writeToOp) Name() string {
522 » return "WSASendto"
523 } 436 }
524 437
525 func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { 438 func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
526 if len(buf) == 0 { 439 if len(buf) == 0 {
527 return 0, nil 440 return 0, nil
528 } 441 }
529 if err := fd.incref(false); err != nil { 442 if err := fd.incref(false); err != nil {
530 return 0, err 443 return 0, err
531 } 444 }
532 defer fd.decref() 445 defer fd.decref()
533 » fd.wio.Lock() 446 » o := &fd.wop
534 » defer fd.wio.Unlock() 447 » o.mu.Lock()
535 » var o writeToOp 448 » defer o.mu.Unlock()
536 » o.Init(fd, buf, 'w') 449 » o.InitBuf(buf)
537 o.sa = sa 450 o.sa = sa
538 » return iosrv.ExecIO(&o) 451 » return iosrv.ExecIO(o, "WSASendto", func(o *operation) error {
539 } 452 » » return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
540 453 » })
541 // Accept new network connections.
542
543 type acceptOp struct {
544 » anOp
545 » newsock syscall.Handle
546 » attrs [2]syscall.RawSockaddrAny // space for local and remote address only
547 }
548
549 func (o *acceptOp) Submit() error {
550 » var d uint32
551 » l := uint32(unsafe.Sizeof(o.attrs[0]))
552 » return syscall.AcceptEx(o.fd.sysfd, o.newsock,
553 » » (*byte)(unsafe.Pointer(&o.attrs[0])), 0, l, l, &d, &o.o)
554 }
555
556 func (o *acceptOp) Name() string {
557 » return "AcceptEx"
558 } 454 }
559 455
560 func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) { 456 func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
561 if err := fd.incref(false); err != nil { 457 if err := fd.incref(false); err != nil {
562 return nil, err 458 return nil, err
563 } 459 }
564 defer fd.decref() 460 defer fd.decref()
565 461
566 // Get new socket. 462 // Get new socket.
567 s, err := sysSocket(fd.family, fd.sotype, 0) 463 s, err := sysSocket(fd.family, fd.sotype, 0)
568 if err != nil { 464 if err != nil {
569 return nil, &OpError{"socket", fd.net, fd.laddr, err} 465 return nil, &OpError{"socket", fd.net, fd.laddr, err}
570 } 466 }
571 467
572 // Associate our new socket with IOCP. 468 // Associate our new socket with IOCP.
573 netfd, err := newFD(s, fd.family, fd.sotype, fd.net) 469 netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
574 if err != nil { 470 if err != nil {
575 closesocket(s) 471 closesocket(s)
576 return nil, &OpError{"accept", fd.net, fd.laddr, err} 472 return nil, &OpError{"accept", fd.net, fd.laddr, err}
577 } 473 }
578 if err := netfd.init(); err != nil { 474 if err := netfd.init(); err != nil {
579 fd.Close() 475 fd.Close()
580 return nil, err 476 return nil, err
581 } 477 }
582 478
583 // Submit accept request. 479 // Submit accept request.
584 » fd.rio.Lock() 480 » o := &fd.rop
585 » defer fd.rio.Unlock() 481 » o.mu.Lock()
586 » var o acceptOp 482 » defer o.mu.Unlock()
587 » o.Init(fd, 'r') 483 » o.handle = s
588 » o.newsock = s 484 » var rawsa [2]syscall.RawSockaddrAny
589 » _, err = iosrv.ExecIO(&o) 485 » o.rsan = int32(unsafe.Sizeof(rawsa[0]))
486 » _, err = iosrv.ExecIO(o, "AcceptEx", func(o *operation) error {
487 » » return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Poi nter(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
488 » })
590 if err != nil { 489 if err != nil {
591 netfd.Close() 490 netfd.Close()
592 return nil, err 491 return nil, err
593 } 492 }
594 493
595 // Inherit properties of the listening socket. 494 // Inherit properties of the listening socket.
596 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT _CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))) 495 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT _CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
597 if err != nil { 496 if err != nil {
598 netfd.Close() 497 netfd.Close()
599 return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err} 498 return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
600 } 499 }
601 500
602 // Get local and peer addr out of AcceptEx buffer. 501 // Get local and peer addr out of AcceptEx buffer.
603 var lrsa, rrsa *syscall.RawSockaddrAny 502 var lrsa, rrsa *syscall.RawSockaddrAny
604 var llen, rlen int32 503 var llen, rlen int32
605 » l := uint32(unsafe.Sizeof(*lrsa)) 504 » syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
606 » syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&o.attrs[0])), 505 » » 0, uint32(o.rsan), uint32(o.rsan), &lrsa, &llen, &rrsa, &rlen)
607 » » 0, l, l, &lrsa, &llen, &rrsa, &rlen)
608 lsa, _ := lrsa.Sockaddr() 506 lsa, _ := lrsa.Sockaddr()
609 rsa, _ := rrsa.Sockaddr() 507 rsa, _ := rrsa.Sockaddr()
610 508
611 netfd.setAddr(toAddr(lsa), toAddr(rsa)) 509 netfd.setAddr(toAddr(lsa), toAddr(rsa))
612 return netfd, nil 510 return netfd, nil
613 } 511 }
614 512
615 // Unimplemented functions. 513 // Unimplemented functions.
616 514
617 func (fd *netFD) dup() (*os.File, error) { 515 func (fd *netFD) dup() (*os.File, error) {
618 // TODO: Implement this 516 // TODO: Implement this
619 return nil, os.NewSyscallError("dup", syscall.EWINDOWS) 517 return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
620 } 518 }
621 519
622 var errNoSupport = errors.New("address family not supported") 520 var errNoSupport = errors.New("address family not supported")
623 521
624 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) { 522 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) {
625 return 0, 0, 0, nil, errNoSupport 523 return 0, 0, 0, nil, errNoSupport
626 } 524 }
627 525
628 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) { 526 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) {
629 return 0, 0, errNoSupport 527 return 0, 0, errNoSupport
630 } 528 }
LEFTRIGHT

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