1
2
3
4
5
6
7
8 package poll
9
10 import (
11 "io"
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
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, newIovecWithBase(&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 if fd.iovecs == nil {
56 fd.iovecs = new([]syscall.Iovec)
57 }
58 *fd.iovecs = iovecs
59
60 var wrote uintptr
61 wrote, err = writev(fd.Sysfd, iovecs)
62 if wrote == ^uintptr(0) {
63 wrote = 0
64 }
65 TestHookDidWritev(int(wrote))
66 n += int64(wrote)
67 consume(v, int64(wrote))
68 for i := range iovecs {
69 iovecs[i] = syscall.Iovec{}
70 }
71 if err != nil {
72 if err == syscall.EINTR {
73 continue
74 }
75 if err == syscall.EAGAIN {
76 if err = fd.pd.waitWrite(fd.isFile); err == nil {
77 continue
78 }
79 }
80 break
81 }
82 if n == 0 {
83 err = io.ErrUnexpectedEOF
84 break
85 }
86 }
87 return n, err
88 }
89
View as plain text