1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build unix || windows
14 _ "unsafe" // for go:linkname
17 // runtimeNano returns the current value of the runtime clock in nanoseconds.
19 //go:linkname runtimeNano runtime.nanotime
20 func runtimeNano() int64
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
32 type pollDesc struct {
36 var serverInit sync.Once
38 func (pd *pollDesc) init(fd *FD) error {
39 serverInit.Do(runtime_pollServerInit)
40 ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd))
42 return errnoErr(syscall.Errno(errno))
48 func (pd *pollDesc) close() {
49 if pd.runtimeCtx == 0 {
52 runtime_pollClose(pd.runtimeCtx)
56 // Evict evicts fd from the pending list, unblocking any I/O running on fd.
57 func (pd *pollDesc) evict() {
58 if pd.runtimeCtx == 0 {
61 runtime_pollUnblock(pd.runtimeCtx)
64 func (pd *pollDesc) prepare(mode int, isFile bool) error {
65 if pd.runtimeCtx == 0 {
68 res := runtime_pollReset(pd.runtimeCtx, mode)
69 return convertErr(res, isFile)
72 func (pd *pollDesc) prepareRead(isFile bool) error {
73 return pd.prepare('r', isFile)
76 func (pd *pollDesc) prepareWrite(isFile bool) error {
77 return pd.prepare('w', isFile)
80 func (pd *pollDesc) wait(mode int, isFile bool) error {
81 if pd.runtimeCtx == 0 {
82 return errors.New("waiting for unsupported file type")
84 res := runtime_pollWait(pd.runtimeCtx, mode)
85 return convertErr(res, isFile)
88 func (pd *pollDesc) waitRead(isFile bool) error {
89 return pd.wait('r', isFile)
92 func (pd *pollDesc) waitWrite(isFile bool) error {
93 return pd.wait('w', isFile)
96 func (pd *pollDesc) waitCanceled(mode int) {
97 if pd.runtimeCtx == 0 {
100 runtime_pollWaitCanceled(pd.runtimeCtx, mode)
103 func (pd *pollDesc) pollable() bool {
104 return pd.runtimeCtx != 0
107 // Error values returned by runtime_pollReset and runtime_pollWait.
108 // These must match the values in runtime/netpoll.go.
113 pollErrNotPollable = 3
116 func convertErr(res int, isFile bool) error {
121 return errClosing(isFile)
123 return ErrDeadlineExceeded
124 case pollErrNotPollable:
125 return ErrNotPollable
127 println("unreachable: ", res)
131 // SetDeadline sets the read and write deadlines associated with fd.
132 func (fd *FD) SetDeadline(t time.Time) error {
133 return setDeadlineImpl(fd, t, 'r'+'w')
136 // SetReadDeadline sets the read deadline associated with fd.
137 func (fd *FD) SetReadDeadline(t time.Time) error {
138 return setDeadlineImpl(fd, t, 'r')
141 // SetWriteDeadline sets the write deadline associated with fd.
142 func (fd *FD) SetWriteDeadline(t time.Time) error {
143 return setDeadlineImpl(fd, t, 'w')
146 func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
149 d = int64(time.Until(t))
151 d = -1 // don't confuse deadline right now with no deadline
154 if err := fd.incref(); err != nil {
158 if fd.pd.runtimeCtx == 0 {
161 runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
165 // IsPollDescriptor reports whether fd is the descriptor being used by the poller.
166 // This is only used for testing.
167 func IsPollDescriptor(fd uintptr) bool {
168 return runtime_isPollServerDescriptor(fd)