Documentation
¶
Overview ¶
Package waiter provides the implementation of a wallet queue, where waiters can be enqueued to be notified when an event of interest happends.
Becoming readable and/or writable are examples of events. Waiters are expected to use a pattern similar to this to make a blocking function out of a non-blocking one:
func (o *object) blockingRead(...) error {
err := o.nonblockingRead(...)
if err != ErrAgain {
// Completed with no need to wait!
return err
}
e := createOrGetWaiterEntry(...)
o.EventRegister(&e, waiter.EventIn)
defer o.EventUnregister(&e)
// We need to try to read again after registration because the
// object may have become readable between the last attempt to
// read and read registration.
err := o.nonblockingRead(...)
if err == ErrAgain {
wait()
err = o.nonblockingRead(...)
}
return err
} Another goroutine needs to notify waiters when events happen. For example:
func(o *object) Write(...) ... {
// Do write work.
[...]
if oldDataAvailableSize == 0 && dataAvailableSize > 0 {
// If no data was available and now some data is
// available, the object became readable, so notify
// potential waiters about this
o.Notify(waiter.EventIn)
}
}
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AlwaysReady ¶
type AlwaysReady struct{}
AlwaysReady implements the Waitable interface but is always ready. Embedding this struct into another struct makes it implement the boilerplate empty functions automatically.
func (*AlwaysReady) EventRegister ¶
func (*AlwaysReady) EventRegister(*Entry, EventMask)
EventRegister doesn't do anything because this object doesn't need to issue notifications because its readiness never changes.
func (*AlwaysReady) EventUnregister ¶
func (*AlwaysReady) EventUnregister(*Entry)
EventUnregister doesn't do anything because this object doesn't need to issue notifications because its Readiness never changes.
func (*AlwaysReady) Readiness ¶
func (*AlwaysReady) Readiness(mask EventMask) EventMask
Readiness always returns the input mask because this project is always ready.
type Entry ¶
type Entry struct {
// Context stores any state the waiter may wish to store in the entry
// itself, which can be used at wake up time.
Context interface{}
// Callback is the function to be called when the waiter entry is
// notified. It is responsible for doing whatever is needed to wake up
// the waiter.
//
// The callback is supposed to perform minimum work, and cannot call
// any method on the queue itself because it will be locked while the callback
// is running
Callback func(e *Entry)
ilist.Entry
// contains filtered or unexported fields
}
Entry represents a waiter that can be added to a waiter queue. It can only be in at one queue at a time, and is added "intrusively" to the queue with no extra memory allocations.
func NewChannelEntry ¶
func NewChannelEntry(c chan interface{}) (Entry, chan interface{})
NewChannelEntry initializes a new Entry that does a non-blocking write of nil to an interface{} channel when the callback is called. It returns the new Entry instance and the channeld being used.
If a channel isn't specified (i.e., if "c" is nil), then NewChannelEntry allocates a new channel.
type EventMask ¶
type EventMask uint16
EventMask represents io events as used in the poll() syscall.
const ( EventIn EventMask = syscall.EPOLLIN EventPri EventMask = syscall.EPOLLPRI EventOut EventMask = syscall.EPOLLOUT EventErr EventMask = syscall.EPOLLERR EventHup EventMask = syscall.EPOLLHUP EventNVal EventMask = 0x20 // Not defined in syscall. )
Events that waiters can wait on. The meaning is the same as those in the poll() syscall.
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue represents the wait queue where waiters can be added and notifiers can notify them when evnets happen.
The zero value for waiter.Queue is an empty queue reaqdy for use.
func (*Queue) EventRegister ¶
EventRegister adds a waiter to the waiter queue; the waiter will be notified when at least one of the events specified in mask happens.
func (*Queue) EventUnregister ¶
EventUnregister removes the given waiter entry from the waiter queue.
func (*Queue) Events ¶
Events returns the set of events being waited on. It is the union of the masks of all registered entries.
type Waitable ¶
type Waitable interface {
// Readiness returns what the object is currently ready for. If it's
// not ready for a desired purpose, the caller may use EventRegister and
// EventUnregister to get notifications once the object becomes ready.
Readiness(mask EventMask) EventMask
// EventRegister registers the given waiter entry to receive
// notifications when an event occurs that makes the object ready for
// at least one of the events in mask.
EventRegister(e *Entry, mask EventMask)
// EventUnregister unregisters a waiter entry previously registered with
// EventRegister
EventUnregister(e *Entry)
}
Waitable contains the methods that need to be implemented by waitable objects.