...
1
2
3
4
5
6
7 package poll
8
9 import (
10 "io"
11 "runtime"
12 "syscall"
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 if runtime.GOOS == "aix" || runtime.GOOS == "solaris" {
34
35 maxVec = 16
36 }
37
38 var n int64
39 var err error
40 for len(*v) > 0 {
41 iovecs = iovecs[:0]
42 for _, chunk := range *v {
43 if len(chunk) == 0 {
44 continue
45 }
46 iovecs = append(iovecs, newIovecWithBase(&chunk[0]))
47 if fd.IsStream && len(chunk) > 1<<30 {
48 iovecs[len(iovecs)-1].SetLen(1 << 30)
49 break
50 }
51 iovecs[len(iovecs)-1].SetLen(len(chunk))
52 if len(iovecs) == maxVec {
53 break
54 }
55 }
56 if len(iovecs) == 0 {
57 break
58 }
59 if fd.iovecs == nil {
60 fd.iovecs = new([]syscall.Iovec)
61 }
62 *fd.iovecs = iovecs
63
64 var wrote uintptr
65 wrote, err = writev(fd.Sysfd, iovecs)
66 if wrote == ^uintptr(0) {
67 wrote = 0
68 }
69 TestHookDidWritev(int(wrote))
70 n += int64(wrote)
71 consume(v, int64(wrote))
72 for i := range iovecs {
73 iovecs[i] = syscall.Iovec{}
74 }
75 if err != nil {
76 if err == syscall.EINTR {
77 continue
78 }
79 if err == syscall.EAGAIN {
80 if err = fd.pd.waitWrite(fd.isFile); err == nil {
81 continue
82 }
83 }
84 break
85 }
86 if n == 0 {
87 err = io.ErrUnexpectedEOF
88 break
89 }
90 }
91 return n, err
92 }
93
View as plain text