github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/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 // More data available. Return back the size of received data. 229 if err == syscall.ERROR_MORE_DATA || err == syscall.WSAEMSGSIZE { 230 return int(o.qty), err 231 } 232 return 0, err 233 } 234 return int(o.qty), nil 235 } 236 // IO is interrupted by "close" or "timeout" 237 netpollErr := err 238 switch netpollErr { 239 case ErrNetClosing, ErrFileClosing, ErrTimeout: 240 // will deal with those. 241 default: 242 panic("unexpected runtime.netpoll error: " + netpollErr.Error()) 243 } 244 // Cancel our request. 245 if canCancelIO { 246 err := syscall.CancelIoEx(fd.Sysfd, &o.o) 247 // Assuming ERROR_NOT_FOUND is returned, if IO is completed. 248 if err != nil && err != syscall.ERROR_NOT_FOUND { 249 // TODO(brainman): maybe do something else, but panic. 250 panic(err) 251 } 252 } else { 253 s.req <- ioSrvReq{o, nil} 254 <-o.errc 255 } 256 // Wait for cancelation to complete. 257 fd.pd.waitCanceled(int(o.mode)) 258 if o.errno != 0 { 259 err = syscall.Errno(o.errno) 260 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 261 err = netpollErr 262 } 263 return 0, err 264 } 265 // We issued a cancelation request. But, it seems, IO operation succeeded 266 // before the cancelation request run. We need to treat the IO operation as 267 // succeeded (the bytes are actually sent/recv from network). 268 return int(o.qty), nil 269 } 270 271 // Start helper goroutines. 272 var rsrv, wsrv ioSrv 273 var onceStartServer sync.Once 274 275 func startServer() { 276 // This is called, once, when only the CancelIo API is available. 277 // Start two special goroutines, both locked to an OS thread, 278 // that start and cancel IO requests. 279 // One will process read requests, while the other will do writes. 280 rsrv.req = make(chan ioSrvReq) 281 go rsrv.ProcessRemoteIO() 282 wsrv.req = make(chan ioSrvReq) 283 go wsrv.ProcessRemoteIO() 284 } 285 286 // FD is a file descriptor. The net and os packages embed this type in 287 // a larger type representing a network connection or OS file. 288 type FD struct { 289 // Lock sysfd and serialize access to Read and Write methods. 290 fdmu fdMutex 291 292 // System file descriptor. Immutable until Close. 293 Sysfd syscall.Handle 294 295 // Read operation. 296 rop operation 297 // Write operation. 298 wop operation 299 300 // I/O poller. 301 pd pollDesc 302 303 // Used to implement pread/pwrite. 304 l sync.Mutex 305 306 // For console I/O. 307 isConsole bool 308 lastbits []byte // first few bytes of the last incomplete rune in last write 309 readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole 310 readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8 311 readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read 312 313 // Semaphore signaled when file is closed. 314 csema uint32 315 316 skipSyncNotif bool 317 318 // Whether this is a streaming descriptor, as opposed to a 319 // packet-based descriptor like a UDP socket. 320 IsStream bool 321 322 // Whether a zero byte read indicates EOF. This is false for a 323 // message based socket connection. 324 ZeroReadIsEOF bool 325 326 // Whether this is a normal file. 327 isFile bool 328 329 // Whether this is a directory. 330 isDir bool 331 } 332 333 // logInitFD is set by tests to enable file descriptor initialization logging. 334 var logInitFD func(net string, fd *FD, err error) 335 336 // Init initializes the FD. The Sysfd field should already be set. 337 // This can be called multiple times on a single FD. 338 // The net argument is a network name from the net package (e.g., "tcp"), 339 // or "file" or "console" or "dir". 340 // Set pollable to true if fd should be managed by runtime netpoll. 341 func (fd *FD) Init(net string, pollable bool) (string, error) { 342 if initErr != nil { 343 return "", initErr 344 } 345 346 switch net { 347 case "file": 348 fd.isFile = true 349 case "console": 350 fd.isConsole = true 351 case "dir": 352 fd.isDir = true 353 case "tcp", "tcp4", "tcp6": 354 case "udp", "udp4", "udp6": 355 case "ip", "ip4", "ip6": 356 case "unix", "unixgram", "unixpacket": 357 default: 358 return "", errors.New("internal error: unknown network type " + net) 359 } 360 361 var err error 362 if pollable { 363 // Only call init for a network socket. 364 // This means that we don't add files to the runtime poller. 365 // Adding files to the runtime poller can confuse matters 366 // if the user is doing their own overlapped I/O. 367 // See issue #21172. 368 // 369 // In general the code below avoids calling the ExecIO 370 // method for non-network sockets. If some method does 371 // somehow call ExecIO, then ExecIO, and therefore the 372 // calling method, will return an error, because 373 // fd.pd.runtimeCtx will be 0. 374 err = fd.pd.init(fd) 375 } 376 if logInitFD != nil { 377 logInitFD(net, fd, err) 378 } 379 if err != nil { 380 return "", err 381 } 382 if pollable && useSetFileCompletionNotificationModes { 383 // We do not use events, so we can skip them always. 384 flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE) 385 // It's not safe to skip completion notifications for UDP: 386 // http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx 387 if net == "tcp" { 388 flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 389 } 390 err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags) 391 if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 { 392 fd.skipSyncNotif = true 393 } 394 } 395 // Disable SIO_UDP_CONNRESET behavior. 396 // http://support.microsoft.com/kb/263823 397 switch net { 398 case "udp", "udp4", "udp6": 399 ret := uint32(0) 400 flag := uint32(0) 401 size := uint32(unsafe.Sizeof(flag)) 402 err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) 403 if err != nil { 404 return "wsaioctl", err 405 } 406 } 407 fd.rop.mode = 'r' 408 fd.wop.mode = 'w' 409 fd.rop.fd = fd 410 fd.wop.fd = fd 411 fd.rop.runtimeCtx = fd.pd.runtimeCtx 412 fd.wop.runtimeCtx = fd.pd.runtimeCtx 413 if !canCancelIO { 414 fd.rop.errc = make(chan error) 415 fd.wop.errc = make(chan error) 416 } 417 return "", nil 418 } 419 420 func (fd *FD) destroy() error { 421 if fd.Sysfd == syscall.InvalidHandle { 422 return syscall.EINVAL 423 } 424 // Poller may want to unregister fd in readiness notification mechanism, 425 // so this must be executed before fd.CloseFunc. 426 fd.pd.close() 427 var err error 428 if fd.isFile || fd.isConsole { 429 err = syscall.CloseHandle(fd.Sysfd) 430 } else if fd.isDir { 431 err = syscall.FindClose(fd.Sysfd) 432 } else { 433 // The net package uses the CloseFunc variable for testing. 434 err = CloseFunc(fd.Sysfd) 435 } 436 fd.Sysfd = syscall.InvalidHandle 437 runtime_Semrelease(&fd.csema) 438 return err 439 } 440 441 // Close closes the FD. The underlying file descriptor is closed by 442 // the destroy method when there are no remaining references. 443 func (fd *FD) Close() error { 444 if !fd.fdmu.increfAndClose() { 445 return errClosing(fd.isFile) 446 } 447 // unblock pending reader and writer 448 fd.pd.evict() 449 err := fd.decref() 450 // Wait until the descriptor is closed. If this was the only 451 // reference, it is already closed. 452 runtime_Semacquire(&fd.csema) 453 return err 454 } 455 456 // Shutdown wraps the shutdown network call. 457 func (fd *FD) Shutdown(how int) error { 458 if err := fd.incref(); err != nil { 459 return err 460 } 461 defer fd.decref() 462 return syscall.Shutdown(fd.Sysfd, how) 463 } 464 465 // Read implements io.Reader. 466 func (fd *FD) Read(buf []byte) (int, error) { 467 if err := fd.readLock(); err != nil { 468 return 0, err 469 } 470 defer fd.readUnlock() 471 472 var n int 473 var err error 474 if fd.isFile || fd.isDir || fd.isConsole { 475 fd.l.Lock() 476 defer fd.l.Unlock() 477 if fd.isConsole { 478 n, err = fd.readConsole(buf) 479 } else { 480 n, err = syscall.Read(fd.Sysfd, buf) 481 } 482 if err != nil { 483 n = 0 484 } 485 } else { 486 o := &fd.rop 487 o.InitBuf(buf) 488 n, err = rsrv.ExecIO(o, func(o *operation) error { 489 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) 490 }) 491 if race.Enabled { 492 race.Acquire(unsafe.Pointer(&ioSync)) 493 } 494 } 495 if len(buf) != 0 { 496 err = fd.eofError(n, err) 497 } 498 return n, err 499 } 500 501 var ReadConsole = syscall.ReadConsole // changed for testing 502 503 // readConsole reads utf16 characters from console File, 504 // encodes them into utf8 and stores them in buffer b. 505 // It returns the number of utf8 bytes read and an error, if any. 506 func (fd *FD) readConsole(b []byte) (int, error) { 507 if len(b) == 0 { 508 return 0, nil 509 } 510 511 if fd.readuint16 == nil { 512 // Note: syscall.ReadConsole fails for very large buffers. 513 // The limit is somewhere around (but not exactly) 16384. 514 // Stay well below. 515 fd.readuint16 = make([]uint16, 0, 10000) 516 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16)) 517 } 518 519 for fd.readbyteOffset >= len(fd.readbyte) { 520 n := cap(fd.readuint16) - len(fd.readuint16) 521 if n > len(b) { 522 n = len(b) 523 } 524 var nw uint32 525 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil) 526 if err != nil { 527 return 0, err 528 } 529 uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)] 530 fd.readuint16 = fd.readuint16[:0] 531 buf := fd.readbyte[:0] 532 for i := 0; i < len(uint16s); i++ { 533 r := rune(uint16s[i]) 534 if utf16.IsSurrogate(r) { 535 if i+1 == len(uint16s) { 536 if nw > 0 { 537 // Save half surrogate pair for next time. 538 fd.readuint16 = fd.readuint16[:1] 539 fd.readuint16[0] = uint16(r) 540 break 541 } 542 r = utf8.RuneError 543 } else { 544 r = utf16.DecodeRune(r, rune(uint16s[i+1])) 545 if r != utf8.RuneError { 546 i++ 547 } 548 } 549 } 550 n := utf8.EncodeRune(buf[len(buf):cap(buf)], r) 551 buf = buf[:len(buf)+n] 552 } 553 fd.readbyte = buf 554 fd.readbyteOffset = 0 555 if nw == 0 { 556 break 557 } 558 } 559 560 src := fd.readbyte[fd.readbyteOffset:] 561 var i int 562 for i = 0; i < len(src) && i < len(b); i++ { 563 x := src[i] 564 if x == 0x1A { // Ctrl-Z 565 if i == 0 { 566 fd.readbyteOffset++ 567 } 568 break 569 } 570 b[i] = x 571 } 572 fd.readbyteOffset += i 573 return i, nil 574 } 575 576 // Pread emulates the Unix pread system call. 577 func (fd *FD) Pread(b []byte, off int64) (int, error) { 578 // Call incref, not readLock, because since pread specifies the 579 // offset it is independent from other reads. 580 if err := fd.incref(); err != nil { 581 return 0, err 582 } 583 defer fd.decref() 584 585 fd.l.Lock() 586 defer fd.l.Unlock() 587 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 588 if e != nil { 589 return 0, e 590 } 591 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 592 o := syscall.Overlapped{ 593 OffsetHigh: uint32(off >> 32), 594 Offset: uint32(off), 595 } 596 var done uint32 597 e = syscall.ReadFile(fd.Sysfd, b, &done, &o) 598 if e != nil { 599 done = 0 600 if e == syscall.ERROR_HANDLE_EOF { 601 e = io.EOF 602 } 603 } 604 if len(b) != 0 { 605 e = fd.eofError(int(done), e) 606 } 607 return int(done), e 608 } 609 610 // ReadFrom wraps the recvfrom network call. 611 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { 612 if len(buf) == 0 { 613 return 0, nil, nil 614 } 615 if err := fd.readLock(); err != nil { 616 return 0, nil, err 617 } 618 defer fd.readUnlock() 619 o := &fd.rop 620 o.InitBuf(buf) 621 n, err := rsrv.ExecIO(o, func(o *operation) error { 622 if o.rsa == nil { 623 o.rsa = new(syscall.RawSockaddrAny) 624 } 625 o.rsan = int32(unsafe.Sizeof(*o.rsa)) 626 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) 627 }) 628 err = fd.eofError(n, err) 629 if err != nil { 630 return n, nil, err 631 } 632 sa, _ := o.rsa.Sockaddr() 633 return n, sa, nil 634 } 635 636 // Write implements io.Writer. 637 func (fd *FD) Write(buf []byte) (int, error) { 638 if err := fd.writeLock(); err != nil { 639 return 0, err 640 } 641 defer fd.writeUnlock() 642 643 var n int 644 var err error 645 if fd.isFile || fd.isDir || fd.isConsole { 646 fd.l.Lock() 647 defer fd.l.Unlock() 648 if fd.isConsole { 649 n, err = fd.writeConsole(buf) 650 } else { 651 n, err = syscall.Write(fd.Sysfd, buf) 652 } 653 if err != nil { 654 n = 0 655 } 656 } else { 657 if race.Enabled { 658 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 659 } 660 o := &fd.wop 661 o.InitBuf(buf) 662 n, err = wsrv.ExecIO(o, func(o *operation) error { 663 return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) 664 }) 665 } 666 return n, err 667 } 668 669 // writeConsole writes len(b) bytes to the console File. 670 // It returns the number of bytes written and an error, if any. 671 func (fd *FD) writeConsole(b []byte) (int, error) { 672 n := len(b) 673 runes := make([]rune, 0, 256) 674 if len(fd.lastbits) > 0 { 675 b = append(fd.lastbits, b...) 676 fd.lastbits = nil 677 678 } 679 for len(b) >= utf8.UTFMax || utf8.FullRune(b) { 680 r, l := utf8.DecodeRune(b) 681 runes = append(runes, r) 682 b = b[l:] 683 } 684 if len(b) > 0 { 685 fd.lastbits = make([]byte, len(b)) 686 copy(fd.lastbits, b) 687 } 688 // syscall.WriteConsole seems to fail, if given large buffer. 689 // So limit the buffer to 16000 characters. This number was 690 // discovered by experimenting with syscall.WriteConsole. 691 const maxWrite = 16000 692 for len(runes) > 0 { 693 m := len(runes) 694 if m > maxWrite { 695 m = maxWrite 696 } 697 chunk := runes[:m] 698 runes = runes[m:] 699 uint16s := utf16.Encode(chunk) 700 for len(uint16s) > 0 { 701 var written uint32 702 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil) 703 if err != nil { 704 return 0, err 705 } 706 uint16s = uint16s[written:] 707 } 708 } 709 return n, nil 710 } 711 712 // Pwrite emulates the Unix pwrite system call. 713 func (fd *FD) Pwrite(b []byte, off int64) (int, error) { 714 // Call incref, not writeLock, because since pwrite specifies the 715 // offset it is independent from other writes. 716 if err := fd.incref(); err != nil { 717 return 0, err 718 } 719 defer fd.decref() 720 721 fd.l.Lock() 722 defer fd.l.Unlock() 723 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 724 if e != nil { 725 return 0, e 726 } 727 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 728 o := syscall.Overlapped{ 729 OffsetHigh: uint32(off >> 32), 730 Offset: uint32(off), 731 } 732 var done uint32 733 e = syscall.WriteFile(fd.Sysfd, b, &done, &o) 734 if e != nil { 735 return 0, e 736 } 737 return int(done), nil 738 } 739 740 // Writev emulates the Unix writev system call. 741 func (fd *FD) Writev(buf *[][]byte) (int64, error) { 742 if len(*buf) == 0 { 743 return 0, nil 744 } 745 if err := fd.writeLock(); err != nil { 746 return 0, err 747 } 748 defer fd.writeUnlock() 749 if race.Enabled { 750 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 751 } 752 o := &fd.wop 753 o.InitBufs(buf) 754 n, err := wsrv.ExecIO(o, func(o *operation) error { 755 return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) 756 }) 757 o.ClearBufs() 758 TestHookDidWritev(n) 759 consume(buf, int64(n)) 760 return int64(n), err 761 } 762 763 // WriteTo wraps the sendto network call. 764 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { 765 if len(buf) == 0 { 766 return 0, nil 767 } 768 if err := fd.writeLock(); err != nil { 769 return 0, err 770 } 771 defer fd.writeUnlock() 772 o := &fd.wop 773 o.InitBuf(buf) 774 o.sa = sa 775 n, err := wsrv.ExecIO(o, func(o *operation) error { 776 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) 777 }) 778 return n, err 779 } 780 781 // Call ConnectEx. This doesn't need any locking, since it is only 782 // called when the descriptor is first created. This is here rather 783 // than in the net package so that it can use fd.wop. 784 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { 785 o := &fd.wop 786 o.sa = ra 787 _, err := wsrv.ExecIO(o, func(o *operation) error { 788 return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) 789 }) 790 return err 791 } 792 793 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { 794 // Submit accept request. 795 o.handle = s 796 o.rsan = int32(unsafe.Sizeof(rawsa[0])) 797 _, err := rsrv.ExecIO(o, func(o *operation) error { 798 return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) 799 }) 800 if err != nil { 801 CloseFunc(s) 802 return "acceptex", err 803 } 804 805 // Inherit properties of the listening socket. 806 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd))) 807 if err != nil { 808 CloseFunc(s) 809 return "setsockopt", err 810 } 811 812 return "", nil 813 } 814 815 // Accept handles accepting a socket. The sysSocket parameter is used 816 // to allocate the net socket. 817 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) { 818 if err := fd.readLock(); err != nil { 819 return syscall.InvalidHandle, nil, 0, "", err 820 } 821 defer fd.readUnlock() 822 823 o := &fd.rop 824 var rawsa [2]syscall.RawSockaddrAny 825 for { 826 s, err := sysSocket() 827 if err != nil { 828 return syscall.InvalidHandle, nil, 0, "", err 829 } 830 831 errcall, err := fd.acceptOne(s, rawsa[:], o) 832 if err == nil { 833 return s, rawsa[:], uint32(o.rsan), "", nil 834 } 835 836 // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is 837 // returned here. These happen if connection reset is received 838 // before AcceptEx could complete. These errors relate to new 839 // connection, not to AcceptEx, so ignore broken connection and 840 // try AcceptEx again for more connections. 841 errno, ok := err.(syscall.Errno) 842 if !ok { 843 return syscall.InvalidHandle, nil, 0, errcall, err 844 } 845 switch errno { 846 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET: 847 // ignore these and try again 848 default: 849 return syscall.InvalidHandle, nil, 0, errcall, err 850 } 851 } 852 } 853 854 // Seek wraps syscall.Seek. 855 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 856 if err := fd.incref(); err != nil { 857 return 0, err 858 } 859 defer fd.decref() 860 861 fd.l.Lock() 862 defer fd.l.Unlock() 863 864 return syscall.Seek(fd.Sysfd, offset, whence) 865 } 866 867 // FindNextFile wraps syscall.FindNextFile. 868 func (fd *FD) FindNextFile(data *syscall.Win32finddata) error { 869 if err := fd.incref(); err != nil { 870 return err 871 } 872 defer fd.decref() 873 return syscall.FindNextFile(fd.Sysfd, data) 874 } 875 876 // Fchdir wraps syscall.Fchdir. 877 func (fd *FD) Fchdir() error { 878 if err := fd.incref(); err != nil { 879 return err 880 } 881 defer fd.decref() 882 return syscall.Fchdir(fd.Sysfd) 883 } 884 885 // GetFileType wraps syscall.GetFileType. 886 func (fd *FD) GetFileType() (uint32, error) { 887 if err := fd.incref(); err != nil { 888 return 0, err 889 } 890 defer fd.decref() 891 return syscall.GetFileType(fd.Sysfd) 892 } 893 894 // GetFileInformationByHandle wraps GetFileInformationByHandle. 895 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error { 896 if err := fd.incref(); err != nil { 897 return err 898 } 899 defer fd.decref() 900 return syscall.GetFileInformationByHandle(fd.Sysfd, data) 901 } 902 903 // RawControl invokes the user-defined function f for a non-IO 904 // operation. 905 func (fd *FD) RawControl(f func(uintptr)) error { 906 if err := fd.incref(); err != nil { 907 return err 908 } 909 defer fd.decref() 910 f(uintptr(fd.Sysfd)) 911 return nil 912 } 913 914 // RawRead invokes the user-defined function f for a read operation. 915 func (fd *FD) RawRead(f func(uintptr) bool) error { 916 return errors.New("not implemented") 917 } 918 919 // RawWrite invokes the user-defined function f for a write operation. 920 func (fd *FD) RawWrite(f func(uintptr) bool) error { 921 return errors.New("not implemented") 922 } 923 924 func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) { 925 switch sa := sa.(type) { 926 case *syscall.SockaddrInet4: 927 var raw syscall.RawSockaddrInet4 928 raw.Family = syscall.AF_INET 929 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 930 p[0] = byte(sa.Port >> 8) 931 p[1] = byte(sa.Port) 932 for i := 0; i < len(sa.Addr); i++ { 933 raw.Addr[i] = sa.Addr[i] 934 } 935 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 936 case *syscall.SockaddrInet6: 937 var raw syscall.RawSockaddrInet6 938 raw.Family = syscall.AF_INET6 939 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 940 p[0] = byte(sa.Port >> 8) 941 p[1] = byte(sa.Port) 942 raw.Scope_id = sa.ZoneId 943 for i := 0; i < len(sa.Addr); i++ { 944 raw.Addr[i] = sa.Addr[i] 945 } 946 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 947 default: 948 return nil, 0, syscall.EWINDOWS 949 } 950 } 951 952 // ReadMsg wraps the WSARecvMsg network call. 953 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 954 if err := fd.readLock(); err != nil { 955 return 0, 0, 0, nil, err 956 } 957 defer fd.readUnlock() 958 959 o := &fd.rop 960 o.InitMsg(p, oob) 961 o.rsa = new(syscall.RawSockaddrAny) 962 o.msg.Name = o.rsa 963 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) 964 n, err := rsrv.ExecIO(o, func(o *operation) error { 965 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) 966 }) 967 err = fd.eofError(n, err) 968 var sa syscall.Sockaddr 969 if err == nil { 970 sa, err = o.rsa.Sockaddr() 971 } 972 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err 973 } 974 975 // WriteMsg wraps the WSASendMsg network call. 976 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 977 if err := fd.writeLock(); err != nil { 978 return 0, 0, err 979 } 980 defer fd.writeUnlock() 981 982 o := &fd.wop 983 o.InitMsg(p, oob) 984 if sa != nil { 985 rsa, len, err := sockaddrToRaw(sa) 986 if err != nil { 987 return 0, 0, err 988 } 989 o.msg.Name = (*syscall.RawSockaddrAny)(rsa) 990 o.msg.Namelen = len 991 } 992 n, err := wsrv.ExecIO(o, func(o *operation) error { 993 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 994 }) 995 return n, int(o.msg.Control.Len), err 996 }