...
1
2
3
4
5 package ssh
6
7 import (
8 "io"
9 "sync"
10 )
11
12
13
14
15 type buffer struct {
16
17 *sync.Cond
18
19 head *element
20 tail *element
21
22 closed bool
23 }
24
25
26 type element struct {
27 buf []byte
28 next *element
29 }
30
31
32 func newBuffer() *buffer {
33 e := new(element)
34 b := &buffer{
35 Cond: newCond(),
36 head: e,
37 tail: e,
38 }
39 return b
40 }
41
42
43
44 func (b *buffer) write(buf []byte) {
45 b.Cond.L.Lock()
46 e := &element{buf: buf}
47 b.tail.next = e
48 b.tail = e
49 b.Cond.Signal()
50 b.Cond.L.Unlock()
51 }
52
53
54
55 func (b *buffer) eof() {
56 b.Cond.L.Lock()
57 b.closed = true
58 b.Cond.Signal()
59 b.Cond.L.Unlock()
60 }
61
62
63
64 func (b *buffer) Read(buf []byte) (n int, err error) {
65 b.Cond.L.Lock()
66 defer b.Cond.L.Unlock()
67
68 for len(buf) > 0 {
69
70 if len(b.head.buf) > 0 {
71 r := copy(buf, b.head.buf)
72 buf, b.head.buf = buf[r:], b.head.buf[r:]
73 n += r
74 continue
75 }
76
77 if len(b.head.buf) == 0 && b.head != b.tail {
78 b.head = b.head.next
79 continue
80 }
81
82
83 if n > 0 {
84 break
85 }
86
87
88
89 if b.closed {
90 err = io.EOF
91 break
92 }
93
94 b.Cond.Wait()
95 }
96 return
97 }
98
View as plain text