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 clear(iovecs)
73 if err != nil {
74 if err == syscall.EINTR {
75 continue
76 }
77 if err == syscall.EAGAIN {
78 if err = fd.pd.waitWrite(fd.isFile); err == nil {
79 continue
80 }
81 }
82 break
83 }
84 if n == 0 {
85 err = io.ErrUnexpectedEOF
86 break
87 }
88 }
89 return n, err
90 }
91
View as plain text