1 Star 0 Fork 1

mysnapcore/mysnapd

forked from tupelo-shen/mysnapd 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
rawsockstop.go 1.80 KB
一键复制 编辑 原始数据 按行查看 历史
tupelo-shen 提交于 2022-11-07 13:00 +08:00 . fix: osutil 3 commit
package netlink
import (
"fmt"
"math/bits"
"os"
"syscall"
)
// RawSockStopper returns a pair of functions to manage stopping code
// reading from a raw socket, readableOrStop blocks until
// fd is readable or stop was called. To work properly it sets fd
// to non-blocking mode.
// TODO: with go 1.11+ it should be possible to just switch to setting
// fd to non-blocking and then wrapping the socket via os.NewFile and
// use Close to force a read to stop.
// c.f. https://github.com/golang/go/commit/ea5825b0b64e1a017a76eac0ad734e11ff557c8e
func RawSockStopper(fd int) (readableOrStop func() (bool, error), stop func(), err error) {
if err := syscall.SetNonblock(fd, true); err != nil {
return nil, nil, err
}
stopR, stopW, err := os.Pipe()
if err != nil {
return nil, nil, err
}
// both stopR and stopW must be kept alive otherwise the corresponding
// file descriptors will get closed
readableOrStop = func() (bool, error) {
return stopperSelectReadable(fd, int(stopR.Fd()))
}
stop = func() {
stopW.Write([]byte{0})
}
return readableOrStop, stop, nil
}
func stopperSelectReadable(fd, stopFd int) (bool, error) {
maxFd := fd
if maxFd < stopFd {
maxFd = stopFd
}
if maxFd >= 1024 {
return false, fmt.Errorf("fd too high for syscall.Select")
}
fdIdx := fd / bits.UintSize
fdShift := uint(fd) % bits.UintSize
stopFdIdx := stopFd / bits.UintSize
stopFdShift := uint(stopFd) % bits.UintSize
readable := false
tout := stopperSelectTimeout()
for {
var r syscall.FdSet
r.Bits[fdIdx] = 1 << fdShift
r.Bits[stopFdIdx] |= 1 << stopFdShift
_, err := syscall.Select(maxFd+1, &r, nil, nil, tout)
if errno, ok := err.(syscall.Errno); ok && errno.Temporary() {
continue
}
if err != nil {
return false, err
}
readable = (r.Bits[fdIdx] & (1 << fdShift)) != 0
break
}
return readable, nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mysnapcore/mysnapd.git
git@gitee.com:mysnapcore/mysnapd.git
mysnapcore
mysnapd
mysnapd
v0.1.0

搜索帮助