...
Source file src/internal/poll/fd_poll_runtime.go
1
2
3
4
5
6
7 package poll
8
9 import (
10 "errors"
11 "sync"
12 "syscall"
13 "time"
14 _ "unsafe"
15 )
16
17
18
19 func runtimeNano() int64
20
21 func runtime_pollServerInit()
22 func runtime_pollOpen(fd uintptr) (uintptr, int)
23 func runtime_pollClose(ctx uintptr)
24 func runtime_pollWait(ctx uintptr, mode int) int
25 func runtime_pollWaitCanceled(ctx uintptr, mode int) int
26 func runtime_pollReset(ctx uintptr, mode int) int
27 func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
28 func runtime_pollUnblock(ctx uintptr)
29 func runtime_isPollServerDescriptor(fd uintptr) bool
30
31 type pollDesc struct {
32 runtimeCtx uintptr
33 }
34
35 var serverInit sync.Once
36
37 func (pd *pollDesc) init(fd *FD) error {
38 serverInit.Do(runtime_pollServerInit)
39 ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd))
40 if errno != 0 {
41 if ctx != 0 {
42 runtime_pollUnblock(ctx)
43 runtime_pollClose(ctx)
44 }
45 return errnoErr(syscall.Errno(errno))
46 }
47 pd.runtimeCtx = ctx
48 return nil
49 }
50
51 func (pd *pollDesc) close() {
52 if pd.runtimeCtx == 0 {
53 return
54 }
55 runtime_pollClose(pd.runtimeCtx)
56 pd.runtimeCtx = 0
57 }
58
59
60 func (pd *pollDesc) evict() {
61 if pd.runtimeCtx == 0 {
62 return
63 }
64 runtime_pollUnblock(pd.runtimeCtx)
65 }
66
67 func (pd *pollDesc) prepare(mode int, isFile bool) error {
68 if pd.runtimeCtx == 0 {
69 return nil
70 }
71 res := runtime_pollReset(pd.runtimeCtx, mode)
72 return convertErr(res, isFile)
73 }
74
75 func (pd *pollDesc) prepareRead(isFile bool) error {
76 return pd.prepare('r', isFile)
77 }
78
79 func (pd *pollDesc) prepareWrite(isFile bool) error {
80 return pd.prepare('w', isFile)
81 }
82
83 func (pd *pollDesc) wait(mode int, isFile bool) error {
84 if pd.runtimeCtx == 0 {
85 return errors.New("waiting for unsupported file type")
86 }
87 res := runtime_pollWait(pd.runtimeCtx, mode)
88 return convertErr(res, isFile)
89 }
90
91 func (pd *pollDesc) waitRead(isFile bool) error {
92 return pd.wait('r', isFile)
93 }
94
95 func (pd *pollDesc) waitWrite(isFile bool) error {
96 return pd.wait('w', isFile)
97 }
98
99 func (pd *pollDesc) waitCanceled(mode int) {
100 if pd.runtimeCtx == 0 {
101 return
102 }
103 runtime_pollWaitCanceled(pd.runtimeCtx, mode)
104 }
105
106 func (pd *pollDesc) pollable() bool {
107 return pd.runtimeCtx != 0
108 }
109
110 func convertErr(res int, isFile bool) error {
111 switch res {
112 case 0:
113 return nil
114 case 1:
115 return errClosing(isFile)
116 case 2:
117 return ErrTimeout
118 case 3:
119 return ErrNotPollable
120 }
121 println("unreachable: ", res)
122 panic("unreachable")
123 }
124
125
126 func (fd *FD) SetDeadline(t time.Time) error {
127 return setDeadlineImpl(fd, t, 'r'+'w')
128 }
129
130
131 func (fd *FD) SetReadDeadline(t time.Time) error {
132 return setDeadlineImpl(fd, t, 'r')
133 }
134
135
136 func (fd *FD) SetWriteDeadline(t time.Time) error {
137 return setDeadlineImpl(fd, t, 'w')
138 }
139
140 func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
141 var d int64
142 if !t.IsZero() {
143 d = int64(time.Until(t))
144 if d == 0 {
145 d = -1
146 }
147 }
148 if err := fd.incref(); err != nil {
149 return err
150 }
151 defer fd.decref()
152 if fd.pd.runtimeCtx == 0 {
153 return ErrNoDeadline
154 }
155 runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
156 return nil
157 }
158
159
160
161 func IsPollDescriptor(fd uintptr) bool {
162 return runtime_isPollServerDescriptor(fd)
163 }
164
View as plain text