1
2
3
4
5
6
7 package poll
8
9 import (
10 "io"
11 "runtime"
12 "syscall"
13 )
14
15
16
17 type FD struct {
18
19 fdmu fdMutex
20
21
22 Sysfd int
23
24
25 pd pollDesc
26
27
28 iovecs *[]syscall.Iovec
29
30
31 csema uint32
32
33
34
35 IsStream bool
36
37
38
39 ZeroReadIsEOF bool
40
41
42 isFile bool
43
44
45 isBlocking bool
46 }
47
48
49
50
51
52
53 func (fd *FD) Init(net string, pollable bool) error {
54
55 if net == "file" {
56 fd.isFile = true
57 }
58 if !pollable {
59 fd.isBlocking = true
60 return nil
61 }
62 return fd.pd.init(fd)
63 }
64
65
66
67 func (fd *FD) destroy() error {
68
69
70 fd.pd.close()
71 err := CloseFunc(fd.Sysfd)
72 fd.Sysfd = -1
73 runtime_Semrelease(&fd.csema)
74 return err
75 }
76
77
78
79 func (fd *FD) Close() error {
80 if !fd.fdmu.increfAndClose() {
81 return errClosing(fd.isFile)
82 }
83
84
85
86
87
88
89 fd.pd.evict()
90
91
92
93 err := fd.decref()
94
95
96
97
98
99 if !fd.isBlocking {
100 runtime_Semacquire(&fd.csema)
101 }
102
103 return err
104 }
105
106
107 func (fd *FD) Shutdown(how int) error {
108 if err := fd.incref(); err != nil {
109 return err
110 }
111 defer fd.decref()
112 return syscall.Shutdown(fd.Sysfd, how)
113 }
114
115
116 func (fd *FD) SetBlocking() error {
117 if err := fd.incref(); err != nil {
118 return err
119 }
120 defer fd.decref()
121 fd.isBlocking = true
122 return syscall.SetNonblock(fd.Sysfd, false)
123 }
124
125
126
127
128
129
130 const maxRW = 1 << 30
131
132
133 func (fd *FD) Read(p []byte) (int, error) {
134 if err := fd.readLock(); err != nil {
135 return 0, err
136 }
137 defer fd.readUnlock()
138 if len(p) == 0 {
139
140
141
142
143
144 return 0, nil
145 }
146 if err := fd.pd.prepareRead(fd.isFile); err != nil {
147 return 0, err
148 }
149 if fd.IsStream && len(p) > maxRW {
150 p = p[:maxRW]
151 }
152 for {
153 n, err := syscall.Read(fd.Sysfd, p)
154 if err != nil {
155 n = 0
156 if err == syscall.EAGAIN && fd.pd.pollable() {
157 if err = fd.pd.waitRead(fd.isFile); err == nil {
158 continue
159 }
160 }
161
162
163
164 if runtime.GOOS == "darwin" && err == syscall.EINTR {
165 continue
166 }
167 }
168 err = fd.eofError(n, err)
169 return n, err
170 }
171 }
172
173
174 func (fd *FD) Pread(p []byte, off int64) (int, error) {
175
176
177
178 if err := fd.incref(); err != nil {
179 return 0, err
180 }
181 if fd.IsStream && len(p) > maxRW {
182 p = p[:maxRW]
183 }
184 n, err := syscall.Pread(fd.Sysfd, p, off)
185 if err != nil {
186 n = 0
187 }
188 fd.decref()
189 err = fd.eofError(n, err)
190 return n, err
191 }
192
193
194 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
195 if err := fd.readLock(); err != nil {
196 return 0, nil, err
197 }
198 defer fd.readUnlock()
199 if err := fd.pd.prepareRead(fd.isFile); err != nil {
200 return 0, nil, err
201 }
202 for {
203 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
204 if err != nil {
205 n = 0
206 if err == syscall.EAGAIN && fd.pd.pollable() {
207 if err = fd.pd.waitRead(fd.isFile); err == nil {
208 continue
209 }
210 }
211 }
212 err = fd.eofError(n, err)
213 return n, sa, err
214 }
215 }
216
217
218 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
219 if err := fd.readLock(); err != nil {
220 return 0, 0, 0, nil, err
221 }
222 defer fd.readUnlock()
223 if err := fd.pd.prepareRead(fd.isFile); err != nil {
224 return 0, 0, 0, nil, err
225 }
226 for {
227 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
228 if err != nil {
229
230 if err == syscall.EAGAIN && fd.pd.pollable() {
231 if err = fd.pd.waitRead(fd.isFile); err == nil {
232 continue
233 }
234 }
235 }
236 err = fd.eofError(n, err)
237 return n, oobn, flags, sa, err
238 }
239 }
240
241
242 func (fd *FD) Write(p []byte) (int, error) {
243 if err := fd.writeLock(); err != nil {
244 return 0, err
245 }
246 defer fd.writeUnlock()
247 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
248 return 0, err
249 }
250 var nn int
251 for {
252 max := len(p)
253 if fd.IsStream && max-nn > maxRW {
254 max = nn + maxRW
255 }
256 n, err := syscall.Write(fd.Sysfd, p[nn:max])
257 if n > 0 {
258 nn += n
259 }
260 if nn == len(p) {
261 return nn, err
262 }
263 if err == syscall.EAGAIN && fd.pd.pollable() {
264 if err = fd.pd.waitWrite(fd.isFile); err == nil {
265 continue
266 }
267 }
268 if err != nil {
269 return nn, err
270 }
271 if n == 0 {
272 return nn, io.ErrUnexpectedEOF
273 }
274 }
275 }
276
277
278 func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
279
280
281
282 if err := fd.incref(); err != nil {
283 return 0, err
284 }
285 defer fd.decref()
286 var nn int
287 for {
288 max := len(p)
289 if fd.IsStream && max-nn > maxRW {
290 max = nn + maxRW
291 }
292 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
293 if n > 0 {
294 nn += n
295 }
296 if nn == len(p) {
297 return nn, err
298 }
299 if err != nil {
300 return nn, err
301 }
302 if n == 0 {
303 return nn, io.ErrUnexpectedEOF
304 }
305 }
306 }
307
308
309 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
310 if err := fd.writeLock(); err != nil {
311 return 0, err
312 }
313 defer fd.writeUnlock()
314 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
315 return 0, err
316 }
317 for {
318 err := syscall.Sendto(fd.Sysfd, p, 0, sa)
319 if err == syscall.EAGAIN && fd.pd.pollable() {
320 if err = fd.pd.waitWrite(fd.isFile); err == nil {
321 continue
322 }
323 }
324 if err != nil {
325 return 0, err
326 }
327 return len(p), nil
328 }
329 }
330
331
332 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
333 if err := fd.writeLock(); err != nil {
334 return 0, 0, err
335 }
336 defer fd.writeUnlock()
337 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
338 return 0, 0, err
339 }
340 for {
341 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
342 if err == syscall.EAGAIN && fd.pd.pollable() {
343 if err = fd.pd.waitWrite(fd.isFile); err == nil {
344 continue
345 }
346 }
347 if err != nil {
348 return n, 0, err
349 }
350 return n, len(oob), err
351 }
352 }
353
354
355 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
356 if err := fd.readLock(); err != nil {
357 return -1, nil, "", err
358 }
359 defer fd.readUnlock()
360
361 if err := fd.pd.prepareRead(fd.isFile); err != nil {
362 return -1, nil, "", err
363 }
364 for {
365 s, rsa, errcall, err := accept(fd.Sysfd)
366 if err == nil {
367 return s, rsa, "", err
368 }
369 switch err {
370 case syscall.EAGAIN:
371 if fd.pd.pollable() {
372 if err = fd.pd.waitRead(fd.isFile); err == nil {
373 continue
374 }
375 }
376 case syscall.ECONNABORTED:
377
378
379
380 continue
381 }
382 return -1, nil, errcall, err
383 }
384 }
385
386
387 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
388 if err := fd.incref(); err != nil {
389 return 0, err
390 }
391 defer fd.decref()
392 return syscall.Seek(fd.Sysfd, offset, whence)
393 }
394
395
396
397
398 func (fd *FD) ReadDirent(buf []byte) (int, error) {
399 if err := fd.incref(); err != nil {
400 return 0, err
401 }
402 defer fd.decref()
403 for {
404 n, err := syscall.ReadDirent(fd.Sysfd, buf)
405 if err != nil {
406 n = 0
407 if err == syscall.EAGAIN && fd.pd.pollable() {
408 if err = fd.pd.waitRead(fd.isFile); err == nil {
409 continue
410 }
411 }
412 }
413
414 return n, err
415 }
416 }
417
418
419 func (fd *FD) Fchdir() error {
420 if err := fd.incref(); err != nil {
421 return err
422 }
423 defer fd.decref()
424 return syscall.Fchdir(fd.Sysfd)
425 }
426
427
428 func (fd *FD) Fstat(s *syscall.Stat_t) error {
429 if err := fd.incref(); err != nil {
430 return err
431 }
432 defer fd.decref()
433 return syscall.Fstat(fd.Sysfd, s)
434 }
435
436
437
438
439 func (fd *FD) WaitWrite() error {
440 return fd.pd.waitWrite(fd.isFile)
441 }
442
443
444 func (fd *FD) WriteOnce(p []byte) (int, error) {
445 if err := fd.writeLock(); err != nil {
446 return 0, err
447 }
448 defer fd.writeUnlock()
449 return syscall.Write(fd.Sysfd, p)
450 }
451
452
453
454 func (fd *FD) RawControl(f func(uintptr)) error {
455 if err := fd.incref(); err != nil {
456 return err
457 }
458 defer fd.decref()
459 f(uintptr(fd.Sysfd))
460 return nil
461 }
462
463
464 func (fd *FD) RawRead(f func(uintptr) bool) error {
465 if err := fd.readLock(); err != nil {
466 return err
467 }
468 defer fd.readUnlock()
469 if err := fd.pd.prepareRead(fd.isFile); err != nil {
470 return err
471 }
472 for {
473 if f(uintptr(fd.Sysfd)) {
474 return nil
475 }
476 if err := fd.pd.waitRead(fd.isFile); err != nil {
477 return err
478 }
479 }
480 }
481
482
483 func (fd *FD) RawWrite(f func(uintptr) bool) error {
484 if err := fd.writeLock(); err != nil {
485 return err
486 }
487 defer fd.writeUnlock()
488 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
489 return err
490 }
491 for {
492 if f(uintptr(fd.Sysfd)) {
493 return nil
494 }
495 if err := fd.pd.waitWrite(fd.isFile); err != nil {
496 return err
497 }
498 }
499 }
500
View as plain text