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