revertws (#17216)
* Revert "MM-34000: Use non-epoll mode for TLS connections (#17172)" This reverts commit2743089b54. * Revert "MM-33233: Fix double close of webconn pump (#17026)" This reverts commit0f98620b65. * Revert "MM-33836: Detect and upgrade incorrect HTTP version for websocket handshakes (#17142)" This reverts commit4c5ea07aff. * revert i18n * Revert "MM-21012: Revamp websocket implementation (#16620)" This reverts commita246104d04. * fix go.mod * Trigger CI
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6a65b6ceca
Коммит
aba6471512
7
vendor/github.com/mailru/easygo/LICENSE
сгенерированный
поставляемый
7
vendor/github.com/mailru/easygo/LICENSE
сгенерированный
поставляемый
@@ -1,7 +0,0 @@
|
||||
Copyright (c) 2017 Mail.Ru Group
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
280
vendor/github.com/mailru/easygo/netpoll/epoll.go
сгенерированный
поставляемый
280
vendor/github.com/mailru/easygo/netpoll/epoll.go
сгенерированный
поставляемый
@@ -1,280 +0,0 @@
|
||||
// +build linux
|
||||
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// EpollEvent represents epoll events configuration bit mask.
|
||||
type EpollEvent uint32
|
||||
|
||||
// EpollEvents that are mapped to epoll_event.events possible values.
|
||||
const (
|
||||
EPOLLIN = unix.EPOLLIN
|
||||
EPOLLOUT = unix.EPOLLOUT
|
||||
EPOLLRDHUP = unix.EPOLLRDHUP
|
||||
EPOLLPRI = unix.EPOLLPRI
|
||||
EPOLLERR = unix.EPOLLERR
|
||||
EPOLLHUP = unix.EPOLLHUP
|
||||
EPOLLET = unix.EPOLLET
|
||||
EPOLLONESHOT = unix.EPOLLONESHOT
|
||||
|
||||
// _EPOLLCLOSED is a special EpollEvent value the receipt of which means
|
||||
// that the epoll instance is closed.
|
||||
_EPOLLCLOSED = 0x20
|
||||
)
|
||||
|
||||
// String returns a string representation of EpollEvent.
|
||||
func (evt EpollEvent) String() (str string) {
|
||||
name := func(event EpollEvent, name string) {
|
||||
if evt&event == 0 {
|
||||
return
|
||||
}
|
||||
if str != "" {
|
||||
str += "|"
|
||||
}
|
||||
str += name
|
||||
}
|
||||
|
||||
name(EPOLLIN, "EPOLLIN")
|
||||
name(EPOLLOUT, "EPOLLOUT")
|
||||
name(EPOLLRDHUP, "EPOLLRDHUP")
|
||||
name(EPOLLPRI, "EPOLLPRI")
|
||||
name(EPOLLERR, "EPOLLERR")
|
||||
name(EPOLLHUP, "EPOLLHUP")
|
||||
name(EPOLLET, "EPOLLET")
|
||||
name(EPOLLONESHOT, "EPOLLONESHOT")
|
||||
name(_EPOLLCLOSED, "_EPOLLCLOSED")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Epoll represents single epoll instance.
|
||||
type Epoll struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
fd int
|
||||
eventFd int
|
||||
closed bool
|
||||
waitDone chan struct{}
|
||||
|
||||
callbacks map[int]func(EpollEvent)
|
||||
}
|
||||
|
||||
// EpollConfig contains options for Epoll instance configuration.
|
||||
type EpollConfig struct {
|
||||
// OnWaitError will be called from goroutine, waiting for events.
|
||||
OnWaitError func(error)
|
||||
}
|
||||
|
||||
func (c *EpollConfig) withDefaults() (config EpollConfig) {
|
||||
if c != nil {
|
||||
config = *c
|
||||
}
|
||||
if config.OnWaitError == nil {
|
||||
config.OnWaitError = defaultOnWaitError
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// EpollCreate creates new epoll instance.
|
||||
// It starts the wait loop in separate goroutine.
|
||||
func EpollCreate(c *EpollConfig) (*Epoll, error) {
|
||||
config := c.withDefaults()
|
||||
|
||||
fd, err := unix.EpollCreate1(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r0, _, errno := unix.Syscall(unix.SYS_EVENTFD2, 0, 0, 0)
|
||||
if errno != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
eventFd := int(r0)
|
||||
|
||||
// Set finalizer for write end of socket pair to avoid data races when
|
||||
// closing Epoll instance and EBADF errors on writing ctl bytes from callers.
|
||||
err = unix.EpollCtl(fd, unix.EPOLL_CTL_ADD, eventFd, &unix.EpollEvent{
|
||||
Events: unix.EPOLLIN,
|
||||
Fd: int32(eventFd),
|
||||
})
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
unix.Close(eventFd)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ep := &Epoll{
|
||||
fd: fd,
|
||||
eventFd: eventFd,
|
||||
callbacks: make(map[int]func(EpollEvent)),
|
||||
waitDone: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Run wait loop.
|
||||
go ep.wait(config.OnWaitError)
|
||||
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
// closeBytes used for writing to eventfd.
|
||||
var closeBytes = []byte{1, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
// Close stops wait loop and closes all underlying resources.
|
||||
func (ep *Epoll) Close() (err error) {
|
||||
ep.mu.Lock()
|
||||
{
|
||||
if ep.closed {
|
||||
ep.mu.Unlock()
|
||||
return ErrClosed
|
||||
}
|
||||
ep.closed = true
|
||||
|
||||
if _, err = unix.Write(ep.eventFd, closeBytes); err != nil {
|
||||
ep.mu.Unlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
ep.mu.Unlock()
|
||||
|
||||
<-ep.waitDone
|
||||
|
||||
if err = unix.Close(ep.eventFd); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ep.mu.Lock()
|
||||
// Set callbacks to nil preventing long mu.Lock() hold.
|
||||
// This could increase the speed of retreiving ErrClosed in other calls to
|
||||
// current epoll instance.
|
||||
// Setting callbacks to nil is safe here because no one should read after
|
||||
// closed flag is true.
|
||||
callbacks := ep.callbacks
|
||||
ep.callbacks = nil
|
||||
ep.mu.Unlock()
|
||||
|
||||
for _, cb := range callbacks {
|
||||
if cb != nil {
|
||||
cb(_EPOLLCLOSED)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Add adds fd to epoll set with given events.
|
||||
// Callback will be called on each received event from epoll.
|
||||
// Note that _EPOLLCLOSED is triggered for every cb when epoll closed.
|
||||
func (ep *Epoll) Add(fd int, events EpollEvent, cb func(EpollEvent)) (err error) {
|
||||
ev := &unix.EpollEvent{
|
||||
Events: uint32(events),
|
||||
Fd: int32(fd),
|
||||
}
|
||||
|
||||
ep.mu.Lock()
|
||||
defer ep.mu.Unlock()
|
||||
|
||||
if ep.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, has := ep.callbacks[fd]; has {
|
||||
return ErrRegistered
|
||||
}
|
||||
ep.callbacks[fd] = cb
|
||||
|
||||
return unix.EpollCtl(ep.fd, unix.EPOLL_CTL_ADD, fd, ev)
|
||||
}
|
||||
|
||||
// Del removes fd from epoll set.
|
||||
func (ep *Epoll) Del(fd int) (err error) {
|
||||
ep.mu.Lock()
|
||||
defer ep.mu.Unlock()
|
||||
|
||||
if ep.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, ok := ep.callbacks[fd]; !ok {
|
||||
return ErrNotRegistered
|
||||
}
|
||||
|
||||
delete(ep.callbacks, fd)
|
||||
|
||||
return unix.EpollCtl(ep.fd, unix.EPOLL_CTL_DEL, fd, nil)
|
||||
}
|
||||
|
||||
// Mod sets to listen events on fd.
|
||||
func (ep *Epoll) Mod(fd int, events EpollEvent) (err error) {
|
||||
ev := &unix.EpollEvent{
|
||||
Events: uint32(events),
|
||||
Fd: int32(fd),
|
||||
}
|
||||
|
||||
ep.mu.RLock()
|
||||
defer ep.mu.RUnlock()
|
||||
|
||||
if ep.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, ok := ep.callbacks[fd]; !ok {
|
||||
return ErrNotRegistered
|
||||
}
|
||||
|
||||
return unix.EpollCtl(ep.fd, unix.EPOLL_CTL_MOD, fd, ev)
|
||||
}
|
||||
|
||||
const (
|
||||
maxWaitEventsBegin = 1024
|
||||
maxWaitEventsStop = 32768
|
||||
)
|
||||
|
||||
func (ep *Epoll) wait(onError func(error)) {
|
||||
defer func() {
|
||||
if err := unix.Close(ep.fd); err != nil {
|
||||
onError(err)
|
||||
}
|
||||
close(ep.waitDone)
|
||||
}()
|
||||
|
||||
events := make([]unix.EpollEvent, maxWaitEventsBegin)
|
||||
callbacks := make([]func(EpollEvent), 0, maxWaitEventsBegin)
|
||||
|
||||
for {
|
||||
n, err := unix.EpollWait(ep.fd, events, -1)
|
||||
if err != nil {
|
||||
if temporaryErr(err) {
|
||||
continue
|
||||
}
|
||||
onError(err)
|
||||
return
|
||||
}
|
||||
|
||||
callbacks = callbacks[:n]
|
||||
|
||||
ep.mu.RLock()
|
||||
for i := 0; i < n; i++ {
|
||||
fd := int(events[i].Fd)
|
||||
if fd == ep.eventFd { // signal to close
|
||||
ep.mu.RUnlock()
|
||||
return
|
||||
}
|
||||
callbacks[i] = ep.callbacks[fd]
|
||||
}
|
||||
ep.mu.RUnlock()
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
if cb := callbacks[i]; cb != nil {
|
||||
cb(EpollEvent(events[i].Events))
|
||||
callbacks[i] = nil
|
||||
}
|
||||
}
|
||||
|
||||
if n == len(events) && n*2 <= maxWaitEventsStop {
|
||||
events = make([]unix.EpollEvent, n*2)
|
||||
callbacks = make([]func(EpollEvent), 0, n*2)
|
||||
}
|
||||
}
|
||||
}
|
||||
119
vendor/github.com/mailru/easygo/netpoll/handle.go
сгенерированный
поставляемый
119
vendor/github.com/mailru/easygo/netpoll/handle.go
сгенерированный
поставляемый
@@ -1,119 +0,0 @@
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
// filer describes an object that has ability to return os.File.
|
||||
type filer interface {
|
||||
// File returns a copy of object's file descriptor.
|
||||
File() (*os.File, error)
|
||||
}
|
||||
|
||||
// Desc is a network connection within netpoll descriptor.
|
||||
// It's methods are not goroutine safe.
|
||||
type Desc struct {
|
||||
file *os.File
|
||||
event Event
|
||||
}
|
||||
|
||||
// NewDesc creates descriptor from custom fd.
|
||||
func NewDesc(fd uintptr, ev Event) *Desc {
|
||||
return &Desc{os.NewFile(fd, ""), ev}
|
||||
}
|
||||
|
||||
// Close closes underlying file.
|
||||
func (h *Desc) Close() error {
|
||||
return h.file.Close()
|
||||
}
|
||||
|
||||
func (h *Desc) fd() int {
|
||||
return int(h.file.Fd())
|
||||
}
|
||||
|
||||
// Must is a helper that wraps a call to a function returning (*Desc, error).
|
||||
// It panics if the error is non-nil and returns desc if not.
|
||||
// It is intended for use in short Desc initializations.
|
||||
func Must(desc *Desc, err error) *Desc {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
// HandleRead creates read descriptor for further use in Poller methods.
|
||||
// It is the same as Handle(conn, EventRead|EventEdgeTriggered).
|
||||
func HandleRead(conn net.Conn) (*Desc, error) {
|
||||
return Handle(conn, EventRead|EventEdgeTriggered)
|
||||
}
|
||||
|
||||
// HandleReadOnce creates read descriptor for further use in Poller methods.
|
||||
// It is the same as Handle(conn, EventRead|EventOneShot).
|
||||
func HandleReadOnce(conn net.Conn) (*Desc, error) {
|
||||
return Handle(conn, EventRead|EventOneShot)
|
||||
}
|
||||
|
||||
// HandleWrite creates write descriptor for further use in Poller methods.
|
||||
// It is the same as Handle(conn, EventWrite|EventEdgeTriggered).
|
||||
func HandleWrite(conn net.Conn) (*Desc, error) {
|
||||
return Handle(conn, EventWrite|EventEdgeTriggered)
|
||||
}
|
||||
|
||||
// HandleWriteOnce creates write descriptor for further use in Poller methods.
|
||||
// It is the same as Handle(conn, EventWrite|EventOneShot).
|
||||
func HandleWriteOnce(conn net.Conn) (*Desc, error) {
|
||||
return Handle(conn, EventWrite|EventOneShot)
|
||||
}
|
||||
|
||||
// HandleReadWrite creates read and write descriptor for further use in Poller
|
||||
// methods.
|
||||
// It is the same as Handle(conn, EventRead|EventWrite|EventEdgeTriggered).
|
||||
func HandleReadWrite(conn net.Conn) (*Desc, error) {
|
||||
return Handle(conn, EventRead|EventWrite|EventEdgeTriggered)
|
||||
}
|
||||
|
||||
// Handle creates new Desc with given conn and event.
|
||||
// Returned descriptor could be used as argument to Start(), Resume() and
|
||||
// Stop() methods of some Poller implementation.
|
||||
func Handle(conn net.Conn, event Event) (*Desc, error) {
|
||||
desc, err := handle(conn, event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the file back to non blocking mode since conn.File() sets underlying
|
||||
// os.File to blocking mode. This is useful to get conn.Set{Read}Deadline
|
||||
// methods still working on source Conn.
|
||||
//
|
||||
// See https://golang.org/pkg/net/#TCPConn.File
|
||||
// See /usr/local/go/src/net/net.go: conn.File()
|
||||
if err = setNonblock(desc.fd(), true); err != nil {
|
||||
return nil, os.NewSyscallError("setnonblock", err)
|
||||
}
|
||||
|
||||
return desc, nil
|
||||
}
|
||||
|
||||
// HandleListener returns descriptor for a net.Listener.
|
||||
func HandleListener(ln net.Listener, event Event) (*Desc, error) {
|
||||
return handle(ln, event)
|
||||
}
|
||||
|
||||
func handle(x interface{}, event Event) (*Desc, error) {
|
||||
f, ok := x.(filer)
|
||||
if !ok {
|
||||
return nil, ErrNotFiler
|
||||
}
|
||||
|
||||
// Get a copy of fd.
|
||||
file, err := f.File()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Desc{
|
||||
file: file,
|
||||
event: event,
|
||||
}, nil
|
||||
}
|
||||
9
vendor/github.com/mailru/easygo/netpoll/handle_stub.go
сгенерированный
поставляемый
9
vendor/github.com/mailru/easygo/netpoll/handle_stub.go
сгенерированный
поставляемый
@@ -1,9 +0,0 @@
|
||||
// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd
|
||||
|
||||
package netpoll
|
||||
|
||||
import "fmt"
|
||||
|
||||
func setNonblock(fd int, nonblocking bool) (err error) {
|
||||
return fmt.Errorf("setNonblock is not supported on this operating system")
|
||||
}
|
||||
9
vendor/github.com/mailru/easygo/netpoll/handle_unix.go
сгенерированный
поставляемый
9
vendor/github.com/mailru/easygo/netpoll/handle_unix.go
сгенерированный
поставляемый
@@ -1,9 +0,0 @@
|
||||
// +build linux darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package netpoll
|
||||
|
||||
import "syscall"
|
||||
|
||||
func setNonblock(fd int, nonblocking bool) (err error) {
|
||||
return syscall.SetNonblock(fd, nonblocking)
|
||||
}
|
||||
401
vendor/github.com/mailru/easygo/netpoll/kqueue.go
сгенерированный
поставляемый
401
vendor/github.com/mailru/easygo/netpoll/kqueue.go
сгенерированный
поставляемый
@@ -1,401 +0,0 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// KeventFilter is a kqueue event filter.
|
||||
type KeventFilter int
|
||||
|
||||
// String returns string representation of a filter.
|
||||
func (filter KeventFilter) String() (str string) {
|
||||
switch filter {
|
||||
case EVFILT_READ:
|
||||
return "EVFILT_READ"
|
||||
case EVFILT_WRITE:
|
||||
return "EVFILT_WRITE"
|
||||
case EVFILT_AIO:
|
||||
return "EVFILT_AIO"
|
||||
case EVFILT_VNODE:
|
||||
return "EVFILT_VNODE"
|
||||
case EVFILT_PROC:
|
||||
return "EVFILT_PROC"
|
||||
case EVFILT_SIGNAL:
|
||||
return "EVFILT_SIGNAL"
|
||||
case EVFILT_TIMER:
|
||||
return "EVFILT_TIMER"
|
||||
case EVFILT_USER:
|
||||
return "EVFILT_USER"
|
||||
case _EVFILT_CLOSED:
|
||||
return "_EVFILT_CLOSED"
|
||||
default:
|
||||
return "_EVFILT_UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// EVFILT_READ takes a descriptor as the identifier, and returns whenever
|
||||
// there is data available to read. The behavior of the filter is slightly
|
||||
// different depending on the descriptor type.
|
||||
EVFILT_READ = unix.EVFILT_READ
|
||||
|
||||
// EVFILT_WRITE takes a descriptor as the identifier, and returns whenever
|
||||
// it is possible to write to the descriptor. For sockets, pipes and fifos,
|
||||
// data will contain the amount of space remaining in the write buffer. The
|
||||
// filter will set EV_EOF when the reader disconnects, and for the fifo
|
||||
// case, this may be cleared by use of EV_CLEAR. Note that this filter is
|
||||
// not supported for vnodes or BPF devices. For sockets, the low water mark
|
||||
// and socket error handling is identical to the EVFILT_READ case.
|
||||
EVFILT_WRITE = unix.EVFILT_WRITE
|
||||
|
||||
// EVFILT_AIO the sigevent portion of the AIO request is filled in, with
|
||||
// sigev_notify_kqueue containing the descriptor of the kqueue that the
|
||||
// event should be attached to, sigev_notify_kevent_flags containing the
|
||||
// kevent flags which should be EV_ONESHOT, EV_CLEAR or EV_DISPATCH,
|
||||
// sigev_value containing the udata value, and sigev_notify set to
|
||||
// SIGEV_KEVENT. When the aio_*() system call is made, the event will be
|
||||
// registered with the specified kqueue, and the ident argument set to the
|
||||
// struct aiocb returned by the aio_*() system call. The filter returns
|
||||
// under the same conditions as aio_error().
|
||||
EVFILT_AIO = unix.EVFILT_AIO
|
||||
|
||||
// EVFILT_VNODE takes a file descriptor as the identifier and the events to
|
||||
// watch for in fflags, and returns when one or more of the requested
|
||||
// events occurs on the descriptor.
|
||||
EVFILT_VNODE = unix.EVFILT_VNODE
|
||||
|
||||
// EVFILT_PROC takes the process ID to monitor as the identifier and the
|
||||
// events to watch for in fflags, and returns when the process performs one
|
||||
// or more of the requested events. If a process can normally see another
|
||||
// process, it can attach an event to it.
|
||||
EVFILT_PROC = unix.EVFILT_PROC
|
||||
|
||||
// EVFILT_SIGNAL takes the signal number to monitor as the identifier and
|
||||
// returns when the given signal is delivered to the process. This coexists
|
||||
// with the signal() and sigaction() facilities, and has a lower
|
||||
// precedence. The filter will record all attempts to deliver a signal to
|
||||
// a process, even if the signal has been marked as SIG_IGN, except for the
|
||||
// SIGCHLD signal, which, if ignored, won't be recorded by the filter.
|
||||
// Event notification happens after normal signal delivery processing. data
|
||||
// returns the number of times the signal has occurred since the last call
|
||||
// to kevent(). This filter automatically sets the EV_CLEAR flag
|
||||
// internally.
|
||||
EVFILT_SIGNAL = unix.EVFILT_SIGNAL
|
||||
|
||||
// EVFILT_TIMER establishes an arbitrary timer identified by ident. When
|
||||
// adding a timer, data specifies the timeout period. The timer will be
|
||||
// periodic unless EV_ONESHOT is specified. On return, data contains the
|
||||
// number of times the timeout has expired since the last call to kevent().
|
||||
// This filter automatically sets the EV_CLEAR flag internally. There is a
|
||||
// system wide limit on the number of timers which is controlled by the
|
||||
// kern.kq_calloutmax sysctl.
|
||||
EVFILT_TIMER = unix.EVFILT_TIMER
|
||||
|
||||
// EVFILT_USER establishes a user event identified by ident which is not
|
||||
// associated with any kernel mechanism but is trig- gered by user level
|
||||
// code.
|
||||
EVFILT_USER = unix.EVFILT_USER
|
||||
|
||||
// Custom filter value signaling that kqueue instance get closed.
|
||||
_EVFILT_CLOSED = -0x7f
|
||||
)
|
||||
|
||||
// KeventFlag represents kqueue event flag.
|
||||
type KeventFlag int
|
||||
|
||||
// String returns string representation of flag bits of the form
|
||||
// "EV_A|EV_B|...".
|
||||
func (flag KeventFlag) String() (str string) {
|
||||
name := func(f KeventFlag, name string) {
|
||||
if flag&f == 0 {
|
||||
return
|
||||
}
|
||||
if str != "" {
|
||||
str += "|"
|
||||
}
|
||||
str += name
|
||||
}
|
||||
name(EV_ADD, "EV_ADD")
|
||||
name(EV_ENABLE, "EV_ENABLE")
|
||||
name(EV_DISABLE, "EV_DISABLE")
|
||||
name(EV_DISPATCH, "EV_DISPATCH")
|
||||
name(EV_DELETE, "EV_DELETE")
|
||||
name(EV_RECEIPT, "EV_RECEIPT")
|
||||
name(EV_ONESHOT, "EV_ONESHOT")
|
||||
name(EV_CLEAR, "EV_CLEAR")
|
||||
name(EV_EOF, "EV_EOF")
|
||||
name(EV_ERROR, "EV_ERROR")
|
||||
return
|
||||
}
|
||||
|
||||
const (
|
||||
// EV_ADD adds the event to the kqueue. Re-adding an existing event will modify
|
||||
// the parameters of the original event, and not result in a duplicate
|
||||
// entry. Adding an event automatically enables it, unless overridden by
|
||||
// the EV_DISABLE flag.
|
||||
EV_ADD = unix.EV_ADD
|
||||
|
||||
// EV_ENABLE permits kevent() to return the event if it is triggered.
|
||||
EV_ENABLE = unix.EV_ENABLE
|
||||
|
||||
// EV_DISABLE disables the event so kevent() will not return it. The filter itself is
|
||||
// not disabled.
|
||||
EV_DISABLE = unix.EV_DISABLE
|
||||
|
||||
// EV_DISPATCH disables the event source immediately after delivery of an event. See
|
||||
// EV_DISABLE above.
|
||||
EV_DISPATCH = unix.EV_DISPATCH
|
||||
|
||||
// EV_DELETE removes the event from the kqueue. Events which are attached to file
|
||||
// descriptors are automatically deleted on the last close of the
|
||||
// descriptor.
|
||||
EV_DELETE = unix.EV_DELETE
|
||||
|
||||
// EV_RECEIPT is useful for making bulk changes to a kqueue without draining
|
||||
// any pending events. When passed as input, it forces EV_ERROR to always
|
||||
// be returned. When a filter is successfully added the data field will be
|
||||
// zero.
|
||||
EV_RECEIPT = unix.EV_RECEIPT
|
||||
|
||||
// EV_ONESHOT causes the event to return only the first occurrence of the
|
||||
// filter being triggered. After the user retrieves the event from the
|
||||
// kqueue, it is deleted.
|
||||
EV_ONESHOT = unix.EV_ONESHOT
|
||||
|
||||
// EV_CLEAR makes event state be reset after the event is retrieved by the
|
||||
// user. This is useful for filters which report state transitions instead
|
||||
// of the current state. Note that some filters may automatically set this
|
||||
// flag internally.
|
||||
EV_CLEAR = unix.EV_CLEAR
|
||||
|
||||
// EV_EOF may be set by the filters to indicate filter-specific EOF
|
||||
// condition.
|
||||
EV_EOF = unix.EV_EOF
|
||||
|
||||
// EV_ERROR is set to indiacate an error occured with the identtifier.
|
||||
EV_ERROR = unix.EV_ERROR
|
||||
)
|
||||
|
||||
// filterCount is a constant number of available filters which can be
|
||||
// registered for an identifier.
|
||||
const filterCount = 8
|
||||
|
||||
// Kevent represents kevent.
|
||||
type Kevent struct {
|
||||
Filter KeventFilter
|
||||
Flags KeventFlag
|
||||
Fflags uint32
|
||||
Data int64
|
||||
}
|
||||
|
||||
// Kevents is a fixed number of pairs of event filter and flags which can be
|
||||
// registered for an identifier.
|
||||
type Kevents [8]Kevent
|
||||
|
||||
// KeventHandler is a function that will be called when event occures on
|
||||
// registered identifier.
|
||||
type KeventHandler func(Kevent)
|
||||
|
||||
// KqueueConfig contains options for configuration kqueue instance.
|
||||
type KqueueConfig struct {
|
||||
// OnWaitError will be called from goroutine, waiting for events.
|
||||
OnWaitError func(error)
|
||||
}
|
||||
|
||||
func (c *KqueueConfig) withDefaults() (config KqueueConfig) {
|
||||
if c != nil {
|
||||
config = *c
|
||||
}
|
||||
if config.OnWaitError == nil {
|
||||
config.OnWaitError = defaultOnWaitError
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// Kqueue represents kqueue instance.
|
||||
type Kqueue struct {
|
||||
mu sync.RWMutex
|
||||
fd int
|
||||
cb map[int]KeventHandler
|
||||
done chan struct{}
|
||||
closed bool
|
||||
}
|
||||
|
||||
// KqueueCreate creates new kqueue instance.
|
||||
// It starts wait loop in a separate goroutine.
|
||||
func KqueueCreate(c *KqueueConfig) (*Kqueue, error) {
|
||||
config := c.withDefaults()
|
||||
|
||||
fd, err := unix.Kqueue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kq := &Kqueue{
|
||||
fd: fd,
|
||||
cb: make(map[int]KeventHandler),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
go kq.wait(config.OnWaitError)
|
||||
|
||||
return kq, nil
|
||||
}
|
||||
|
||||
// Close closes kqueue instance.
|
||||
// NOTE: not implemented yet.
|
||||
func (k *Kqueue) Close() error {
|
||||
// TODO(): implement close.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add adds a event handler for identifier fd with given n events.
|
||||
func (k *Kqueue) Add(fd int, events Kevents, n int, cb KeventHandler) error {
|
||||
var kevs [filterCount]unix.Kevent_t
|
||||
for i := 0; i < n; i++ {
|
||||
kevs[i] = evGet(fd, events[i].Filter, events[i].Flags)
|
||||
}
|
||||
|
||||
arr := unsafe.Pointer(&kevs)
|
||||
hdr := &reflect.SliceHeader{
|
||||
Data: uintptr(arr),
|
||||
Len: n,
|
||||
Cap: n,
|
||||
}
|
||||
changes := *(*[]unix.Kevent_t)(unsafe.Pointer(hdr))
|
||||
|
||||
k.mu.Lock()
|
||||
defer k.mu.Unlock()
|
||||
|
||||
if k.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, has := k.cb[fd]; has {
|
||||
return ErrRegistered
|
||||
}
|
||||
k.cb[fd] = cb
|
||||
|
||||
_, err := unix.Kevent(k.fd, changes, nil, nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Mod modifies events registered for fd.
|
||||
func (k *Kqueue) Mod(fd int, events Kevents, n int) error {
|
||||
var kevs [filterCount]unix.Kevent_t
|
||||
for i := 0; i < n; i++ {
|
||||
kevs[i] = evGet(fd, events[i].Filter, events[i].Flags)
|
||||
}
|
||||
|
||||
arr := unsafe.Pointer(&kevs)
|
||||
hdr := &reflect.SliceHeader{
|
||||
Data: uintptr(arr),
|
||||
Len: n,
|
||||
Cap: n,
|
||||
}
|
||||
changes := *(*[]unix.Kevent_t)(unsafe.Pointer(hdr))
|
||||
|
||||
k.mu.RLock()
|
||||
defer k.mu.RUnlock()
|
||||
|
||||
if k.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, has := k.cb[fd]; !has {
|
||||
return ErrNotRegistered
|
||||
}
|
||||
|
||||
_, err := unix.Kevent(k.fd, changes, nil, nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Del removes callback for fd. Note that it does not cleanups events for fd in
|
||||
// kqueue. You should close fd or call Mod() with EV_DELETE flag set.
|
||||
func (k *Kqueue) Del(fd int) error {
|
||||
k.mu.Lock()
|
||||
defer k.mu.Unlock()
|
||||
|
||||
if k.closed {
|
||||
return ErrClosed
|
||||
}
|
||||
if _, has := k.cb[fd]; !has {
|
||||
return ErrNotRegistered
|
||||
}
|
||||
|
||||
delete(k.cb, fd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *Kqueue) wait(onError func(error)) {
|
||||
const (
|
||||
maxWaitEventsBegin = 1 << 10 // 1024
|
||||
maxWaitEventsStop = 1 << 15 // 32768
|
||||
)
|
||||
|
||||
defer func() {
|
||||
if err := unix.Close(k.fd); err != nil {
|
||||
onError(err)
|
||||
}
|
||||
close(k.done)
|
||||
}()
|
||||
|
||||
evs := make([]unix.Kevent_t, maxWaitEventsBegin)
|
||||
cbs := make([]KeventHandler, maxWaitEventsBegin)
|
||||
|
||||
for {
|
||||
n, err := unix.Kevent(k.fd, nil, evs, nil)
|
||||
if err != nil {
|
||||
if temporaryErr(err) {
|
||||
continue
|
||||
}
|
||||
onError(err)
|
||||
return
|
||||
}
|
||||
|
||||
cbs = cbs[:n]
|
||||
k.mu.RLock()
|
||||
for i := 0; i < n; i++ {
|
||||
fd := int(evs[i].Ident)
|
||||
if fd == -1 { //todo
|
||||
k.mu.RUnlock()
|
||||
return
|
||||
}
|
||||
cbs[i] = k.cb[fd]
|
||||
}
|
||||
k.mu.RUnlock()
|
||||
|
||||
for i, cb := range cbs {
|
||||
if cb != nil {
|
||||
e := evs[i]
|
||||
cb(Kevent{
|
||||
Filter: KeventFilter(e.Filter),
|
||||
Flags: KeventFlag(e.Flags),
|
||||
Data: e.Data,
|
||||
Fflags: e.Fflags,
|
||||
})
|
||||
cbs[i] = nil
|
||||
}
|
||||
}
|
||||
|
||||
if n == len(evs) && n*2 <= maxWaitEventsStop {
|
||||
evs = make([]unix.Kevent_t, n*2)
|
||||
cbs = make([]KeventHandler, n*2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func evGet(fd int, filter KeventFilter, flags KeventFlag) unix.Kevent_t {
|
||||
return unix.Kevent_t{
|
||||
Ident: uint64(fd),
|
||||
Filter: int16(filter),
|
||||
Flags: uint16(flags),
|
||||
}
|
||||
}
|
||||
185
vendor/github.com/mailru/easygo/netpoll/netpoll.go
сгенерированный
поставляемый
185
vendor/github.com/mailru/easygo/netpoll/netpoll.go
сгенерированный
поставляемый
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
Package netpoll provides a portable interface for network I/O event
|
||||
notification facility.
|
||||
|
||||
Its API is intended for monitoring multiple file descriptors to see if I/O is
|
||||
possible on any of them. It supports edge-triggered and level-triggered
|
||||
interfaces.
|
||||
|
||||
To get more info you could look at operating system API documentation of
|
||||
particular netpoll implementations:
|
||||
- epoll on linux;
|
||||
- kqueue on bsd;
|
||||
|
||||
The Handle function creates netpoll.Desc for further use in Poller's methods:
|
||||
|
||||
desc, err := netpoll.Handle(conn, netpoll.EventRead | netpoll.EventEdgeTriggered)
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
|
||||
The Poller describes os-dependent network poller:
|
||||
|
||||
poller, err := netpoll.New(nil)
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
|
||||
// Get netpoll descriptor with EventRead|EventEdgeTriggered.
|
||||
desc := netpoll.Must(netpoll.HandleRead(conn))
|
||||
|
||||
poller.Start(desc, func(ev netpoll.Event) {
|
||||
if ev&netpoll.EventReadHup != 0 {
|
||||
poller.Stop(desc)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
_, err := ioutil.ReadAll(conn)
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
})
|
||||
|
||||
Currently, Poller is implemented only for Linux.
|
||||
*/
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotFiler is returned by Handle* functions to indicate that given
|
||||
// net.Conn does not provide access to its file descriptor.
|
||||
ErrNotFiler = fmt.Errorf("could not get file descriptor")
|
||||
|
||||
// ErrClosed is returned by Poller methods to indicate that instance is
|
||||
// closed and operation could not be processed.
|
||||
ErrClosed = fmt.Errorf("poller instance is closed")
|
||||
|
||||
// ErrRegistered is returned by Poller Start() method to indicate that
|
||||
// connection with the same underlying file descriptor was already
|
||||
// registered within the poller instance.
|
||||
ErrRegistered = fmt.Errorf("file descriptor is already registered in poller instance")
|
||||
|
||||
// ErrNotRegistered is returned by Poller Stop() and Resume() methods to
|
||||
// indicate that connection with the same underlying file descriptor was
|
||||
// not registered before within the poller instance.
|
||||
ErrNotRegistered = fmt.Errorf("file descriptor was not registered before in poller instance")
|
||||
)
|
||||
|
||||
// Event represents netpoll configuration bit mask.
|
||||
type Event uint16
|
||||
|
||||
// Event values that denote the type of events that caller want to receive.
|
||||
const (
|
||||
EventRead Event = 0x1
|
||||
EventWrite = 0x2
|
||||
)
|
||||
|
||||
// Event values that configure the Poller's behavior.
|
||||
const (
|
||||
EventOneShot Event = 0x4
|
||||
EventEdgeTriggered = 0x8
|
||||
)
|
||||
|
||||
// Event values that could be passed to CallbackFn as additional information
|
||||
// event.
|
||||
const (
|
||||
// EventHup is indicates that some side of i/o operations (receive, send or
|
||||
// both) is closed.
|
||||
// Usually (depending on operating system and its version) the EventReadHup
|
||||
// or EventWriteHup are also set int Event value.
|
||||
EventHup Event = 0x10
|
||||
|
||||
EventReadHup = 0x20
|
||||
EventWriteHup = 0x40
|
||||
|
||||
EventErr = 0x80
|
||||
|
||||
// EventPollerClosed is a special Event value the receipt of which means that the
|
||||
// Poller instance is closed.
|
||||
EventPollerClosed = 0x8000
|
||||
)
|
||||
|
||||
// String returns a string representation of Event.
|
||||
func (ev Event) String() (str string) {
|
||||
name := func(event Event, name string) {
|
||||
if ev&event == 0 {
|
||||
return
|
||||
}
|
||||
if str != "" {
|
||||
str += "|"
|
||||
}
|
||||
str += name
|
||||
}
|
||||
|
||||
name(EventRead, "EventRead")
|
||||
name(EventWrite, "EventWrite")
|
||||
name(EventOneShot, "EventOneShot")
|
||||
name(EventEdgeTriggered, "EventEdgeTriggered")
|
||||
name(EventReadHup, "EventReadHup")
|
||||
name(EventWriteHup, "EventWriteHup")
|
||||
name(EventHup, "EventHup")
|
||||
name(EventErr, "EventErr")
|
||||
name(EventPollerClosed, "EventPollerClosed")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Poller describes an object that implements logic of polling connections for
|
||||
// i/o events such as availability of read() or write() operations.
|
||||
type Poller interface {
|
||||
// Start adds desc to the observation list.
|
||||
//
|
||||
// Note that if desc was configured with OneShot event, then poller will
|
||||
// remove it from its observation list. If you will be interested in
|
||||
// receiving events after the callback, call Resume(desc).
|
||||
//
|
||||
// Note that Resume() call directly inside desc's callback could cause
|
||||
// deadlock.
|
||||
//
|
||||
// Note that multiple calls with same desc will produce unexpected
|
||||
// behavior.
|
||||
Start(*Desc, CallbackFn) error
|
||||
|
||||
// Stop removes desc from the observation list.
|
||||
//
|
||||
// Note that it does not call desc.Close().
|
||||
Stop(*Desc) error
|
||||
|
||||
// Resume enables observation of desc.
|
||||
//
|
||||
// It is useful when desc was configured with EventOneShot.
|
||||
// It should be called only after Start().
|
||||
//
|
||||
// Note that if there no need to observe desc anymore, you should call
|
||||
// Stop() to prevent memory leaks.
|
||||
Resume(*Desc) error
|
||||
}
|
||||
|
||||
// CallbackFn is a function that will be called on kernel i/o event
|
||||
// notification.
|
||||
type CallbackFn func(Event)
|
||||
|
||||
// Config contains options for Poller configuration.
|
||||
type Config struct {
|
||||
// OnWaitError will be called from goroutine, waiting for events.
|
||||
OnWaitError func(error)
|
||||
}
|
||||
|
||||
func (c *Config) withDefaults() (config Config) {
|
||||
if c != nil {
|
||||
config = *c
|
||||
}
|
||||
if config.OnWaitError == nil {
|
||||
config.OnWaitError = defaultOnWaitError
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
func defaultOnWaitError(err error) {
|
||||
log.Printf("netpoll: wait loop error: %s", err)
|
||||
}
|
||||
88
vendor/github.com/mailru/easygo/netpoll/netpoll_epoll.go
сгенерированный
поставляемый
88
vendor/github.com/mailru/easygo/netpoll/netpoll_epoll.go
сгенерированный
поставляемый
@@ -1,88 +0,0 @@
|
||||
// +build linux
|
||||
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// New creates new epoll-based Poller instance with given config.
|
||||
func New(c *Config) (Poller, error) {
|
||||
cfg := c.withDefaults()
|
||||
|
||||
epoll, err := EpollCreate(&EpollConfig{
|
||||
OnWaitError: cfg.OnWaitError,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return poller{epoll}, nil
|
||||
}
|
||||
|
||||
// poller implements Poller interface.
|
||||
type poller struct {
|
||||
*Epoll
|
||||
}
|
||||
|
||||
// Start implements Poller.Start() method.
|
||||
func (ep poller) Start(desc *Desc, cb CallbackFn) error {
|
||||
err := ep.Add(desc.fd(), toEpollEvent(desc.event),
|
||||
func(ep EpollEvent) {
|
||||
var event Event
|
||||
|
||||
if ep&EPOLLHUP != 0 {
|
||||
event |= EventHup
|
||||
}
|
||||
if ep&EPOLLRDHUP != 0 {
|
||||
event |= EventReadHup
|
||||
}
|
||||
if ep&EPOLLIN != 0 {
|
||||
event |= EventRead
|
||||
}
|
||||
if ep&EPOLLOUT != 0 {
|
||||
event |= EventWrite
|
||||
}
|
||||
if ep&EPOLLERR != 0 {
|
||||
event |= EventErr
|
||||
}
|
||||
if ep&_EPOLLCLOSED != 0 {
|
||||
event |= EventPollerClosed
|
||||
}
|
||||
|
||||
cb(event)
|
||||
},
|
||||
)
|
||||
if err == nil {
|
||||
if err = setNonblock(desc.fd(), true); err != nil {
|
||||
return os.NewSyscallError("setnonblock", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop implements Poller.Stop() method.
|
||||
func (ep poller) Stop(desc *Desc) error {
|
||||
return ep.Del(desc.fd())
|
||||
}
|
||||
|
||||
// Resume implements Poller.Resume() method.
|
||||
func (ep poller) Resume(desc *Desc) error {
|
||||
return ep.Mod(desc.fd(), toEpollEvent(desc.event))
|
||||
}
|
||||
|
||||
func toEpollEvent(event Event) (ep EpollEvent) {
|
||||
if event&EventRead != 0 {
|
||||
ep |= EPOLLIN | EPOLLRDHUP
|
||||
}
|
||||
if event&EventWrite != 0 {
|
||||
ep |= EPOLLOUT
|
||||
}
|
||||
if event&EventOneShot != 0 {
|
||||
ep |= EPOLLONESHOT
|
||||
}
|
||||
if event&EventEdgeTriggered != 0 {
|
||||
ep |= EPOLLET
|
||||
}
|
||||
return ep
|
||||
}
|
||||
112
vendor/github.com/mailru/easygo/netpoll/netpoll_kqueue.go
сгенерированный
поставляемый
112
vendor/github.com/mailru/easygo/netpoll/netpoll_kqueue.go
сгенерированный
поставляемый
@@ -1,112 +0,0 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package netpoll
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// New creates new kqueue-based Poller instance with given config.
|
||||
func New(c *Config) (Poller, error) {
|
||||
cfg := c.withDefaults()
|
||||
|
||||
kq, err := KqueueCreate(&KqueueConfig{
|
||||
OnWaitError: cfg.OnWaitError,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return poller{kq}, nil
|
||||
}
|
||||
|
||||
type poller struct {
|
||||
*Kqueue
|
||||
}
|
||||
|
||||
func (p poller) Start(desc *Desc, cb CallbackFn) error {
|
||||
n, events := toKevents(desc.event, true)
|
||||
err := p.Add(desc.fd(), events, n, func(kev Kevent) {
|
||||
var (
|
||||
event Event
|
||||
|
||||
flags = kev.Flags
|
||||
filter = kev.Filter
|
||||
)
|
||||
|
||||
// Set EventHup for any EOF flag. Below will be more precise detection
|
||||
// of what exatcly HUP occured.
|
||||
if flags&EV_EOF != 0 {
|
||||
event |= EventHup
|
||||
}
|
||||
|
||||
if filter == EVFILT_READ {
|
||||
event |= EventRead
|
||||
if flags&EV_EOF != 0 {
|
||||
event |= EventReadHup
|
||||
}
|
||||
}
|
||||
if filter == EVFILT_WRITE {
|
||||
event |= EventWrite
|
||||
if flags&EV_EOF != 0 {
|
||||
event |= EventWriteHup
|
||||
}
|
||||
}
|
||||
if flags&EV_ERROR != 0 {
|
||||
event |= EventErr
|
||||
}
|
||||
if filter == _EVFILT_CLOSED {
|
||||
event |= EventPollerClosed
|
||||
}
|
||||
|
||||
cb(event)
|
||||
})
|
||||
if err == nil {
|
||||
if err = setNonblock(desc.fd(), true); err != nil {
|
||||
return os.NewSyscallError("setnonblock", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p poller) Stop(desc *Desc) error {
|
||||
n, events := toKevents(desc.event, false)
|
||||
if err := p.Del(desc.fd()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.Mod(desc.fd(), events, n); err != nil && err != ErrNotRegistered {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p poller) Resume(desc *Desc) error {
|
||||
n, events := toKevents(desc.event, true)
|
||||
return p.Mod(desc.fd(), events, n)
|
||||
}
|
||||
|
||||
func toKevents(event Event, add bool) (n int, ks Kevents) {
|
||||
var flags KeventFlag
|
||||
if add {
|
||||
flags = EV_ADD
|
||||
if event&EventOneShot != 0 {
|
||||
flags |= EV_ONESHOT
|
||||
}
|
||||
if event&EventEdgeTriggered != 0 {
|
||||
flags |= EV_CLEAR
|
||||
}
|
||||
} else {
|
||||
flags = EV_DELETE
|
||||
}
|
||||
if event&EventRead != 0 {
|
||||
ks[n].Flags = flags
|
||||
ks[n].Filter = EVFILT_READ
|
||||
n++
|
||||
}
|
||||
if event&EventWrite != 0 {
|
||||
ks[n].Flags = flags
|
||||
ks[n].Filter = EVFILT_WRITE
|
||||
n++
|
||||
}
|
||||
return
|
||||
}
|
||||
11
vendor/github.com/mailru/easygo/netpoll/netpoll_stub.go
сгенерированный
поставляемый
11
vendor/github.com/mailru/easygo/netpoll/netpoll_stub.go
сгенерированный
поставляемый
@@ -1,11 +0,0 @@
|
||||
// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd
|
||||
|
||||
package netpoll
|
||||
|
||||
import "fmt"
|
||||
|
||||
// New always returns an error to indicate that Poller is not implemented for
|
||||
// current operating system.
|
||||
func New(*Config) (Poller, error) {
|
||||
return nil, fmt.Errorf("poller is not supported on this operating system")
|
||||
}
|
||||
11
vendor/github.com/mailru/easygo/netpoll/util.go
сгенерированный
поставляемый
11
vendor/github.com/mailru/easygo/netpoll/util.go
сгенерированный
поставляемый
@@ -1,11 +0,0 @@
|
||||
package netpoll
|
||||
|
||||
import "syscall"
|
||||
|
||||
func temporaryErr(err error) bool {
|
||||
errno, ok := err.(syscall.Errno)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return errno.Temporary()
|
||||
}
|
||||
Ссылка в новой задаче
Block a user