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

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

Issue 8670044: code review 8670044: net: implement netpoll for windows (Closed)
Left Patch Set: Created 10 years, 11 months ago
Right Patch Set: diff -r 5ee81a14cdfe https://go.googlecode.com/hg/ Created 10 years, 8 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:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/net/fd_poll_runtime.go ('k') | src/pkg/net/sendfile_windows.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
(no file at all)
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 // Interface for all IO operations.
71 type anOpIface interface { 71 type anOpIface interface {
72 Op() *anOp 72 Op() *anOp
73 Name() string 73 Name() string
74 Submit() error 74 Submit() error
75 } 75 }
76 76
77 // IO completion result parameters.
78 type ioResult struct {
79 qty uint32
80 err error
81 }
82
83 // anOp implements functionality common to all IO operations. 77 // anOp implements functionality common to all IO operations.
78 // Its beginning must be the same as runtime.net_anOp. Keep these in sync.
84 type anOp struct { 79 type anOp struct {
85 // Used by IOCP interface, it must be first field 80 // Used by IOCP interface, it must be first field
86 // of the struct, as our code rely on it. 81 // of the struct, as our code rely on it.
87 o syscall.Overlapped 82 o syscall.Overlapped
88 83
89 » resultc chan ioResult 84 » // fields used by runtime.netpoll
90 » errnoc chan error 85 » runtimeCtx uintptr
91 » fd *netFD 86 » mode int32
92 } 87 » errno int32
93 88 » qty uint32
94 func (o *anOp) Init(fd *netFD, mode int) { 89
90 » errnoc chan error
91 » fd *netFD
92 }
93
94 func (o *anOp) Init(fd *netFD, mode int32) {
95 o.fd = fd 95 o.fd = fd
96 » var i int 96 » o.mode = mode
97 » if mode == 'r' { 97 » o.runtimeCtx = fd.pd.runtimeCtx
98 » » i = 0 98 » if !canCancelIO {
99 » } else { 99 » » var i int
100 » » i = 1 100 » » if mode == 'r' {
101 » } 101 » » » i = 0
102 » if fd.resultc[i] == nil { 102 » » } else {
103 » » fd.resultc[i] = make(chan ioResult, 1) 103 » » » i = 1
104 » } 104 » » }
105 » o.resultc = fd.resultc[i] 105 » » if fd.errnoc[i] == nil {
106 » if fd.errnoc[i] == nil { 106 » » » fd.errnoc[i] = make(chan error)
107 » » fd.errnoc[i] = make(chan error) 107 » » }
108 » } 108 » » o.errnoc = fd.errnoc[i]
109 » o.errnoc = fd.errnoc[i] 109 » }
110 } 110 }
111 111
112 func (o *anOp) Op() *anOp { 112 func (o *anOp) Op() *anOp {
113 return o 113 return o
114 } 114 }
115 115
116 // bufOp is used by IO operations that read / write 116 // bufOp is used by IO operations that read / write
117 // data from / to client buffer. 117 // data from / to client buffer.
118 type bufOp struct { 118 type bufOp struct {
119 anOp 119 anOp
120 buf syscall.WSABuf 120 buf syscall.WSABuf
121 } 121 }
122 122
123 func (o *bufOp) Init(fd *netFD, buf []byte, mode int) { 123 func (o *bufOp) Init(fd *netFD, buf []byte, mode int32) {
124 o.anOp.Init(fd, mode) 124 o.anOp.Init(fd, mode)
125 o.buf.Len = uint32(len(buf)) 125 o.buf.Len = uint32(len(buf))
126 if len(buf) == 0 { 126 if len(buf) == 0 {
127 o.buf.Buf = nil 127 o.buf.Buf = nil
128 } else { 128 } else {
129 o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0])) 129 o.buf.Buf = (*byte)(unsafe.Pointer(&buf[0]))
130 }
131 }
132
133 // resultSrv will retrieve all IO completion results from
134 // iocp and send them to the correspondent waiting client
135 // goroutine via channel supplied in the request.
136 type resultSrv struct {
137 iocp syscall.Handle
138 }
139
140 func runtime_blockingSyscallHint()
141
142 func (s *resultSrv) Run() {
143 var o *syscall.Overlapped
144 var key uint32
145 var r ioResult
146 for {
147 r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key , &o, 0)
148 if r.err == syscall.Errno(syscall.WAIT_TIMEOUT) && o == nil {
149 runtime_blockingSyscallHint()
150 r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qt y), &key, &o, syscall.INFINITE)
151 }
152 switch {
153 case r.err == nil:
154 // Dequeued successfully completed IO packet.
155 case r.err == syscall.Errno(syscall.WAIT_TIMEOUT) && o == nil:
156 // Wait has timed out (should not happen now, but might be used in the future).
157 panic("GetQueuedCompletionStatus timed out")
158 case o == nil:
159 // Failed to dequeue anything -> report the error.
160 panic("GetQueuedCompletionStatus failed " + r.err.Error( ))
161 default:
162 // Dequeued failed IO packet.
163 }
164 (*anOp)(unsafe.Pointer(o)).resultc <- r
165 } 130 }
166 } 131 }
167 132
168 // ioSrv executes net IO requests. 133 // ioSrv executes net IO requests.
169 type ioSrv struct { 134 type ioSrv struct {
170 submchan chan anOpIface // submit IO requests 135 submchan chan anOpIface // submit IO requests
171 canchan chan anOpIface // cancel IO requests 136 canchan chan anOpIface // cancel IO requests
172 } 137 }
173 138
174 // ProcessRemoteIO will execute submit IO requests on behalf 139 // ProcessRemoteIO will execute submit IO requests on behalf
(...skipping 10 matching lines...) Expand all
185 o.Op().errnoc <- o.Submit() 150 o.Op().errnoc <- o.Submit()
186 case o := <-s.canchan: 151 case o := <-s.canchan:
187 o.Op().errnoc <- syscall.CancelIo(syscall.Handle(o.Op(). fd.sysfd)) 152 o.Op().errnoc <- syscall.CancelIo(syscall.Handle(o.Op(). fd.sysfd))
188 } 153 }
189 } 154 }
190 } 155 }
191 156
192 // ExecIO executes a single IO operation oi. It submits and cancels 157 // ExecIO executes a single IO operation oi. It submits and cancels
193 // IO in the current thread for systems where Windows CancelIoEx API 158 // IO in the current thread for systems where Windows CancelIoEx API
194 // is available. Alternatively, it passes the request onto 159 // is available. Alternatively, it passes the request onto
195 // a special goroutine and waits for completion or cancels request. 160 // runtime netpoll and waits for completion or cancels request.
196 // deadline is unix nanos. 161 func (s *ioSrv) ExecIO(oi anOpIface) (int, error) {
197 func (s *ioSrv) ExecIO(oi anOpIface, deadline int64) (int, error) {
198 var err error 162 var err error
199 o := oi.Op() 163 o := oi.Op()
200 » // Calculate timeout delta. 164 » // Notify runtime netpoll about starting IO.
201 » var delta int64 165 » err = o.fd.pd.Prepare(int(o.mode))
202 » if deadline != 0 { 166 » if err != nil {
203 » » delta = deadline - time.Now().UnixNano() 167 » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err}
204 » » if delta <= 0 {
205 » » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, errT imeout}
206 » » }
207 } 168 }
208 // Start IO. 169 // Start IO.
209 if canCancelIO { 170 if canCancelIO {
210 err = oi.Submit() 171 err = oi.Submit()
211 } else { 172 } else {
212 // Send request to a special dedicated thread, 173 // Send request to a special dedicated thread,
213 // so it can stop the IO with CancelIO later. 174 // so it can stop the IO with CancelIO later.
214 s.submchan <- oi 175 s.submchan <- oi
215 err = <-o.errnoc 176 err = <-o.errnoc
216 } 177 }
217 switch err { 178 switch err {
218 case nil: 179 case nil:
219 // IO completed immediately, but we need to get our completion m essage anyway. 180 // IO completed immediately, but we need to get our completion m essage anyway.
220 case syscall.ERROR_IO_PENDING: 181 case syscall.ERROR_IO_PENDING:
221 // IO started, and we have to wait for its completion. 182 // IO started, and we have to wait for its completion.
222 err = nil 183 err = nil
223 default: 184 default:
224 return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err} 185 return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err}
225 } 186 }
226 // Setup timer, if deadline is given.
227 var timer <-chan time.Time
228 if delta > 0 {
229 t := time.NewTimer(time.Duration(delta) * time.Nanosecond)
230 defer t.Stop()
231 timer = t.C
232 }
233 // Wait for our request to complete. 187 // Wait for our request to complete.
234 » var r ioResult 188 » err = o.fd.pd.Wait(int(o.mode))
235 » var cancelled, timeout bool 189 » if err == nil {
236 » select { 190 » » // All is good. Extract our IO results and return.
237 » case r = <-o.resultc: 191 » » if o.errno != 0 {
238 » case <-timer: 192 » » » err = syscall.Errno(o.errno)
239 » » cancelled = true 193 » » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err}
240 » » timeout = true 194 » » }
241 » case <-o.fd.closec: 195 » » return int(o.qty), nil
242 » » cancelled = true 196 » }
243 » } 197 » // IO is interrupted by "close" or "timeout"
244 » if cancelled { 198 » netpollErr := err
245 » » // Cancel it. 199 » switch netpollErr {
246 » » if canCancelIO { 200 » case errClosing, errTimeout:
247 » » » err := syscall.CancelIoEx(syscall.Handle(o.Op().fd.sysfd ), &o.o) 201 » » // will deal with those.
248 » » » // Assuming ERROR_NOT_FOUND is returned, if IO is comple ted. 202 » default:
249 » » » if err != nil && err != syscall.ERROR_NOT_FOUND { 203 » » panic("net: unexpected runtime.netpoll error: " + netpollErr.Err or())
250 » » » » // TODO(brainman): maybe do something else, but panic. 204 » }
251 » » » » panic(err) 205 » // Cancel our request.
252 » » » } 206 » if canCancelIO {
253 » » } else { 207 » » err := syscall.CancelIoEx(syscall.Handle(o.Op().fd.sysfd), &o.o)
254 » » » s.canchan <- oi 208 » » // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
255 » » » <-o.errnoc 209 » » if err != nil && err != syscall.ERROR_NOT_FOUND {
256 » » } 210 » » » // TODO(brainman): maybe do something else, but panic.
257 » » // Wait for IO to be canceled or complete successfully. 211 » » » panic(err)
258 » » r = <-o.resultc 212 » » }
259 » » if r.err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 213 » } else {
260 » » » if timeout { 214 » » s.canchan <- oi
261 » » » » r.err = errTimeout 215 » » <-o.errnoc
262 » » » } else { 216 » }
263 » » » » r.err = errClosing 217 » // Wait for cancellation to complete.
264 » » » } 218 » o.fd.pd.WaitCanceled(int(o.mode))
265 » » } 219 » if o.errno != 0 {
266 » } 220 » » err = syscall.Errno(o.errno)
267 » if r.err != nil { 221 » » if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
268 » » err = &OpError{oi.Name(), o.fd.net, o.fd.laddr, r.err} 222 » » » err = netpollErr
269 » } 223 » » }
270 » return int(r.qty), err 224 » » return 0, &OpError{oi.Name(), o.fd.net, o.fd.laddr, err}
225 » }
226 » // We issued cancellation request. But, it seems, IO operation succeeded
227 » // before cancellation request run. We need to treat IO operation as
228 » // succeeded (the bytes are actually sent/recv from network).
229 » return int(o.qty), nil
271 } 230 }
272 231
273 // Start helper goroutines. 232 // Start helper goroutines.
274 var resultsrv *resultSrv
275 var iosrv *ioSrv 233 var iosrv *ioSrv
276 var onceStartServer sync.Once 234 var onceStartServer sync.Once
277 235
278 func startServer() { 236 func startServer() {
279 resultsrv = new(resultSrv)
280 var err error
281 resultsrv.iocp, err = syscall.CreateIoCompletionPort(syscall.InvalidHand le, 0, 0, 1)
282 if err != nil {
283 panic("CreateIoCompletionPort: " + err.Error())
284 }
285 go resultsrv.Run()
286
287 iosrv = new(ioSrv) 237 iosrv = new(ioSrv)
288 if !canCancelIO { 238 if !canCancelIO {
289 // Only CancelIo API is available. Lets start special goroutine 239 // Only CancelIo API is available. Lets start special goroutine
290 // locked to an OS thread, that both starts and cancels IO. 240 // locked to an OS thread, that both starts and cancels IO.
291 iosrv.submchan = make(chan anOpIface) 241 iosrv.submchan = make(chan anOpIface)
292 iosrv.canchan = make(chan anOpIface) 242 iosrv.canchan = make(chan anOpIface)
293 go iosrv.ProcessRemoteIO() 243 go iosrv.ProcessRemoteIO()
294 } 244 }
295 } 245 }
296 246
297 // Network file descriptor. 247 // Network file descriptor.
298 type netFD struct { 248 type netFD struct {
299 // locking/lifetime of sysfd 249 // locking/lifetime of sysfd
300 sysmu sync.Mutex 250 sysmu sync.Mutex
301 sysref int 251 sysref int
302 closing bool 252 closing bool
303 253
304 // immutable until Close 254 // immutable until Close
305 sysfd syscall.Handle 255 sysfd syscall.Handle
306 family int 256 family int
307 sotype int 257 sotype int
308 isConnected bool 258 isConnected bool
309 net string 259 net string
310 laddr Addr 260 laddr Addr
311 raddr Addr 261 raddr Addr
312 » resultc [2]chan ioResult // read/write completion results 262 » errnoc [2]chan error // read/write submit or cancel operation error s
313 » errnoc [2]chan error // read/write submit or cancel operation er rors
314 » closec chan bool // used by Close to cancel pending IO
315 263
316 // serialize access to Read and Write methods 264 // serialize access to Read and Write methods
317 rio, wio sync.Mutex 265 rio, wio sync.Mutex
318 266
319 » // read and write deadlines 267 » // wait server
320 » rdeadline, wdeadline deadline 268 » pd pollDesc
321 } 269 }
322 270
323 func allocFD(fd syscall.Handle, family, sotype int, net string) *netFD { 271 func newFD(fd syscall.Handle, family, sotype int, net string) (*netFD, error) {
272 » if initErr != nil {
273 » » return nil, initErr
274 » }
275 » onceStartServer.Do(startServer)
324 netfd := &netFD{ 276 netfd := &netFD{
325 sysfd: fd, 277 sysfd: fd,
326 family: family, 278 family: family,
327 sotype: sotype, 279 sotype: sotype,
328 net: net, 280 net: net,
329 » » closec: make(chan bool), 281 » }
330 » } 282 » if err := netfd.pd.Init(netfd); err != nil {
331 » return netfd
332 }
333
334 func newFD(fd syscall.Handle, family, proto int, net string) (*netFD, error) {
335 » if initErr != nil {
336 » » return nil, initErr
337 » }
338 » onceStartServer.Do(startServer)
339 » // Associate our socket with resultsrv.iocp.
340 » if _, err := syscall.CreateIoCompletionPort(syscall.Handle(fd), resultsr v.iocp, 0, 0); err != nil {
341 return nil, err 283 return nil, err
342 } 284 }
343 » return allocFD(fd, family, proto, net), nil 285 » return netfd, nil
344 } 286 }
345 287
346 func (fd *netFD) setAddr(laddr, raddr Addr) { 288 func (fd *netFD) setAddr(laddr, raddr Addr) {
347 fd.laddr = laddr 289 fd.laddr = laddr
348 fd.raddr = raddr 290 fd.raddr = raddr
349 runtime.SetFinalizer(fd, (*netFD).closesocket) 291 runtime.SetFinalizer(fd, (*netFD).closesocket)
350 } 292 }
351 293
352 // Make new connection. 294 // Make new connection.
353 295
(...skipping 25 matching lines...) Expand all
379 panic("unexpected type in connect") 321 panic("unexpected type in connect")
380 } 322 }
381 if err := syscall.Bind(fd.sysfd, la); err != nil { 323 if err := syscall.Bind(fd.sysfd, la); err != nil {
382 return err 324 return err
383 } 325 }
384 } 326 }
385 // Call ConnectEx API. 327 // Call ConnectEx API.
386 var o connectOp 328 var o connectOp
387 o.Init(fd, 'w') 329 o.Init(fd, 'w')
388 o.ra = ra 330 o.ra = ra
389 » _, err := iosrv.ExecIO(&o, fd.wdeadline.value()) 331 » _, err := iosrv.ExecIO(&o)
390 if err != nil { 332 if err != nil {
391 return err 333 return err
392 } 334 }
393 // Refresh socket properties. 335 // Refresh socket properties.
394 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))) 336 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)))
395 } 337 }
396 338
397 // Add a reference to this fd. 339 // Add a reference to this fd.
398 // If closing==true, mark the fd as closing. 340 // If closing==true, mark the fd as closing.
399 // Returns an error if the fd cannot be used. 341 // Returns an error if the fd cannot be used.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 } 373 }
432 fd.sysmu.Unlock() 374 fd.sysmu.Unlock()
433 } 375 }
434 376
435 func (fd *netFD) Close() error { 377 func (fd *netFD) Close() error {
436 if err := fd.incref(true); err != nil { 378 if err := fd.incref(true); err != nil {
437 return err 379 return err
438 } 380 }
439 defer fd.decref() 381 defer fd.decref()
440 // unblock pending reader and writer 382 // unblock pending reader and writer
441 » close(fd.closec) 383 » fd.pd.Evict()
442 // wait for both reader and writer to exit 384 // wait for both reader and writer to exit
443 fd.rio.Lock() 385 fd.rio.Lock()
444 defer fd.rio.Unlock() 386 defer fd.rio.Unlock()
445 fd.wio.Lock() 387 fd.wio.Lock()
446 defer fd.wio.Unlock() 388 defer fd.wio.Unlock()
447 return nil 389 return nil
448 } 390 }
449 391
450 func (fd *netFD) shutdown(how int) error { 392 func (fd *netFD) shutdown(how int) error {
451 if err := fd.incref(false); err != nil { 393 if err := fd.incref(false); err != nil {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 430
489 func (fd *netFD) Read(buf []byte) (int, error) { 431 func (fd *netFD) Read(buf []byte) (int, error) {
490 if err := fd.incref(false); err != nil { 432 if err := fd.incref(false); err != nil {
491 return 0, err 433 return 0, err
492 } 434 }
493 defer fd.decref() 435 defer fd.decref()
494 fd.rio.Lock() 436 fd.rio.Lock()
495 defer fd.rio.Unlock() 437 defer fd.rio.Unlock()
496 var o readOp 438 var o readOp
497 o.Init(fd, buf, 'r') 439 o.Init(fd, buf, 'r')
498 » n, err := iosrv.ExecIO(&o, fd.rdeadline.value()) 440 » n, err := iosrv.ExecIO(&o)
499 if err == nil && n == 0 { 441 if err == nil && n == 0 {
500 err = io.EOF 442 err = io.EOF
501 } 443 }
502 return n, err 444 return n, err
503 } 445 }
504 446
505 // ReadFrom from network. 447 // ReadFrom from network.
506 448
507 type readFromOp struct { 449 type readFromOp struct {
508 bufOp 450 bufOp
(...skipping 16 matching lines...) Expand all
525 } 467 }
526 if err := fd.incref(false); err != nil { 468 if err := fd.incref(false); err != nil {
527 return 0, nil, err 469 return 0, nil, err
528 } 470 }
529 defer fd.decref() 471 defer fd.decref()
530 fd.rio.Lock() 472 fd.rio.Lock()
531 defer fd.rio.Unlock() 473 defer fd.rio.Unlock()
532 var o readFromOp 474 var o readFromOp
533 o.Init(fd, buf, 'r') 475 o.Init(fd, buf, 'r')
534 o.rsan = int32(unsafe.Sizeof(o.rsa)) 476 o.rsan = int32(unsafe.Sizeof(o.rsa))
535 » n, err = iosrv.ExecIO(&o, fd.rdeadline.value()) 477 » n, err = iosrv.ExecIO(&o)
536 if err != nil { 478 if err != nil {
537 return 0, nil, err 479 return 0, nil, err
538 } 480 }
539 sa, _ = o.rsa.Sockaddr() 481 sa, _ = o.rsa.Sockaddr()
540 return 482 return
541 } 483 }
542 484
543 // Write to network. 485 // Write to network.
544 486
545 type writeOp struct { 487 type writeOp struct {
(...skipping 11 matching lines...) Expand all
557 499
558 func (fd *netFD) Write(buf []byte) (int, error) { 500 func (fd *netFD) Write(buf []byte) (int, error) {
559 if err := fd.incref(false); err != nil { 501 if err := fd.incref(false); err != nil {
560 return 0, err 502 return 0, err
561 } 503 }
562 defer fd.decref() 504 defer fd.decref()
563 fd.wio.Lock() 505 fd.wio.Lock()
564 defer fd.wio.Unlock() 506 defer fd.wio.Unlock()
565 var o writeOp 507 var o writeOp
566 o.Init(fd, buf, 'w') 508 o.Init(fd, buf, 'w')
567 » return iosrv.ExecIO(&o, fd.wdeadline.value()) 509 » return iosrv.ExecIO(&o)
568 } 510 }
569 511
570 // WriteTo to network. 512 // WriteTo to network.
571 513
572 type writeToOp struct { 514 type writeToOp struct {
573 bufOp 515 bufOp
574 sa syscall.Sockaddr 516 sa syscall.Sockaddr
575 } 517 }
576 518
577 func (o *writeToOp) Submit() error { 519 func (o *writeToOp) Submit() error {
(...skipping 11 matching lines...) Expand all
589 } 531 }
590 if err := fd.incref(false); err != nil { 532 if err := fd.incref(false); err != nil {
591 return 0, err 533 return 0, err
592 } 534 }
593 defer fd.decref() 535 defer fd.decref()
594 fd.wio.Lock() 536 fd.wio.Lock()
595 defer fd.wio.Unlock() 537 defer fd.wio.Unlock()
596 var o writeToOp 538 var o writeToOp
597 o.Init(fd, buf, 'w') 539 o.Init(fd, buf, 'w')
598 o.sa = sa 540 o.sa = sa
599 » return iosrv.ExecIO(&o, fd.wdeadline.value()) 541 » return iosrv.ExecIO(&o)
600 } 542 }
601 543
602 // Accept new network connections. 544 // Accept new network connections.
603 545
604 type acceptOp struct { 546 type acceptOp struct {
605 anOp 547 anOp
606 newsock syscall.Handle 548 newsock syscall.Handle
607 attrs [2]syscall.RawSockaddrAny // space for local and remote address only 549 attrs [2]syscall.RawSockaddrAny // space for local and remote address only
608 } 550 }
609 551
(...skipping 14 matching lines...) Expand all
624 } 566 }
625 defer fd.decref() 567 defer fd.decref()
626 568
627 // Get new socket. 569 // Get new socket.
628 s, err := sysSocket(fd.family, fd.sotype, 0) 570 s, err := sysSocket(fd.family, fd.sotype, 0)
629 if err != nil { 571 if err != nil {
630 return nil, &OpError{"socket", fd.net, fd.laddr, err} 572 return nil, &OpError{"socket", fd.net, fd.laddr, err}
631 } 573 }
632 574
633 // Associate our new socket with IOCP. 575 // Associate our new socket with IOCP.
634 » onceStartServer.Do(startServer) 576 » netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
635 » if _, err := syscall.CreateIoCompletionPort(s, resultsrv.iocp, 0, 0); er r != nil { 577 » if err != nil {
636 closesocket(s) 578 closesocket(s)
637 » » return nil, &OpError{"CreateIoCompletionPort", fd.net, fd.laddr, err} 579 » » return nil, &OpError{"accept", fd.net, fd.laddr, err}
638 } 580 }
639 581
640 // Submit accept request. 582 // Submit accept request.
641 var o acceptOp 583 var o acceptOp
642 o.Init(fd, 'r') 584 o.Init(fd, 'r')
643 o.newsock = s 585 o.newsock = s
644 » _, err = iosrv.ExecIO(&o, fd.rdeadline.value()) 586 » _, err = iosrv.ExecIO(&o)
645 if err != nil { 587 if err != nil {
646 closesocket(s) 588 closesocket(s)
647 return nil, err 589 return nil, err
648 } 590 }
649 591
650 // Inherit properties of the listening socket. 592 // Inherit properties of the listening socket.
651 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT _CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))) 593 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT _CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
652 if err != nil { 594 if err != nil {
653 closesocket(s) 595 closesocket(s)
654 return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err} 596 return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
655 } 597 }
656 598
657 // Get local and peer addr out of AcceptEx buffer. 599 // Get local and peer addr out of AcceptEx buffer.
658 var lrsa, rrsa *syscall.RawSockaddrAny 600 var lrsa, rrsa *syscall.RawSockaddrAny
659 var llen, rlen int32 601 var llen, rlen int32
660 l := uint32(unsafe.Sizeof(*lrsa)) 602 l := uint32(unsafe.Sizeof(*lrsa))
661 syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&o.attrs[0])), 603 syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&o.attrs[0])),
662 0, l, l, &lrsa, &llen, &rrsa, &rlen) 604 0, l, l, &lrsa, &llen, &rrsa, &rlen)
663 lsa, _ := lrsa.Sockaddr() 605 lsa, _ := lrsa.Sockaddr()
664 rsa, _ := rrsa.Sockaddr() 606 rsa, _ := rrsa.Sockaddr()
665 607
666 netfd := allocFD(s, fd.family, fd.sotype, fd.net)
667 netfd.setAddr(toAddr(lsa), toAddr(rsa)) 608 netfd.setAddr(toAddr(lsa), toAddr(rsa))
668 return netfd, nil 609 return netfd, nil
669 } 610 }
670 611
671 // Unimplemented functions. 612 // Unimplemented functions.
672 613
673 func (fd *netFD) dup() (*os.File, error) { 614 func (fd *netFD) dup() (*os.File, error) {
674 // TODO: Implement this 615 // TODO: Implement this
675 return nil, os.NewSyscallError("dup", syscall.EWINDOWS) 616 return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
676 } 617 }
677 618
678 var errNoSupport = errors.New("address family not supported") 619 var errNoSupport = errors.New("address family not supported")
679 620
680 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) { 621 func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ockaddr, err error) {
681 return 0, 0, 0, nil, errNoSupport 622 return 0, 0, 0, nil, errNoSupport
682 } 623 }
683 624
684 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) { 625 func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob n int, err error) {
685 return 0, 0, errNoSupport 626 return 0, 0, errNoSupport
686 } 627 }
LEFTRIGHT

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