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