...
1
2
3
4
5
6
7 package poll
8
9 import (
10 "io"
11 "syscall"
12 "unsafe"
13 )
14
15
16 func (fd *FD) Writev(v *[][]byte) (int64, error) {
17 if err := fd.writeLock(); err != nil {
18 return 0, err
19 }
20 defer fd.writeUnlock()
21 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
22 return 0, err
23 }
24
25 var iovecs []syscall.Iovec
26 if fd.iovecs != nil {
27 iovecs = *fd.iovecs
28 }
29
30
31
32 maxVec := 1024
33
34 var n int64
35 var err error
36 for len(*v) > 0 {
37 iovecs = iovecs[:0]
38 for _, chunk := range *v {
39 if len(chunk) == 0 {
40 continue
41 }
42 iovecs = append(iovecs, syscall.Iovec{Base: &chunk[0]})
43 if fd.IsStream && len(chunk) > 1<<30 {
44 iovecs[len(iovecs)-1].SetLen(1 << 30)
45 break
46 }
47 iovecs[len(iovecs)-1].SetLen(len(chunk))
48 if len(iovecs) == maxVec {
49 break
50 }
51 }
52 if len(iovecs) == 0 {
53 break
54 }
55 fd.iovecs = &iovecs
56
57 wrote, _, e0 := syscall.Syscall(syscall.SYS_WRITEV,
58 uintptr(fd.Sysfd),
59 uintptr(unsafe.Pointer(&iovecs[0])),
60 uintptr(len(iovecs)))
61 if wrote == ^uintptr(0) {
62 wrote = 0
63 }
64 TestHookDidWritev(int(wrote))
65 n += int64(wrote)
66 consume(v, int64(wrote))
67 if e0 == syscall.EAGAIN {
68 if err = fd.pd.waitWrite(fd.isFile); err == nil {
69 continue
70 }
71 } else if e0 != 0 {
72 err = syscall.Errno(e0)
73 }
74 if err != nil {
75 break
76 }
77 if n == 0 {
78 err = io.ErrUnexpectedEOF
79 break
80 }
81 }
82 return n, err
83 }
84
View as plain text