github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/internal/poll/fd_poll_runtime.go (about) 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. 4 5 //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || windows || solaris 6 // +build aix darwin dragonfly freebsd linux netbsd openbsd windows solaris 7 8 package poll 9 10 import ( 11 "errors" 12 "sync" 13 "syscall" 14 "time" 15 _ "unsafe" // for go:linkname 16 ) 17 18 // runtimeNano returns the current value of the runtime clock in nanoseconds. 19 //go:linkname runtimeNano runtime.nanotime 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) 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 if ctx != 0 { 43 runtime_pollUnblock(ctx) 44 runtime_pollClose(ctx) 45 } 46 return errnoErr(syscall.Errno(errno)) 47 } 48 pd.runtimeCtx = ctx 49 return nil 50 } 51 52 func (pd *pollDesc) close() { 53 if pd.runtimeCtx == 0 { 54 return 55 } 56 runtime_pollClose(pd.runtimeCtx) 57 pd.runtimeCtx = 0 58 } 59 60 // Evict evicts fd from the pending list, unblocking any I/O running on fd. 61 func (pd *pollDesc) evict() { 62 if pd.runtimeCtx == 0 { 63 return 64 } 65 runtime_pollUnblock(pd.runtimeCtx) 66 } 67 68 func (pd *pollDesc) prepare(mode int, isFile bool) error { 69 if pd.runtimeCtx == 0 { 70 return nil 71 } 72 res := runtime_pollReset(pd.runtimeCtx, mode) 73 return convertErr(res, isFile) 74 } 75 76 func (pd *pollDesc) prepareRead(isFile bool) error { 77 return pd.prepare('r', isFile) 78 } 79 80 func (pd *pollDesc) prepareWrite(isFile bool) error { 81 return pd.prepare('w', isFile) 82 } 83 84 func (pd *pollDesc) wait(mode int, isFile bool) error { 85 if pd.runtimeCtx == 0 { 86 return errors.New("waiting for unsupported file type") 87 } 88 res := runtime_pollWait(pd.runtimeCtx, mode) 89 return convertErr(res, isFile) 90 } 91 92 func (pd *pollDesc) waitRead(isFile bool) error { 93 return pd.wait('r', isFile) 94 } 95 96 func (pd *pollDesc) waitWrite(isFile bool) error { 97 return pd.wait('w', isFile) 98 } 99 100 func (pd *pollDesc) waitCanceled(mode int) { 101 if pd.runtimeCtx == 0 { 102 return 103 } 104 runtime_pollWaitCanceled(pd.runtimeCtx, mode) 105 } 106 107 func (pd *pollDesc) pollable() bool { 108 return pd.runtimeCtx != 0 109 } 110 111 // Error values returned by runtime_pollReset and runtime_pollWait. 112 // These must match the values in runtime/netpoll.go. 113 const ( 114 pollNoError = 0 115 pollErrClosing = 1 116 pollErrTimeout = 2 117 pollErrNotPollable = 3 118 ) 119 120 func convertErr(res int, isFile bool) error { 121 switch res { 122 case pollNoError: 123 return nil 124 case pollErrClosing: 125 return errClosing(isFile) 126 case pollErrTimeout: 127 return ErrDeadlineExceeded 128 case pollErrNotPollable: 129 return ErrNotPollable 130 } 131 println("unreachable: ", res) 132 panic("unreachable") 133 } 134 135 // SetDeadline sets the read and write deadlines associated with fd. 136 func (fd *FD) SetDeadline(t time.Time) error { 137 return setDeadlineImpl(fd, t, 'r'+'w') 138 } 139 140 // SetReadDeadline sets the read deadline associated with fd. 141 func (fd *FD) SetReadDeadline(t time.Time) error { 142 return setDeadlineImpl(fd, t, 'r') 143 } 144 145 // SetWriteDeadline sets the write deadline associated with fd. 146 func (fd *FD) SetWriteDeadline(t time.Time) error { 147 return setDeadlineImpl(fd, t, 'w') 148 } 149 150 func setDeadlineImpl(fd *FD, t time.Time, mode int) error { 151 var d int64 152 if !t.IsZero() { 153 d = int64(time.Until(t)) 154 if d == 0 { 155 d = -1 // don't confuse deadline right now with no deadline 156 } 157 } 158 if err := fd.incref(); err != nil { 159 return err 160 } 161 defer fd.decref() 162 if fd.pd.runtimeCtx == 0 { 163 return ErrNoDeadline 164 } 165 runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode) 166 return nil 167 } 168 169 // IsPollDescriptor reports whether fd is the descriptor being used by the poller. 170 // This is only used for testing. 171 func IsPollDescriptor(fd uintptr) bool { 172 return runtime_isPollServerDescriptor(fd) 173 }