github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/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 unix || windows 6 7 package poll 8 9 import ( 10 "errors" 11 "sync" 12 "syscall" 13 "time" 14 _ "unsafe" // for go:linkname 15 ) 16 17 // runtimeNano returns the current value of the runtime clock in nanoseconds. 18 // 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) 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 // Evict evicts fd from the pending list, unblocking any I/O running on fd. 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 // Error values returned by runtime_pollReset and runtime_pollWait. 108 // These must match the values in runtime/netpoll.go. 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 // 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') 134 } 135 136 // SetReadDeadline sets the read deadline associated with fd. 137 func (fd *FD) SetReadDeadline(t time.Time) error { 138 return setDeadlineImpl(fd, t, 'r') 139 } 140 141 // SetWriteDeadline sets the write deadline associated with fd. 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 // don't confuse deadline right now with no deadline 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 // 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) 169 }