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