netpoll

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2019 License: MIT Imports: 8 Imported by: 6

Documentation

Overview

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.

Index

Constants

View Source
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
)
View Source
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 indicate an error occurred with the identifier.
	EV_ERROR = unix.EV_ERROR
)
View Source
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
	// EventPollClosed is a special Event value the receipt of which means that the
	// EventPoll instance is closed.
	EventPollClosed = 0x8000
)

Event values that could be passed to CallbackFn as additional information event.

Variables

View Source
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 EventPoll methods to indicate that instance is
	// closed and operation could not be processed.
	ErrClosed = fmt.Errorf("poller instance is closed")

	// ErrRegistered is returned by EventPoll 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 EventPoll 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")
)

Functions

This section is empty.

Types

type CallbackFn

type CallbackFn func(Event)

CallbackFn is a function that will be called on kernel i/o event notification.

type Config

type Config struct {
	// OnWaitError will be called from goroutine, waiting for events.
	OnWaitError func(error)
}

Config contains options for EventPoll configuration.

type Desc

type Desc struct {
	// contains filtered or unexported fields
}

Desc is a network connection within netpoll descriptor. It's methods are not goroutine safe.

func Handle

func Handle(conn net.Conn, event Event) (*Desc, error)

Handle creates new Desc with given conn and event. Returned descriptor could be used as argument to Start(), Resume() and Stop() methods of some EventPoll implementation.

func HandleListener

func HandleListener(ln net.Listener, event Event) (*Desc, error)

HandleListener returns descriptor for a net.Listener.

func HandleRead

func HandleRead(conn net.Conn) (*Desc, error)

HandleRead creates read descriptor for further use in EventPoll methods. It is the same as Handle(conn, EventRead|EventEdgeTriggered).

func HandleReadOnce

func HandleReadOnce(conn net.Conn) (*Desc, error)

HandleReadOnce creates read descriptor for further use in EventPoll methods. It is the same as Handle(conn, EventRead|EventOneShot).

func HandleReadWrite

func HandleReadWrite(conn net.Conn) (*Desc, error)

HandleReadWrite creates read and write descriptor for further use in EventPoll methods. It is the same as Handle(conn, EventRead|EventWrite|EventEdgeTriggered).

func HandleWrite

func HandleWrite(conn net.Conn) (*Desc, error)

HandleWrite creates write descriptor for further use in EventPoll methods. It is the same as Handle(conn, EventWrite|EventEdgeTriggered).

func HandleWriteOnce

func HandleWriteOnce(conn net.Conn) (*Desc, error)

HandleWriteOnce creates write descriptor for further use in EventPoll methods. It is the same as Handle(conn, EventWrite|EventOneShot).

func Must

func Must(desc *Desc, err error) *Desc

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 NewDesc

func NewDesc(fd uintptr, ev Event) (*Desc, error)

NewDesc creates descriptor from custom fd.

func (*Desc) Close

func (h *Desc) Close() error

Close closes underlying file.

func (*Desc) Fd

func (h *Desc) Fd() int

Fd returns the underlying file descriptor

type Event

type Event uint16

Event represents netpoll configuration bit mask.

const (
	EventRead  Event = 0x1
	EventWrite       = 0x2
)

Event values that denote the type of events that caller want to receive.

const (
	EventOneShot       Event = 0x4
	EventEdgeTriggered       = 0x8
)

Event values that configure the EventPoll's behavior.

func (Event) String

func (ev Event) String() (str string)

String returns a string representation of Event.

type EventPoll

type EventPoll 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
}

EventPoll describes an object that implements logic of polling connections for i/o events such as availability of read() or write() operations.

func New

func New(c *Config) (EventPoll, error)

New creates new kqueue-based EventPoll instance with given config.

type KEvent

type KEvent struct {
	Filter KeventFilter
	Flags  KeventFlag
	Fflags uint32
	Data   int64
}

KEvent represents kevent.

type KEventHandler

type KEventHandler func(KEvent)

KEventHandler is a function that will be called when event occures on registered identifier.

type KEvents

type KEvents [8]KEvent

KEvents is a fixed number of pairs of event filter and flags which can be registered for an identifier.

type KQueue

type KQueue struct {
	// contains filtered or unexported fields
}

KQueue represents kqueue instance.

func KQueueCreate

func KQueueCreate(c *KQueueConfig) (*KQueue, error)

KQueueCreate creates new kqueue instance. It starts wait loop in a separate goroutine.

func (*KQueue) Add

func (k *KQueue) Add(fd int, events KEvents, n int, cb KEventHandler) error

Add adds a event handler for identifier fd with given n events.

func (*KQueue) Close

func (k *KQueue) Close() error

Close closes kqueue instance. NOTE: not implemented yet.

func (*KQueue) Del

func (k *KQueue) Del(fd int) error

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 (*KQueue) Mod

func (k *KQueue) Mod(fd int, events KEvents, n int) error

Mod modifies events registered for fd.

type KQueueConfig

type KQueueConfig struct {
	// OnWaitError will be called from goroutine, waiting for events.
	OnWaitError func(error)
}

KQueueConfig contains options for configuration kqueue instance.

type KeventFilter

type KeventFilter int

KeventFilter is a kqueue event filter.

func (KeventFilter) String

func (filter KeventFilter) String() (str string)

String returns string representation of a filter.

type KeventFlag

type KeventFlag int

KeventFlag represents kqueue event flag.

func (KeventFlag) String

func (flag KeventFlag) String() (str string)

String returns string representation of flag bits of the form "EV_A|EV_B|...".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL