github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/net/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 net 8 9 import ( 10 "sync" 11 "syscall" 12 "time" 13 ) 14 15 // runtimeNano returns the current value of the runtime clock in nanoseconds. 16 func runtimeNano() int64 17 18 func runtime_pollServerInit() 19 func runtime_pollOpen(fd uintptr) (uintptr, int) 20 func runtime_pollClose(ctx uintptr) 21 func runtime_pollWait(ctx uintptr, mode int) int 22 func runtime_pollWaitCanceled(ctx uintptr, mode int) int 23 func runtime_pollReset(ctx uintptr, mode int) int 24 func runtime_pollSetDeadline(ctx uintptr, d int64, mode int) 25 func runtime_pollUnblock(ctx uintptr) 26 27 type pollDesc struct { 28 runtimeCtx uintptr 29 } 30 31 var serverInit sync.Once 32 33 func (pd *pollDesc) Init(fd *netFD) error { 34 serverInit.Do(runtime_pollServerInit) 35 ctx, errno := runtime_pollOpen(uintptr(fd.sysfd)) 36 if errno != 0 { 37 return syscall.Errno(errno) 38 } 39 pd.runtimeCtx = ctx 40 return nil 41 } 42 43 func (pd *pollDesc) Close() { 44 if pd.runtimeCtx == 0 { 45 return 46 } 47 runtime_pollClose(pd.runtimeCtx) 48 pd.runtimeCtx = 0 49 } 50 51 func (pd *pollDesc) Lock() { 52 } 53 54 func (pd *pollDesc) Unlock() { 55 } 56 57 func (pd *pollDesc) Wakeup() { 58 } 59 60 // Evict evicts fd from the pending list, unblocking any I/O running on fd. 61 // Return value is whether the pollServer should be woken up. 62 func (pd *pollDesc) Evict() bool { 63 if pd.runtimeCtx == 0 { 64 return false 65 } 66 runtime_pollUnblock(pd.runtimeCtx) 67 return false 68 } 69 70 func (pd *pollDesc) Prepare(mode int) error { 71 res := runtime_pollReset(pd.runtimeCtx, mode) 72 return convertErr(res) 73 } 74 75 func (pd *pollDesc) PrepareRead() error { 76 return pd.Prepare('r') 77 } 78 79 func (pd *pollDesc) PrepareWrite() error { 80 return pd.Prepare('w') 81 } 82 83 func (pd *pollDesc) Wait(mode int) error { 84 res := runtime_pollWait(pd.runtimeCtx, mode) 85 return convertErr(res) 86 } 87 88 func (pd *pollDesc) WaitRead() error { 89 return pd.Wait('r') 90 } 91 92 func (pd *pollDesc) WaitWrite() error { 93 return pd.Wait('w') 94 } 95 96 func (pd *pollDesc) WaitCanceled(mode int) { 97 runtime_pollWaitCanceled(pd.runtimeCtx, mode) 98 } 99 100 func (pd *pollDesc) WaitCanceledRead() { 101 pd.WaitCanceled('r') 102 } 103 104 func (pd *pollDesc) WaitCanceledWrite() { 105 pd.WaitCanceled('w') 106 } 107 108 func convertErr(res int) error { 109 switch res { 110 case 0: 111 return nil 112 case 1: 113 return errClosing 114 case 2: 115 return errTimeout 116 } 117 println("unreachable: ", res) 118 panic("unreachable") 119 } 120 121 func (fd *netFD) setDeadline(t time.Time) error { 122 return setDeadlineImpl(fd, t, 'r'+'w') 123 } 124 125 func (fd *netFD) setReadDeadline(t time.Time) error { 126 return setDeadlineImpl(fd, t, 'r') 127 } 128 129 func (fd *netFD) setWriteDeadline(t time.Time) error { 130 return setDeadlineImpl(fd, t, 'w') 131 } 132 133 func setDeadlineImpl(fd *netFD, t time.Time, mode int) error { 134 d := runtimeNano() + int64(t.Sub(time.Now())) 135 if t.IsZero() { 136 d = 0 137 } 138 if err := fd.incref(); err != nil { 139 return err 140 } 141 runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode) 142 fd.decref() 143 return nil 144 }