github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/internal/socket/rawconn_mmsg.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  // +build linux
     6  
     7  package socket
     8  
     9  import (
    10  	"net"
    11  	"os"
    12  	"syscall"
    13  )
    14  
    15  func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
    16  	hs := make(mmsghdrs, len(ms))
    17  	var parseFn func([]byte, string) (net.Addr, error)
    18  	if c.network != "tcp" {
    19  		parseFn = parseInetAddr
    20  	}
    21  	if err := hs.pack(ms, parseFn, nil); err != nil {
    22  		return 0, err
    23  	}
    24  	var operr error
    25  	var n int
    26  	fn := func(s uintptr) bool {
    27  		n, operr = recvmmsg(s, hs, flags)
    28  		if operr == syscall.EAGAIN {
    29  			return false
    30  		}
    31  		return true
    32  	}
    33  	if err := c.c.Read(fn); err != nil {
    34  		return n, err
    35  	}
    36  	if operr != nil {
    37  		return n, os.NewSyscallError("recvmmsg", operr)
    38  	}
    39  	if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
    40  		return n, err
    41  	}
    42  	return n, nil
    43  }
    44  
    45  func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
    46  	hs := make(mmsghdrs, len(ms))
    47  	var marshalFn func(net.Addr) []byte
    48  	if c.network != "tcp" {
    49  		marshalFn = marshalInetAddr
    50  	}
    51  	if err := hs.pack(ms, nil, marshalFn); err != nil {
    52  		return 0, err
    53  	}
    54  	var operr error
    55  	var n int
    56  	fn := func(s uintptr) bool {
    57  		n, operr = sendmmsg(s, hs, flags)
    58  		if operr == syscall.EAGAIN {
    59  			return false
    60  		}
    61  		return true
    62  	}
    63  	if err := c.c.Write(fn); err != nil {
    64  		return n, err
    65  	}
    66  	if operr != nil {
    67  		return n, os.NewSyscallError("sendmmsg", operr)
    68  	}
    69  	if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
    70  		return n, err
    71  	}
    72  	return n, nil
    73  }