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