libgo: Update to Go 1.3.3 release.
[gcc.git] / libgo / go / net / fd_windows.go
1 // Copyright 2010 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 net
6
7 import (
8 "errors"
9 "io"
10 "os"
11 "runtime"
12 "sync"
13 "syscall"
14 "time"
15 "unsafe"
16 )
17
18 var (
19 initErr error
20 ioSync uint64
21 )
22
23 // CancelIo Windows API cancels all outstanding IO for a particular
24 // socket on current thread. To overcome that limitation, we run
25 // special goroutine, locked to OS single thread, that both starts
26 // and cancels IO. It means, there are 2 unavoidable thread switches
27 // for every IO.
28 // Some newer versions of Windows has new CancelIoEx API, that does
29 // not have that limitation and can be used from any thread. This
30 // package uses CancelIoEx API, if present, otherwise it fallback
31 // to CancelIo.
32
33 var (
34 canCancelIO bool // determines if CancelIoEx API is present
35 skipSyncNotif bool
36 hasLoadSetFileCompletionNotificationModes bool
37 )
38
39 func sysInit() {
40 var d syscall.WSAData
41 e := syscall.WSAStartup(uint32(0x202), &d)
42 if e != nil {
43 initErr = os.NewSyscallError("WSAStartup", e)
44 }
45 canCancelIO = syscall.LoadCancelIoEx() == nil
46 if syscall.LoadGetAddrInfo() == nil {
47 lookupPort = newLookupPort
48 lookupIP = newLookupIP
49 }
50
51 hasLoadSetFileCompletionNotificationModes = syscall.LoadSetFileCompletionNotificationModes() == nil
52 if hasLoadSetFileCompletionNotificationModes {
53 // It's not safe to use FILE_SKIP_COMPLETION_PORT_ON_SUCCESS if non IFS providers are installed:
54 // http://support.microsoft.com/kb/2568167
55 skipSyncNotif = true
56 protos := [2]int32{syscall.IPPROTO_TCP, 0}
57 var buf [32]syscall.WSAProtocolInfo
58 len := uint32(unsafe.Sizeof(buf))
59 n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
60 if err != nil {
61 skipSyncNotif = false
62 } else {
63 for i := int32(0); i < n; i++ {
64 if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
65 skipSyncNotif = false
66 break
67 }
68 }
69 }
70 }
71 }
72
73 func closesocket(s syscall.Handle) error {
74 return syscall.Closesocket(s)
75 }
76
77 func canUseConnectEx(net string) bool {
78 switch net {
79 case "udp", "udp4", "udp6", "ip", "ip4", "ip6":
80 // ConnectEx windows API does not support connectionless sockets.
81 return false
82 }
83 return syscall.LoadConnectEx() == nil
84 }
85
86 func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
87 if !canUseConnectEx(net) {
88 // Use the relatively inefficient goroutine-racing
89 // implementation of DialTimeout.
90 return dialChannel(net, ra, dialer, deadline)
91 }
92 return dialer(deadline)
93 }
94
95 // operation contains superset of data necessary to perform all async IO.
96 type operation struct {
97 // Used by IOCP interface, it must be first field
98 // of the struct, as our code rely on it.
99 o syscall.Overlapped
100
101 // fields used by runtime.netpoll
102 runtimeCtx uintptr
103 mode int32
104 errno int32
105 qty uint32
106
107 // fields used only by net package
108 fd *netFD
109 errc chan error
110 buf syscall.WSABuf
111 sa syscall.Sockaddr
112 rsa *syscall.RawSockaddrAny
113 rsan int32
114 handle syscall.Handle
115 flags uint32
116 }
117
118 func (o *operation) InitBuf(buf []byte) {
119 o.buf.Len = uint32(len(buf))
120 o.buf.Buf = nil
121 if len(buf) != 0 {
122 o.buf.Buf = &buf[0]
123 }
124 }
125
126 // ioSrv executes net IO requests.
127 type ioSrv struct {
128 req chan ioSrvReq
129 }
130
131 type ioSrvReq struct {
132 o *operation
133 submit func(o *operation) error // if nil, cancel the operation
134 }
135
136 // ProcessRemoteIO will execute submit IO requests on behalf
137 // of other goroutines, all on a single os thread, so it can
138 // cancel them later. Results of all operations will be sent
139 // back to their requesters via channel supplied in request.
140 // It is used only when the CancelIoEx API is unavailable.
141 func (s *ioSrv) ProcessRemoteIO() {
142 runtime.LockOSThread()
143 defer runtime.UnlockOSThread()
144 for r := range s.req {
145 if r.submit != nil {
146 r.o.errc <- r.submit(r.o)
147 } else {
148 r.o.errc <- syscall.CancelIo(r.o.fd.sysfd)
149 }
150 }
151 }
152
153 // ExecIO executes a single IO operation o. It submits and cancels
154 // IO in the current thread for systems where Windows CancelIoEx API
155 // is available. Alternatively, it passes the request onto
156 // runtime netpoll and waits for completion or cancels request.
157 func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) error) (int, error) {
158 fd := o.fd
159 // Notify runtime netpoll about starting IO.
160 err := fd.pd.Prepare(int(o.mode))
161 if err != nil {
162 return 0, &OpError{name, fd.net, fd.laddr, err}
163 }
164 // Start IO.
165 if canCancelIO {
166 err = submit(o)
167 } else {
168 // Send request to a special dedicated thread,
169 // so it can stop the IO with CancelIO later.
170 s.req <- ioSrvReq{o, submit}
171 err = <-o.errc
172 }
173 switch err {
174 case nil:
175 // IO completed immediately
176 if o.fd.skipSyncNotif {
177 // No completion message will follow, so return immediately.
178 return int(o.qty), nil
179 }
180 // Need to get our completion message anyway.
181 case syscall.ERROR_IO_PENDING:
182 // IO started, and we have to wait for its completion.
183 err = nil
184 default:
185 return 0, &OpError{name, fd.net, fd.laddr, err}
186 }
187 // Wait for our request to complete.
188 err = fd.pd.Wait(int(o.mode))
189 if err == nil {
190 // All is good. Extract our IO results and return.
191 if o.errno != 0 {
192 err = syscall.Errno(o.errno)
193 return 0, &OpError{name, fd.net, fd.laddr, err}
194 }
195 return int(o.qty), nil
196 }
197 // IO is interrupted by "close" or "timeout"
198 netpollErr := err
199 switch netpollErr {
200 case errClosing, errTimeout:
201 // will deal with those.
202 default:
203 panic("net: unexpected runtime.netpoll error: " + netpollErr.Error())
204 }
205 // Cancel our request.
206 if canCancelIO {
207 err := syscall.CancelIoEx(fd.sysfd, &o.o)
208 // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
209 if err != nil && err != syscall.ERROR_NOT_FOUND {
210 // TODO(brainman): maybe do something else, but panic.
211 panic(err)
212 }
213 } else {
214 s.req <- ioSrvReq{o, nil}
215 <-o.errc
216 }
217 // Wait for cancellation to complete.
218 fd.pd.WaitCanceled(int(o.mode))
219 if o.errno != 0 {
220 err = syscall.Errno(o.errno)
221 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
222 err = netpollErr
223 }
224 return 0, &OpError{name, fd.net, 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
230 }
231
232 // Start helper goroutines.
233 var rsrv, wsrv *ioSrv
234 var onceStartServer sync.Once
235
236 func startServer() {
237 rsrv = new(ioSrv)
238 wsrv = new(ioSrv)
239 if !canCancelIO {
240 // Only CancelIo API is available. Lets start two special goroutines
241 // locked to an OS thread, that both starts and cancels IO. One will
242 // process read requests, while other will do writes.
243 rsrv.req = make(chan ioSrvReq)
244 go rsrv.ProcessRemoteIO()
245 wsrv.req = make(chan ioSrvReq)
246 go wsrv.ProcessRemoteIO()
247 }
248 }
249
250 // Network file descriptor.
251 type netFD struct {
252 // locking/lifetime of sysfd + serialize access to Read and Write methods
253 fdmu fdMutex
254
255 // immutable until Close
256 sysfd syscall.Handle
257 family int
258 sotype int
259 isConnected bool
260 skipSyncNotif bool
261 net string
262 laddr Addr
263 raddr Addr
264
265 rop operation // read operation
266 wop operation // write operation
267
268 // wait server
269 pd pollDesc
270 }
271
272 func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
273 if initErr != nil {
274 return nil, initErr
275 }
276 onceStartServer.Do(startServer)
277 return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
278 }
279
280 func (fd *netFD) init() error {
281 if err := fd.pd.Init(fd); err != nil {
282 return err
283 }
284 if hasLoadSetFileCompletionNotificationModes {
285 // We do not use events, so we can skip them always.
286 flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
287 // It's not safe to skip completion notifications for UDP:
288 // http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx
289 if skipSyncNotif && fd.net == "tcp" {
290 flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
291 }
292 err := syscall.SetFileCompletionNotificationModes(fd.sysfd, flags)
293 if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
294 fd.skipSyncNotif = true
295 }
296 }
297 fd.rop.mode = 'r'
298 fd.wop.mode = 'w'
299 fd.rop.fd = fd
300 fd.wop.fd = fd
301 fd.rop.runtimeCtx = fd.pd.runtimeCtx
302 fd.wop.runtimeCtx = fd.pd.runtimeCtx
303 if !canCancelIO {
304 fd.rop.errc = make(chan error)
305 fd.wop.errc = make(chan error)
306 }
307 return nil
308 }
309
310 func (fd *netFD) setAddr(laddr, raddr Addr) {
311 fd.laddr = laddr
312 fd.raddr = raddr
313 runtime.SetFinalizer(fd, (*netFD).Close)
314 }
315
316 func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
317 // Do not need to call fd.writeLock here,
318 // because fd is not yet accessible to user,
319 // so no concurrent operations are possible.
320 if err := fd.init(); err != nil {
321 return err
322 }
323 if !deadline.IsZero() {
324 fd.setWriteDeadline(deadline)
325 defer fd.setWriteDeadline(noDeadline)
326 }
327 if !canUseConnectEx(fd.net) {
328 return syscall.Connect(fd.sysfd, ra)
329 }
330 // ConnectEx windows API requires an unconnected, previously bound socket.
331 if la == nil {
332 switch ra.(type) {
333 case *syscall.SockaddrInet4:
334 la = &syscall.SockaddrInet4{}
335 case *syscall.SockaddrInet6:
336 la = &syscall.SockaddrInet6{}
337 default:
338 panic("unexpected type in connect")
339 }
340 if err := syscall.Bind(fd.sysfd, la); err != nil {
341 return err
342 }
343 }
344 // Call ConnectEx API.
345 o := &fd.wop
346 o.sa = ra
347 _, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
348 return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
349 })
350 if err != nil {
351 return err
352 }
353 // Refresh socket properties.
354 return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
355 }
356
357 func (fd *netFD) destroy() {
358 if fd.sysfd == syscall.InvalidHandle {
359 return
360 }
361 // Poller may want to unregister fd in readiness notification mechanism,
362 // so this must be executed before closesocket.
363 fd.pd.Close()
364 closesocket(fd.sysfd)
365 fd.sysfd = syscall.InvalidHandle
366 // no need for a finalizer anymore
367 runtime.SetFinalizer(fd, nil)
368 }
369
370 // Add a reference to this fd.
371 // Returns an error if the fd cannot be used.
372 func (fd *netFD) incref() error {
373 if !fd.fdmu.Incref() {
374 return errClosing
375 }
376 return nil
377 }
378
379 // Remove a reference to this FD and close if we've been asked to do so
380 // (and there are no references left).
381 func (fd *netFD) decref() {
382 if fd.fdmu.Decref() {
383 fd.destroy()
384 }
385 }
386
387 // Add a reference to this fd and lock for reading.
388 // Returns an error if the fd cannot be used.
389 func (fd *netFD) readLock() error {
390 if !fd.fdmu.RWLock(true) {
391 return errClosing
392 }
393 return nil
394 }
395
396 // Unlock for reading and remove a reference to this FD.
397 func (fd *netFD) readUnlock() {
398 if fd.fdmu.RWUnlock(true) {
399 fd.destroy()
400 }
401 }
402
403 // Add a reference to this fd and lock for writing.
404 // Returns an error if the fd cannot be used.
405 func (fd *netFD) writeLock() error {
406 if !fd.fdmu.RWLock(false) {
407 return errClosing
408 }
409 return nil
410 }
411
412 // Unlock for writing and remove a reference to this FD.
413 func (fd *netFD) writeUnlock() {
414 if fd.fdmu.RWUnlock(false) {
415 fd.destroy()
416 }
417 }
418
419 func (fd *netFD) Close() error {
420 if !fd.fdmu.IncrefAndClose() {
421 return errClosing
422 }
423 // unblock pending reader and writer
424 fd.pd.Evict()
425 fd.decref()
426 return nil
427 }
428
429 func (fd *netFD) shutdown(how int) error {
430 if err := fd.incref(); err != nil {
431 return err
432 }
433 defer fd.decref()
434 err := syscall.Shutdown(fd.sysfd, how)
435 if err != nil {
436 return &OpError{"shutdown", fd.net, fd.laddr, err}
437 }
438 return nil
439 }
440
441 func (fd *netFD) closeRead() error {
442 return fd.shutdown(syscall.SHUT_RD)
443 }
444
445 func (fd *netFD) closeWrite() error {
446 return fd.shutdown(syscall.SHUT_WR)
447 }
448
449 func (fd *netFD) Read(buf []byte) (int, error) {
450 if err := fd.readLock(); err != nil {
451 return 0, err
452 }
453 defer fd.readUnlock()
454 o := &fd.rop
455 o.InitBuf(buf)
456 n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
457 return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
458 })
459 if err == nil && n == 0 {
460 err = io.EOF
461 }
462 if raceenabled {
463 raceAcquire(unsafe.Pointer(&ioSync))
464 }
465 return n, err
466 }
467
468 func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
469 if len(buf) == 0 {
470 return 0, nil, nil
471 }
472 if err := fd.readLock(); err != nil {
473 return 0, nil, err
474 }
475 defer fd.readUnlock()
476 o := &fd.rop
477 o.InitBuf(buf)
478 n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
479 if o.rsa == nil {
480 o.rsa = new(syscall.RawSockaddrAny)
481 }
482 o.rsan = int32(unsafe.Sizeof(*o.rsa))
483 return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
484 })
485 if err != nil {
486 return 0, nil, err
487 }
488 sa, _ = o.rsa.Sockaddr()
489 return
490 }
491
492 func (fd *netFD) Write(buf []byte) (int, error) {
493 if err := fd.writeLock(); err != nil {
494 return 0, err
495 }
496 defer fd.writeUnlock()
497 if raceenabled {
498 raceReleaseMerge(unsafe.Pointer(&ioSync))
499 }
500 o := &fd.wop
501 o.InitBuf(buf)
502 return wsrv.ExecIO(o, "WSASend", func(o *operation) error {
503 return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
504 })
505 }
506
507 func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
508 if len(buf) == 0 {
509 return 0, nil
510 }
511 if err := fd.writeLock(); err != nil {
512 return 0, err
513 }
514 defer fd.writeUnlock()
515 o := &fd.wop
516 o.InitBuf(buf)
517 o.sa = sa
518 return wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
519 return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
520 })
521 }
522
523 func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
524 // Get new socket.
525 s, err := sysSocket(fd.family, fd.sotype, 0)
526 if err != nil {
527 return nil, &OpError{"socket", fd.net, fd.laddr, err}
528 }
529
530 // Associate our new socket with IOCP.
531 netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
532 if err != nil {
533 closesocket(s)
534 return nil, &OpError{"accept", fd.net, fd.laddr, err}
535 }
536 if err := netfd.init(); err != nil {
537 fd.Close()
538 return nil, err
539 }
540
541 // Submit accept request.
542 o.handle = s
543 o.rsan = int32(unsafe.Sizeof(rawsa[0]))
544 _, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
545 return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
546 })
547 if err != nil {
548 netfd.Close()
549 return nil, err
550 }
551
552 // Inherit properties of the listening socket.
553 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
554 if err != nil {
555 netfd.Close()
556 return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
557 }
558
559 return netfd, nil
560 }
561
562 func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
563 if err := fd.readLock(); err != nil {
564 return nil, err
565 }
566 defer fd.readUnlock()
567
568 o := &fd.rop
569 var netfd *netFD
570 var err error
571 var rawsa [2]syscall.RawSockaddrAny
572 for {
573 netfd, err = fd.acceptOne(toAddr, rawsa[:], o)
574 if err == nil {
575 break
576 }
577 // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
578 // returned here. These happen if connection reset is received
579 // before AcceptEx could complete. These errors relate to new
580 // connection, not to AcceptEx, so ignore broken connection and
581 // try AcceptEx again for more connections.
582 operr, ok := err.(*OpError)
583 if !ok {
584 return nil, err
585 }
586 errno, ok := operr.Err.(syscall.Errno)
587 if !ok {
588 return nil, err
589 }
590 switch errno {
591 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
592 // ignore these and try again
593 default:
594 return nil, err
595 }
596 }
597
598 // Get local and peer addr out of AcceptEx buffer.
599 var lrsa, rrsa *syscall.RawSockaddrAny
600 var llen, rlen int32
601 syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
602 0, uint32(o.rsan), uint32(o.rsan), &lrsa, &llen, &rrsa, &rlen)
603 lsa, _ := lrsa.Sockaddr()
604 rsa, _ := rrsa.Sockaddr()
605
606 netfd.setAddr(toAddr(lsa), toAddr(rsa))
607 return netfd, nil
608 }
609
610 func skipRawSocketTests() (skip bool, skipmsg string, err error) {
611 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
612 // Note: To use a socket of type SOCK_RAW requires administrative privileges.
613 // Users running Winsock applications that use raw sockets must be a member of
614 // the Administrators group on the local computer, otherwise raw socket calls
615 // will fail with an error code of WSAEACCES. On Windows Vista and later, access
616 // for raw sockets is enforced at socket creation. In earlier versions of Windows,
617 // access for raw sockets is enforced during other socket operations.
618 s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
619 if err == syscall.WSAEACCES {
620 return true, "skipping test; no access to raw socket allowed", nil
621 }
622 if err != nil {
623 return true, "", err
624 }
625 defer syscall.Closesocket(s)
626 return false, "", nil
627 }
628
629 // Unimplemented functions.
630
631 func (fd *netFD) dup() (*os.File, error) {
632 // TODO: Implement this
633 return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
634 }
635
636 var errNoSupport = errors.New("address family not supported")
637
638 func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
639 return 0, 0, 0, nil, errNoSupport
640 }
641
642 func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
643 return 0, 0, errNoSupport
644 }