...
Source file src/pkg/internal/poll/fd_plan9.go
1
2
3
4
5 package poll
6
7 import (
8 "errors"
9 "io"
10 "sync/atomic"
11 "time"
12 )
13
14 type atomicBool int32
15
16 func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
17 func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
18 func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
19
20 type FD struct {
21
22 fdmu fdMutex
23
24 Destroy func()
25
26
27 raio *asyncIO
28 waio *asyncIO
29 rtimer *time.Timer
30 wtimer *time.Timer
31 rtimedout atomicBool
32 wtimedout atomicBool
33
34
35
36
37
38 isFile bool
39 }
40
41
42
43
44 func (fd *FD) destroy() error {
45 if fd.Destroy != nil {
46 fd.Destroy()
47 }
48 return nil
49 }
50
51
52
53 func (fd *FD) Close() error {
54 if !fd.fdmu.increfAndClose() {
55 return errClosing(fd.isFile)
56 }
57 return nil
58 }
59
60
61 func (fd *FD) Read(fn func([]byte) (int, error), b []byte) (int, error) {
62 if fd.rtimedout.isSet() {
63 return 0, ErrTimeout
64 }
65 if err := fd.readLock(); err != nil {
66 return 0, err
67 }
68 defer fd.readUnlock()
69 if len(b) == 0 {
70 return 0, nil
71 }
72 fd.raio = newAsyncIO(fn, b)
73 n, err := fd.raio.Wait()
74 fd.raio = nil
75 if isHangup(err) {
76 err = io.EOF
77 }
78 if isInterrupted(err) {
79 err = ErrTimeout
80 }
81 return n, err
82 }
83
84
85 func (fd *FD) Write(fn func([]byte) (int, error), b []byte) (int, error) {
86 if fd.wtimedout.isSet() {
87 return 0, ErrTimeout
88 }
89 if err := fd.writeLock(); err != nil {
90 return 0, err
91 }
92 defer fd.writeUnlock()
93 fd.waio = newAsyncIO(fn, b)
94 n, err := fd.waio.Wait()
95 fd.waio = nil
96 if isInterrupted(err) {
97 err = ErrTimeout
98 }
99 return n, err
100 }
101
102
103 func (fd *FD) SetDeadline(t time.Time) error {
104 return setDeadlineImpl(fd, t, 'r'+'w')
105 }
106
107
108 func (fd *FD) SetReadDeadline(t time.Time) error {
109 return setDeadlineImpl(fd, t, 'r')
110 }
111
112
113 func (fd *FD) SetWriteDeadline(t time.Time) error {
114 return setDeadlineImpl(fd, t, 'w')
115 }
116
117 func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
118 d := t.Sub(time.Now())
119 if mode == 'r' || mode == 'r'+'w' {
120 fd.rtimedout.setFalse()
121 }
122 if mode == 'w' || mode == 'r'+'w' {
123 fd.wtimedout.setFalse()
124 }
125 if t.IsZero() || d < 0 {
126
127 if mode == 'r' || mode == 'r'+'w' {
128 if fd.rtimer != nil {
129 fd.rtimer.Stop()
130 }
131 fd.rtimer = nil
132 }
133 if mode == 'w' || mode == 'r'+'w' {
134 if fd.wtimer != nil {
135 fd.wtimer.Stop()
136 }
137 fd.wtimer = nil
138 }
139 } else {
140
141 if mode == 'r' || mode == 'r'+'w' {
142 fd.rtimer = time.AfterFunc(d, func() {
143 fd.rtimedout.setTrue()
144 if fd.raio != nil {
145 fd.raio.Cancel()
146 }
147 })
148 }
149 if mode == 'w' || mode == 'r'+'w' {
150 fd.wtimer = time.AfterFunc(d, func() {
151 fd.wtimedout.setTrue()
152 if fd.waio != nil {
153 fd.waio.Cancel()
154 }
155 })
156 }
157 }
158 if !t.IsZero() && d < 0 {
159
160 if mode == 'r' || mode == 'r'+'w' {
161 fd.rtimedout.setTrue()
162 if fd.raio != nil {
163 fd.raio.Cancel()
164 }
165 }
166 if mode == 'w' || mode == 'r'+'w' {
167 fd.wtimedout.setTrue()
168 if fd.waio != nil {
169 fd.waio.Cancel()
170 }
171 }
172 }
173 return nil
174 }
175
176
177
178
179 func (fd *FD) ReadLock() error {
180 return fd.readLock()
181 }
182
183
184 func (fd *FD) ReadUnlock() {
185 fd.readUnlock()
186 }
187
188 func isHangup(err error) bool {
189 return err != nil && stringsHasSuffix(err.Error(), "Hangup")
190 }
191
192 func isInterrupted(err error) bool {
193 return err != nil && stringsHasSuffix(err.Error(), "interrupted")
194 }
195
196
197
198 func IsPollDescriptor(fd uintptr) bool {
199 return false
200 }
201
202
203
204 func (fd *FD) RawControl(f func(uintptr)) error {
205 return errors.New("not implemented")
206 }
207
208
209 func (fd *FD) RawRead(f func(uintptr) bool) error {
210 return errors.New("not implemented")
211 }
212
213
214 func (fd *FD) RawWrite(f func(uintptr) bool) error {
215 return errors.New("not implemented")
216 }
217
View as plain text