func timeoutIO() { // CancelIO only cancels all pending input and output (I/O) operations that are // issued by the calling thread for the specified file, does not cancel I/O // operations that other threads issue for a file handle. So we need do all timeout // I/O in single OS thread. runtime.LockOSThread() defer runtime.UnlockOSThread() for { o := <-ioChan var e int switch o.f { case read: e = syscall.WSARecv(uint32(o.fd.sysfd), o.pckt.w, 1, o.done, o.flags, &o.pckt.o, nil) case readfrom: e = syscall.WSARecvFrom(uint32(o.fd.sysfd), o.pckt.w, 1, o.done, o.flags, o.rsa, o.size, &o.pckt.o, nil) case write: e = syscall.WSASend(uint32(o.fd.sysfd), o.pckt.w, 1, o.done, uint32(0), &o.pckt.o, nil) case writeto: e = syscall.WSASendto(uint32(o.fd.sysfd), o.pckt.w, 1, o.done, 0, *o.sa, &o.pckt.o, nil) case cancel: _, e = syscall.CancelIo(uint32(o.fd.sysfd)) } o.c <- e } }
func (s *Ssdp) read() ([]byte, string, error) { bufs := syscall.WSABuf{ Len: 2048, Buf: &s.socket.readBytes[0], } var n, flags uint32 var asIp4 syscall.RawSockaddrInet4 fromAny := (*syscall.RawSockaddrAny)(unsafe.Pointer(&asIp4)) fromSize := int32(unsafe.Sizeof(asIp4)) err := syscall.WSARecvFrom(s.socket.socket, &bufs, 1, &n, &flags, fromAny, &fromSize, nil, nil) if err != nil { return nil, "", err } if n > 0 { // need to convert the port bytes ordering portBytes := make([]byte, 6) binary.BigEndian.PutUint16(portBytes, asIp4.Port) port := binary.LittleEndian.Uint16(portBytes) // set the address src := fmt.Sprintf("%d.%d.%d.%d:%d", asIp4.Addr[0], asIp4.Addr[1], asIp4.Addr[2], asIp4.Addr[3], port) //s.logger.Infof("Message: %s", string(readBytes[0:n])) return s.socket.readBytes[0:n], src, nil } return nil, "", nil }
func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) { if len(buf) == 0 { return 0, nil, nil } if err := fd.readLock(); err != nil { return 0, nil, err } defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) n, err := rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } o.rsan = int32(unsafe.Sizeof(*o.rsa)) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) }) err = fd.eofError(n, err) if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("wsarecvfrom", err) } if err != nil { return n, nil, err } sa, _ := o.rsa.Sockaddr() return n, sa, nil }
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) { if fd == nil { return 0, nil, os.EINVAL } if len(p) == 0 { return 0, nil, nil } fd.rio.Lock() defer fd.rio.Unlock() fd.incref() defer fd.decref() if fd.sysfd == -1 { return 0, nil, os.EINVAL } // Submit receive request. var pckt ioPacket pckt.c = fd.cr pckt.w = newWSABuf(p) var done uint32 flags := uint32(0) var rsa syscall.RawSockaddrAny l := int32(unsafe.Sizeof(rsa)) var e int if fd.rdeadline_delta > 0 { a := &arg{f: readfrom, fd: fd, pckt: &pckt, done: &done, flags: &flags, rsa: &rsa, size: &l, c: make(chan int)} ioChan <- a e = <-a.c } else { e = syscall.WSARecvFrom(uint32(fd.sysfd), pckt.w, 1, &done, &flags, &rsa, &l, &pckt.o, nil) } switch e { case 0: // IO completed immediately, but we need to get our completion message anyway. case syscall.ERROR_IO_PENDING: // IO started, and we have to wait for it's completion. default: return 0, nil, &OpError{"WSARecvFrom", fd.net, fd.laddr, os.Errno(e)} } // Wait for our request to complete. r := waitPacket(fd, &pckt, 'r') if r.errno != 0 { err = &OpError{"WSARecvFrom", fd.net, fd.laddr, os.Errno(r.errno)} } n = int(r.qty) sa, _ = rsa.Sockaddr() return }
func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { if len(buf) == 0 { return 0, nil, nil } if err := fd.readLock(); err != nil { return 0, nil, err } defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } o.rsan = int32(unsafe.Sizeof(*o.rsa)) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) }) if err != nil { return 0, nil, err } sa, _ = o.rsa.Sockaddr() return }
func (o *readFromOp) Submit() error { var d, f uint32 return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &o.rsan, &o.o, nil) }
func (o *readFromOp) Submit() (errno int) { var d, f uint32 l := int32(unsafe.Sizeof(o.rsa)) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &l, &o.o, nil) }