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