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