func (q *Queue) IsEmpty() bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	return q.list.Front() == nil
}
IsEmpty returns if the wait queue is empty or not.
package waiter
import (
	"sync"
	"github.com/brewlin/net-protocol/pkg/ilist"
)
type EventMask uint16
const (
	EventIn   EventMask = 0x01  
	EventPri  EventMask = 0x02  
	EventOut  EventMask = 0x04  
	EventErr  EventMask = 0x08  
	EventHUp  EventMask = 0x10  
	EventNVal EventMask = 0x20  
)
type Waitable interface {
	Readiness(mask EventMask) EventMask
	EventRegister(e *Entry, mask EventMask)
	EventUnregister(e *Entry)
}
type EntryCallback interface {
	Callback(e *Entry)
}
type Entry struct {
	Context interface{}
	Callback EntryCallback
	mask EventMask
	ilist.Entry
}
type channelCallback struct{}
func (*channelCallback) Callback(e *Entry) {
	ch := e.Context.(chan struct{})
	select {
	case ch <- struct{}{}:
	default:
	}
}
func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) {
	if c == nil {
		c = make(chan struct{}, 1)
	}
	return Entry{Context: c, Callback: &channelCallback{}}, c
}
type Queue struct {
	list ilist.List
	mu   sync.RWMutex
}
func (q *Queue) EventRegister(e *Entry, mask EventMask) {
	q.mu.Lock()
	e.mask = mask
	q.list.PushBack(e)
	q.mu.Unlock()
}
func (q *Queue) EventUnregister(e *Entry) {
	q.mu.Lock()
	q.list.Remove(e)
	q.mu.Unlock()
}
func (q *Queue) Notify(mask EventMask) {
	q.mu.RLock()
	for it := q.list.Front(); it != nil; it = it.Next() {
		e := it.(*Entry)
		if mask&e.mask != 0 {
			e.Callback.Callback(e)
		}
	}
	q.mu.RUnlock()
}
func (q *Queue) Events() EventMask {
	ret := EventMask(0)
	q.mu.RLock()
	for it := q.list.Front(); it != nil; it = it.Next() {
		e := it.(*Entry)
		ret |= e.mask
	}
	q.mu.RUnlock()
	return ret
}