github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/internal/poll/fd_windows.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package poll 6 7 import ( 8 "errors" 9 "internal/race" 10 "internal/syscall/windows" 11 "io" 12 "runtime" 13 "sync" 14 "syscall" 15 "unicode/utf16" 16 "unicode/utf8" 17 "unsafe" 18 ) 19 20 var ( 21 initErr error 22 ioSync uint64 23 ) 24 25 // CancelIo Windows API cancels all outstanding IO for a particular 26 // socket on current thread. To overcome that limitation, we run 27 // special goroutine, locked to OS single thread, that both starts 28 // and cancels IO. It means, there are 2 unavoidable thread switches 29 // for every IO. 30 // Some newer versions of Windows has new CancelIoEx API, that does 31 // not have that limitation and can be used from any thread. This 32 // package uses CancelIoEx API, if present, otherwise it fallback 33 // to CancelIo. 34 35 var canCancelIO bool // determines if CancelIoEx API is present 36 37 // This package uses SetFileCompletionNotificationModes Windows API 38 // to skip calling GetQueuedCompletionStatus if an IO operation completes 39 // synchronously. Unfortuently SetFileCompletionNotificationModes is not 40 // available on Windows XP. Also there is a known bug where 41 // SetFileCompletionNotificationModes crashes on some systems 42 // (see http://support.microsoft.com/kb/2568167 for details). 43 44 var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use 45 46 // checkSetFileCompletionNotificationModes verifies that 47 // SetFileCompletionNotificationModes Windows API is present 48 // on the system and is safe to use. 49 // See http://support.microsoft.com/kb/2568167 for details. 50 func checkSetFileCompletionNotificationModes() { 51 err := syscall.LoadSetFileCompletionNotificationModes() 52 if err != nil { 53 return 54 } 55 protos := [2]int32{syscall.IPPROTO_TCP, 0} 56 var buf [32]syscall.WSAProtocolInfo 57 len := uint32(unsafe.Sizeof(buf)) 58 n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len) 59 if err != nil { 60 return 61 } 62 for i := int32(0); i < n; i++ { 63 if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 { 64 return 65 } 66 } 67 useSetFileCompletionNotificationModes = true 68 } 69 70 func init() { 71 var d syscall.WSAData 72 e := syscall.WSAStartup(uint32(0x202), &d) 73 if e != nil { 74 initErr = e 75 } 76 canCancelIO = syscall.LoadCancelIoEx() == nil 77 checkSetFileCompletionNotificationModes() 78 } 79 80 // operation contains superset of data necessary to perform all async IO. 81 type operation struct { 82 // Used by IOCP interface, it must be first field 83 // of the struct, as our code rely on it. 84 o syscall.Overlapped 85 86 // fields used by runtime.netpoll 87 runtimeCtx uintptr 88 mode int32 89 errno int32 90 qty uint32 91 92 // fields used only by net package 93 fd *FD 94 errc chan error 95 buf syscall.WSABuf 96 msg windows.WSAMsg 97 sa syscall.Sockaddr 98 rsa *syscall.RawSockaddrAny 99 rsan int32 100 handle syscall.Handle 101 flags uint32 102 bufs []syscall.WSABuf 103 } 104 105 func (o *operation) InitBuf(buf []byte) { 106 o.buf.Len = uint32(len(buf)) 107 o.buf.Buf = nil 108 if len(buf) != 0 { 109 o.buf.Buf = &buf[0] 110 } 111 } 112 113 func (o *operation) InitBufs(buf *[][]byte) { 114 if o.bufs == nil { 115 o.bufs = make([]syscall.WSABuf, 0, len(*buf)) 116 } else { 117 o.bufs = o.bufs[:0] 118 } 119 for _, b := range *buf { 120 var p *byte 121 if len(b) > 0 { 122 p = &b[0] 123 } 124 o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: p}) 125 } 126 } 127 128 // ClearBufs clears all pointers to Buffers parameter captured 129 // by InitBufs, so it can be released by garbage collector. 130 func (o *operation) ClearBufs() { 131 for i := range o.bufs { 132 o.bufs[i].Buf = nil 133 } 134 o.bufs = o.bufs[:0] 135 } 136 137 func (o *operation) InitMsg(p []byte, oob []byte) { 138 o.InitBuf(p) 139 o.msg.Buffers = &o.buf 140 o.msg.BufferCount = 1 141 142 o.msg.Name = nil 143 o.msg.Namelen = 0 144 145 o.msg.Flags = 0 146 o.msg.Control.Len = uint32(len(oob)) 147 o.msg.Control.Buf = nil 148 if len(oob) != 0 { 149 o.msg.Control.Buf = &oob[0] 150 } 151 } 152 153 // ioSrv executes net IO requests. 154 type ioSrv struct { 155 req chan ioSrvReq 156 } 157 158 type ioSrvReq struct { 159 o *operation 160 submit func(o *operation) error // if nil, cancel the operation 161 } 162 163 // ProcessRemoteIO will execute submit IO requests on behalf 164 // of other goroutines, all on a single os thread, so it can 165 // cancel them later. Results of all operations will be sent 166 // back to their requesters via channel supplied in request. 167 // It is used only when the CancelIoEx API is unavailable. 168 func (s *ioSrv) ProcessRemoteIO() { 169 runtime.LockOSThread() 170 defer runtime.UnlockOSThread() 171 for r := range s.req { 172 if r.submit != nil { 173 r.o.errc <- r.submit(r.o) 174 } else { 175 r.o.errc <- syscall.CancelIo(r.o.fd.Sysfd) 176 } 177 } 178 } 179 180 // ExecIO executes a single IO operation o. It submits and cancels 181 // IO in the current thread for systems where Windows CancelIoEx API 182 // is available. Alternatively, it passes the request onto 183 // runtime netpoll and waits for completion or cancels request. 184 func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, error) { 185 if o.fd.pd.runtimeCtx == 0 { 186 return 0, errors.New("internal error: polling on unsupported descriptor type") 187 } 188 189 if !canCancelIO { 190 onceStartServer.Do(startServer) 191 } 192 193 fd := o.fd 194 // Notify runtime netpoll about starting IO. 195 err := fd.pd.prepare(int(o.mode), fd.isFile) 196 if err != nil { 197 return 0, err 198 } 199 // Start IO. 200 if canCancelIO { 201 err = submit(o) 202 } else { 203 // Send request to a special dedicated thread, 204 // so it can stop the IO with CancelIO later. 205 s.req <- ioSrvReq{o, submit} 206 err = <-o.errc 207 } 208 switch err { 209 case nil: 210 // IO completed immediately 211 if o.fd.skipSyncNotif { 212 // No completion message will follow, so return immediately. 213 return int(o.qty), nil 214 } 215 // Need to get our completion message anyway. 216 case syscall.ERROR_IO_PENDING: 217 // IO started, and we have to wait for its completion. 218 err = nil 219 default: 220 return 0, err 221 } 222 // Wait for our request to complete. 223 err = fd.pd.wait(int(o.mode), fd.isFile) 224 if err == nil { 225 // All is good. Extract our IO results and return. 226 if o.errno != 0 { 227 err = syscall.Errno(o.errno) 228 return 0, err 229 } 230 return int(o.qty), nil 231 } 232 // IO is interrupted by "close" or "timeout" 233 netpollErr := err 234 switch netpollErr { 235 case ErrNetClosing, ErrFileClosing, ErrTimeout: 236 // will deal with those. 237 default: 238 panic("unexpected runtime.netpoll error: " + netpollErr.Error()) 239 } 240 // Cancel our request. 241 if canCancelIO { 242 err := syscall.CancelIoEx(fd.Sysfd, &o.o) 243 // Assuming ERROR_NOT_FOUND is returned, if IO is completed. 244 if err != nil && err != syscall.ERROR_NOT_FOUND { 245 // TODO(brainman): maybe do something else, but panic. 246 panic(err) 247 } 248 } else { 249 s.req <- ioSrvReq{o, nil} 250 <-o.errc 251 } 252 // Wait for cancelation to complete. 253 fd.pd.waitCanceled(int(o.mode)) 254 if o.errno != 0 { 255 err = syscall.Errno(o.errno) 256 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 257 err = netpollErr 258 } 259 return 0, err 260 } 261 // We issued a cancelation request. But, it seems, IO operation succeeded 262 // before the cancelation request run. We need to treat the IO operation as 263 // succeeded (the bytes are actually sent/recv from network). 264 return int(o.qty), nil 265 } 266 267 // Start helper goroutines. 268 var rsrv, wsrv ioSrv 269 var onceStartServer sync.Once 270 271 func startServer() { 272 // This is called, once, when only the CancelIo API is available. 273 // Start two special goroutines, both locked to an OS thread, 274 // that start and cancel IO requests. 275 // One will process read requests, while the other will do writes. 276 rsrv.req = make(chan ioSrvReq) 277 go rsrv.ProcessRemoteIO() 278 wsrv.req = make(chan ioSrvReq) 279 go wsrv.ProcessRemoteIO() 280 } 281 282 // FD is a file descriptor. The net and os packages embed this type in 283 // a larger type representing a network connection or OS file. 284 type FD struct { 285 // Lock sysfd and serialize access to Read and Write methods. 286 fdmu fdMutex 287 288 // System file descriptor. Immutable until Close. 289 Sysfd syscall.Handle 290 291 // Read operation. 292 rop operation 293 // Write operation. 294 wop operation 295 296 // I/O poller. 297 pd pollDesc 298 299 // Used to implement pread/pwrite. 300 l sync.Mutex 301 302 // For console I/O. 303 isConsole bool 304 lastbits []byte // first few bytes of the last incomplete rune in last write 305 readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole 306 readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8 307 readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read 308 309 // Semaphore signaled when file is closed. 310 csema uint32 311 312 skipSyncNotif bool 313 314 // Whether this is a streaming descriptor, as opposed to a 315 // packet-based descriptor like a UDP socket. 316 IsStream bool 317 318 // Whether a zero byte read indicates EOF. This is false for a 319 // message based socket connection. 320 ZeroReadIsEOF bool 321 322 // Whether this is a normal file. 323 isFile bool 324 325 // Whether this is a directory. 326 isDir bool 327 } 328 329 // logInitFD is set by tests to enable file descriptor initialization logging. 330 var logInitFD func(net string, fd *FD, err error) 331 332 // Init initializes the FD. The Sysfd field should already be set. 333 // This can be called multiple times on a single FD. 334 // The net argument is a network name from the net package (e.g., "tcp"), 335 // or "file" or "console" or "dir". 336 // Set pollable to true if fd should be managed by runtime netpoll. 337 func (fd *FD) Init(net string, pollable bool) (string, error) { 338 if initErr != nil { 339 return "", initErr 340 } 341 342 switch net { 343 case "file": 344 fd.isFile = true 345 case "console": 346 fd.isConsole = true 347 case "dir": 348 fd.isDir = true 349 case "tcp", "tcp4", "tcp6": 350 case "udp", "udp4", "udp6": 351 case "ip", "ip4", "ip6": 352 case "unix", "unixgram", "unixpacket": 353 default: 354 return "", errors.New("internal error: unknown network type " + net) 355 } 356 357 var err error 358 if pollable { 359 // Only call init for a network socket. 360 // This means that we don't add files to the runtime poller. 361 // Adding files to the runtime poller can confuse matters 362 // if the user is doing their own overlapped I/O. 363 // See issue #21172. 364 // 365 // In general the code below avoids calling the ExecIO 366 // method for non-network sockets. If some method does 367 // somehow call ExecIO, then ExecIO, and therefore the 368 // calling method, will return an error, because 369 // fd.pd.runtimeCtx will be 0. 370 err = fd.pd.init(fd) 371 } 372 if logInitFD != nil { 373 logInitFD(net, fd, err) 374 } 375 if err != nil { 376 return "", err 377 } 378 if pollable && useSetFileCompletionNotificationModes { 379 // We do not use events, so we can skip them always. 380 flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE) 381 // It's not safe to skip completion notifications for UDP: 382 // http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx 383 if net == "tcp" { 384 flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 385 } 386 err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags) 387 if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 { 388 fd.skipSyncNotif = true 389 } 390 } 391 // Disable SIO_UDP_CONNRESET behavior. 392 // http://support.microsoft.com/kb/263823 393 switch net { 394 case "udp", "udp4", "udp6": 395 ret := uint32(0) 396 flag := uint32(0) 397 size := uint32(unsafe.Sizeof(flag)) 398 err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) 399 if err != nil { 400 return "wsaioctl", err 401 } 402 } 403 fd.rop.mode = 'r' 404 fd.wop.mode = 'w' 405 fd.rop.fd = fd 406 fd.wop.fd = fd 407 fd.rop.runtimeCtx = fd.pd.runtimeCtx 408 fd.wop.runtimeCtx = fd.pd.runtimeCtx 409 if !canCancelIO { 410 fd.rop.errc = make(chan error) 411 fd.wop.errc = make(chan error) 412 } 413 return "", nil 414 } 415 416 func (fd *FD) destroy() error { 417 if fd.Sysfd == syscall.InvalidHandle { 418 return syscall.EINVAL 419 } 420 // Poller may want to unregister fd in readiness notification mechanism, 421 // so this must be executed before fd.CloseFunc. 422 fd.pd.close() 423 var err error 424 if fd.isFile || fd.isConsole { 425 err = syscall.CloseHandle(fd.Sysfd) 426 } else if fd.isDir { 427 err = syscall.FindClose(fd.Sysfd) 428 } else { 429 // The net package uses the CloseFunc variable for testing. 430 err = CloseFunc(fd.Sysfd) 431 } 432 fd.Sysfd = syscall.InvalidHandle 433 runtime_Semrelease(&fd.csema) 434 return err 435 } 436 437 // Close closes the FD. The underlying file descriptor is closed by 438 // the destroy method when there are no remaining references. 439 func (fd *FD) Close() error { 440 if !fd.fdmu.increfAndClose() { 441 return errClosing(fd.isFile) 442 } 443 // unblock pending reader and writer 444 fd.pd.evict() 445 err := fd.decref() 446 // Wait until the descriptor is closed. If this was the only 447 // reference, it is already closed. 448 runtime_Semacquire(&fd.csema) 449 return err 450 } 451 452 // Shutdown wraps the shutdown network call. 453 func (fd *FD) Shutdown(how int) error { 454 if err := fd.incref(); err != nil { 455 return err 456 } 457 defer fd.decref() 458 return syscall.Shutdown(fd.Sysfd, how) 459 } 460 461 // Read implements io.Reader. 462 func (fd *FD) Read(buf []byte) (int, error) { 463 if err := fd.readLock(); err != nil { 464 return 0, err 465 } 466 defer fd.readUnlock() 467 468 var n int 469 var err error 470 if fd.isFile || fd.isDir || fd.isConsole { 471 fd.l.Lock() 472 defer fd.l.Unlock() 473 if fd.isConsole { 474 n, err = fd.readConsole(buf) 475 } else { 476 n, err = syscall.Read(fd.Sysfd, buf) 477 } 478 if err != nil { 479 n = 0 480 } 481 } else { 482 o := &fd.rop 483 o.InitBuf(buf) 484 n, err = rsrv.ExecIO(o, func(o *operation) error { 485 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) 486 }) 487 if race.Enabled { 488 race.Acquire(unsafe.Pointer(&ioSync)) 489 } 490 } 491 if len(buf) != 0 { 492 err = fd.eofError(n, err) 493 } 494 return n, err 495 } 496 497 var ReadConsole = syscall.ReadConsole // changed for testing 498 499 // readConsole reads utf16 characters from console File, 500 // encodes them into utf8 and stores them in buffer b. 501 // It returns the number of utf8 bytes read and an error, if any. 502 func (fd *FD) readConsole(b []byte) (int, error) { 503 if len(b) == 0 { 504 return 0, nil 505 } 506 507 if fd.readuint16 == nil { 508 // Note: syscall.ReadConsole fails for very large buffers. 509 // The limit is somewhere around (but not exactly) 16384. 510 // Stay well below. 511 fd.readuint16 = make([]uint16, 0, 10000) 512 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16)) 513 } 514 515 for fd.readbyteOffset >= len(fd.readbyte) { 516 n := cap(fd.readuint16) - len(fd.readuint16) 517 if n > len(b) { 518 n = len(b) 519 } 520 var nw uint32 521 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil) 522 if err != nil { 523 return 0, err 524 } 525 uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)] 526 fd.readuint16 = fd.readuint16[:0] 527 buf := fd.readbyte[:0] 528 for i := 0; i < len(uint16s); i++ { 529 r := rune(uint16s[i]) 530 if utf16.IsSurrogate(r) { 531 if i+1 == len(uint16s) { 532 if nw > 0 { 533 // Save half surrogate pair for next time. 534 fd.readuint16 = fd.readuint16[:1] 535 fd.readuint16[0] = uint16(r) 536 break 537 } 538 r = utf8.RuneError 539 } else { 540 r = utf16.DecodeRune(r, rune(uint16s[i+1])) 541 if r != utf8.RuneError { 542 i++ 543 } 544 } 545 } 546 n := utf8.EncodeRune(buf[len(buf):cap(buf)], r) 547 buf = buf[:len(buf)+n] 548 } 549 fd.readbyte = buf 550 fd.readbyteOffset = 0 551 if nw == 0 { 552 break 553 } 554 } 555 556 src := fd.readbyte[fd.readbyteOffset:] 557 var i int 558 for i = 0; i < len(src) && i < len(b); i++ { 559 x := src[i] 560 if x == 0x1A { // Ctrl-Z 561 if i == 0 { 562 fd.readbyteOffset++ 563 } 564 break 565 } 566 b[i] = x 567 } 568 fd.readbyteOffset += i 569 return i, nil 570 } 571 572 // Pread emulates the Unix pread system call. 573 func (fd *FD) Pread(b []byte, off int64) (int, error) { 574 // Call incref, not readLock, because since pread specifies the 575 // offset it is independent from other reads. 576 if err := fd.incref(); err != nil { 577 return 0, err 578 } 579 defer fd.decref() 580 581 fd.l.Lock() 582 defer fd.l.Unlock() 583 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 584 if e != nil { 585 return 0, e 586 } 587 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 588 o := syscall.Overlapped{ 589 OffsetHigh: uint32(off >> 32), 590 Offset: uint32(off), 591 } 592 var done uint32 593 e = syscall.ReadFile(fd.Sysfd, b, &done, &o) 594 if e != nil { 595 done = 0 596 if e == syscall.ERROR_HANDLE_EOF { 597 e = io.EOF 598 } 599 } 600 if len(b) != 0 { 601 e = fd.eofError(int(done), e) 602 } 603 return int(done), e 604 } 605 606 // ReadFrom wraps the recvfrom network call. 607 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { 608 if len(buf) == 0 { 609 return 0, nil, nil 610 } 611 if err := fd.readLock(); err != nil { 612 return 0, nil, err 613 } 614 defer fd.readUnlock() 615 o := &fd.rop 616 o.InitBuf(buf) 617 n, err := rsrv.ExecIO(o, func(o *operation) error { 618 if o.rsa == nil { 619 o.rsa = new(syscall.RawSockaddrAny) 620 } 621 o.rsan = int32(unsafe.Sizeof(*o.rsa)) 622 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) 623 }) 624 err = fd.eofError(n, err) 625 if err != nil { 626 return n, nil, err 627 } 628 sa, _ := o.rsa.Sockaddr() 629 return n, sa, nil 630 } 631 632 // Write implements io.Writer. 633 func (fd *FD) Write(buf []byte) (int, error) { 634 if err := fd.writeLock(); err != nil { 635 return 0, err 636 } 637 defer fd.writeUnlock() 638 639 var n int 640 var err error 641 if fd.isFile || fd.isDir || fd.isConsole { 642 fd.l.Lock() 643 defer fd.l.Unlock() 644 if fd.isConsole { 645 n, err = fd.writeConsole(buf) 646 } else { 647 n, err = syscall.Write(fd.Sysfd, buf) 648 } 649 if err != nil { 650 n = 0 651 } 652 } else { 653 if race.Enabled { 654 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 655 } 656 o := &fd.wop 657 o.InitBuf(buf) 658 n, err = wsrv.ExecIO(o, func(o *operation) error { 659 return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) 660 }) 661 } 662 return n, err 663 } 664 665 // writeConsole writes len(b) bytes to the console File. 666 // It returns the number of bytes written and an error, if any. 667 func (fd *FD) writeConsole(b []byte) (int, error) { 668 n := len(b) 669 runes := make([]rune, 0, 256) 670 if len(fd.lastbits) > 0 { 671 b = append(fd.lastbits, b...) 672 fd.lastbits = nil 673 674 } 675 for len(b) >= utf8.UTFMax || utf8.FullRune(b) { 676 r, l := utf8.DecodeRune(b) 677 runes = append(runes, r) 678 b = b[l:] 679 } 680 if len(b) > 0 { 681 fd.lastbits = make([]byte, len(b)) 682 copy(fd.lastbits, b) 683 } 684 // syscall.WriteConsole seems to fail, if given large buffer. 685 // So limit the buffer to 16000 characters. This number was 686 // discovered by experimenting with syscall.WriteConsole. 687 const maxWrite = 16000 688 for len(runes) > 0 { 689 m := len(runes) 690 if m > maxWrite { 691 m = maxWrite 692 } 693 chunk := runes[:m] 694 runes = runes[m:] 695 uint16s := utf16.Encode(chunk) 696 for len(uint16s) > 0 { 697 var written uint32 698 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil) 699 if err != nil { 700 return 0, err 701 } 702 uint16s = uint16s[written:] 703 } 704 } 705 return n, nil 706 } 707 708 // Pwrite emulates the Unix pwrite system call. 709 func (fd *FD) Pwrite(b []byte, off int64) (int, error) { 710 // Call incref, not writeLock, because since pwrite specifies the 711 // offset it is independent from other writes. 712 if err := fd.incref(); err != nil { 713 return 0, err 714 } 715 defer fd.decref() 716 717 fd.l.Lock() 718 defer fd.l.Unlock() 719 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 720 if e != nil { 721 return 0, e 722 } 723 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 724 o := syscall.Overlapped{ 725 OffsetHigh: uint32(off >> 32), 726 Offset: uint32(off), 727 } 728 var done uint32 729 e = syscall.WriteFile(fd.Sysfd, b, &done, &o) 730 if e != nil { 731 return 0, e 732 } 733 return int(done), nil 734 } 735 736 // Writev emulates the Unix writev system call. 737 func (fd *FD) Writev(buf *[][]byte) (int64, error) { 738 if len(*buf) == 0 { 739 return 0, nil 740 } 741 if err := fd.writeLock(); err != nil { 742 return 0, err 743 } 744 defer fd.writeUnlock() 745 if race.Enabled { 746 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 747 } 748 o := &fd.wop 749 o.InitBufs(buf) 750 n, err := wsrv.ExecIO(o, func(o *operation) error { 751 return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) 752 }) 753 o.ClearBufs() 754 TestHookDidWritev(n) 755 consume(buf, int64(n)) 756 return int64(n), err 757 } 758 759 // WriteTo wraps the sendto network call. 760 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { 761 if len(buf) == 0 { 762 return 0, nil 763 } 764 if err := fd.writeLock(); err != nil { 765 return 0, err 766 } 767 defer fd.writeUnlock() 768 o := &fd.wop 769 o.InitBuf(buf) 770 o.sa = sa 771 n, err := wsrv.ExecIO(o, func(o *operation) error { 772 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) 773 }) 774 return n, err 775 } 776 777 // Call ConnectEx. This doesn't need any locking, since it is only 778 // called when the descriptor is first created. This is here rather 779 // than in the net package so that it can use fd.wop. 780 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { 781 o := &fd.wop 782 o.sa = ra 783 _, err := wsrv.ExecIO(o, func(o *operation) error { 784 return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) 785 }) 786 return err 787 } 788 789 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { 790 // Submit accept request. 791 o.handle = s 792 o.rsan = int32(unsafe.Sizeof(rawsa[0])) 793 _, err := rsrv.ExecIO(o, func(o *operation) error { 794 return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) 795 }) 796 if err != nil { 797 CloseFunc(s) 798 return "acceptex", err 799 } 800 801 // Inherit properties of the listening socket. 802 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd))) 803 if err != nil { 804 CloseFunc(s) 805 return "setsockopt", err 806 } 807 808 return "", nil 809 } 810 811 // Accept handles accepting a socket. The sysSocket parameter is used 812 // to allocate the net socket. 813 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) { 814 if err := fd.readLock(); err != nil { 815 return syscall.InvalidHandle, nil, 0, "", err 816 } 817 defer fd.readUnlock() 818 819 o := &fd.rop 820 var rawsa [2]syscall.RawSockaddrAny 821 for { 822 s, err := sysSocket() 823 if err != nil { 824 return syscall.InvalidHandle, nil, 0, "", err 825 } 826 827 errcall, err := fd.acceptOne(s, rawsa[:], o) 828 if err == nil { 829 return s, rawsa[:], uint32(o.rsan), "", nil 830 } 831 832 // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is 833 // returned here. These happen if connection reset is received 834 // before AcceptEx could complete. These errors relate to new 835 // connection, not to AcceptEx, so ignore broken connection and 836 // try AcceptEx again for more connections. 837 errno, ok := err.(syscall.Errno) 838 if !ok { 839 return syscall.InvalidHandle, nil, 0, errcall, err 840 } 841 switch errno { 842 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET: 843 // ignore these and try again 844 default: 845 return syscall.InvalidHandle, nil, 0, errcall, err 846 } 847 } 848 } 849 850 // Seek wraps syscall.Seek. 851 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 852 if err := fd.incref(); err != nil { 853 return 0, err 854 } 855 defer fd.decref() 856 857 fd.l.Lock() 858 defer fd.l.Unlock() 859 860 return syscall.Seek(fd.Sysfd, offset, whence) 861 } 862 863 // FindNextFile wraps syscall.FindNextFile. 864 func (fd *FD) FindNextFile(data *syscall.Win32finddata) error { 865 if err := fd.incref(); err != nil { 866 return err 867 } 868 defer fd.decref() 869 return syscall.FindNextFile(fd.Sysfd, data) 870 } 871 872 // Fchdir wraps syscall.Fchdir. 873 func (fd *FD) Fchdir() error { 874 if err := fd.incref(); err != nil { 875 return err 876 } 877 defer fd.decref() 878 return syscall.Fchdir(fd.Sysfd) 879 } 880 881 // GetFileType wraps syscall.GetFileType. 882 func (fd *FD) GetFileType() (uint32, error) { 883 if err := fd.incref(); err != nil { 884 return 0, err 885 } 886 defer fd.decref() 887 return syscall.GetFileType(fd.Sysfd) 888 } 889 890 // GetFileInformationByHandle wraps GetFileInformationByHandle. 891 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error { 892 if err := fd.incref(); err != nil { 893 return err 894 } 895 defer fd.decref() 896 return syscall.GetFileInformationByHandle(fd.Sysfd, data) 897 } 898 899 // RawControl invokes the user-defined function f for a non-IO 900 // operation. 901 func (fd *FD) RawControl(f func(uintptr)) error { 902 if err := fd.incref(); err != nil { 903 return err 904 } 905 defer fd.decref() 906 f(uintptr(fd.Sysfd)) 907 return nil 908 } 909 910 // RawRead invokes the user-defined function f for a read operation. 911 func (fd *FD) RawRead(f func(uintptr) bool) error { 912 return errors.New("not implemented") 913 } 914 915 // RawWrite invokes the user-defined function f for a write operation. 916 func (fd *FD) RawWrite(f func(uintptr) bool) error { 917 return errors.New("not implemented") 918 } 919 920 func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) { 921 switch sa := sa.(type) { 922 case *syscall.SockaddrInet4: 923 var raw syscall.RawSockaddrInet4 924 raw.Family = syscall.AF_INET 925 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 926 p[0] = byte(sa.Port >> 8) 927 p[1] = byte(sa.Port) 928 for i := 0; i < len(sa.Addr); i++ { 929 raw.Addr[i] = sa.Addr[i] 930 } 931 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 932 case *syscall.SockaddrInet6: 933 var raw syscall.RawSockaddrInet6 934 raw.Family = syscall.AF_INET6 935 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 936 p[0] = byte(sa.Port >> 8) 937 p[1] = byte(sa.Port) 938 raw.Scope_id = sa.ZoneId 939 for i := 0; i < len(sa.Addr); i++ { 940 raw.Addr[i] = sa.Addr[i] 941 } 942 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 943 default: 944 return nil, 0, syscall.EWINDOWS 945 } 946 } 947 948 // ReadMsg wraps the WSARecvMsg network call. 949 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 950 if err := fd.readLock(); err != nil { 951 return 0, 0, 0, nil, err 952 } 953 defer fd.readUnlock() 954 955 o := &fd.rop 956 o.InitMsg(p, oob) 957 o.rsa = new(syscall.RawSockaddrAny) 958 o.msg.Name = o.rsa 959 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) 960 n, err := rsrv.ExecIO(o, func(o *operation) error { 961 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) 962 }) 963 err = fd.eofError(n, err) 964 var sa syscall.Sockaddr 965 if err == nil { 966 sa, err = o.rsa.Sockaddr() 967 } 968 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err 969 } 970 971 // WriteMsg wraps the WSASendMsg network call. 972 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 973 if err := fd.writeLock(); err != nil { 974 return 0, 0, err 975 } 976 defer fd.writeUnlock() 977 978 o := &fd.wop 979 o.InitMsg(p, oob) 980 if sa != nil { 981 rsa, len, err := sockaddrToRaw(sa) 982 if err != nil { 983 return 0, 0, err 984 } 985 o.msg.Name = (*syscall.RawSockaddrAny)(rsa) 986 o.msg.Namelen = len 987 } 988 n, err := wsrv.ExecIO(o, func(o *operation) error { 989 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 990 }) 991 return n, int(o.msg.Control.Len), err 992 }