func (g *Gopher) AfterRead(h func(c *Conn)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.afterRead = h
}
AfterRead registers callback after syscall.Read
the handler would be called on *nix.
package nbio
import (
	"container/heap"
	"net"
	"runtime"
	"sync"
	"time"
	"unsafe"
	"github.com/lesismal/nbio/logging"
)
const (
	DefaultReadBufferSize = 1024 * 32
	DefaultMaxWriteBufferSize = 1024 * 1024
	DefaultMaxReadTimesPerEventLoop = 3
	DefaultMinConnCacheSize = 1024 * 2
)
var (
	MaxOpenFiles = 1024 * 1024
)
type Config struct {
	Name string
	Network string
	Addrs []string
	NPoller int
	NListener int
	Backlog int
	ReadBufferSize int
	MinConnCacheSize int
	MaxWriteBufferSize int
	MaxReadTimesPerEventLoop int
	LockListener bool
	LockPoller bool
	EpollMod int
}
type Gopher struct {
	sync.WaitGroup
	mux  sync.Mutex
	tmux sync.Mutex
	Name string
	network                  string
	addrs                    []string
	pollerNum                int
	backlogSize              int
	readBufferSize           int
	maxWriteBufferSize       int
	maxReadTimesPerEventLoop int
	minConnCacheSize         int
	epollMod                 int
	lockListener             bool
	lockPoller               bool
	lfds []int
	connsStd  map[*Conn]struct{}
	connsUnix []*Conn
	listeners []*poller
	pollers   []*poller
	onOpen            func(c *Conn)
	onClose           func(c *Conn, err error)
	onRead            func(c *Conn)
	onData            func(c *Conn, data []byte)
	onReadBufferAlloc func(c *Conn) []byte
	onReadBufferFree  func(c *Conn, buffer []byte)
	onWriteBufferFree func(c *Conn, buffer []byte)
	beforeRead        func(c *Conn)
	afterRead         func(c *Conn)
	beforeWrite       func(c *Conn)
	onStop            func()
	callings  []func()
	chCalling chan struct{}
	timers    timerHeap
	trigger   *time.Timer
	chTimer   chan struct{}
	Execute func(f func())
}
func (g *Gopher) Stop() {
	g.onStop()
	g.trigger.Stop()
	close(g.chTimer)
	for _, l := range g.listeners {
		l.stop()
	}
	for i := 0; i < g.pollerNum; i++ {
		g.pollers[i].stop()
	}
	g.mux.Lock()
	conns := g.connsStd
	g.connsStd = map[*Conn]struct{}{}
	connsUnix := g.connsUnix
	g.mux.Unlock()
	for c := range conns {
		if c != nil {
			c.Close()
		}
	}
	for _, c := range connsUnix {
		if c != nil {
			go c.Close()
		}
	}
	g.Wait()
	logging.Info("Gopher[%v] stop", g.Name)
}
func (g *Gopher) AddConn(conn net.Conn) (*Conn, error) {
	c, err := NBConn(conn)
	if err != nil {
		return nil, err
	}
	g.pollers[uint32(c.Hash())%uint32(g.pollerNum)].addConn(c)
	return c, nil
}
func (g *Gopher) OnOpen(h func(c *Conn)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onOpen = h
}
func (g *Gopher) OnClose(h func(c *Conn, err error)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onClose = func(c *Conn, err error) {
		g.atOnce(func() {
			h(c, err)
		})
	}
}
func (g *Gopher) OnRead(h func(c *Conn)) {
	g.onRead = h
}
func (g *Gopher) OnData(h func(c *Conn, data []byte)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onData = h
}
func (g *Gopher) OnReadBufferAlloc(h func(c *Conn) []byte) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onReadBufferAlloc = h
}
func (g *Gopher) OnReadBufferFree(h func(c *Conn, b []byte)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onReadBufferFree = h
}
func (g *Gopher) OnWriteBufferRelease(h func(c *Conn, b []byte)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.onWriteBufferFree = h
}
func (g *Gopher) BeforeRead(h func(c *Conn)) {
	if h == nil {
		panic("invalid nil handler")
	}
	g.beforeRead = h
}