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