github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/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 darwin dragonfly freebsd linux netbsd openbsd windows solaris 6 7 package poll 8 9 import ( 10 "errors" 11 "sync" 12 "syscall" 13 "time" 14 ) 15 16 // runtimeNano returns the current value of the runtime clock in nanoseconds. 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 // Evict evicts fd from the pending list, unblocking any I/O running on fd. 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 // SetDeadline sets the read and write deadlines associated with fd. 122 func (fd *FD) SetDeadline(t time.Time) error { 123 return setDeadlineImpl(fd, t, 'r'+'w') 124 } 125 126 // SetReadDeadline sets the read deadline associated with fd. 127 func (fd *FD) SetReadDeadline(t time.Time) error { 128 return setDeadlineImpl(fd, t, 'r') 129 } 130 131 // SetWriteDeadline sets the write deadline associated with fd. 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 // If the user has a deadline in the future, but the delay calculation 141 // overflows, then set the deadline to the maximum possible value. 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 // PollDescriptor returns the descriptor being used by the poller, 159 // or ^uintptr(0) if there isn't one. This is only used for testing. 160 func PollDescriptor() uintptr { 161 return runtime_pollServerDescriptor() 162 }