2021-12-04 16:42:11 +00:00

123 lines
2.9 KiB
Go

// Copyright 2020 lesismal. All rights reserved.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build linux || darwin || netbsd || freebsd || openbsd || dragonfly
// +build linux darwin netbsd freebsd openbsd dragonfly
package nbio
import (
"runtime"
"strings"
"syscall"
"time"
"github.com/lesismal/nbio/logging"
)
// Start init and start pollers.
func (g *Gopher) Start() error {
var err error
for i := 0; i < len(g.addrs); i++ {
g.listeners[i], err = newPoller(g, true, i)
if err != nil {
for j := 0; j < i; j++ {
g.listeners[j].stop()
}
return err
}
}
for i := 0; i < g.pollerNum; i++ {
g.pollers[i], err = newPoller(g, false, i)
if err != nil {
for j := 0; j < len(g.lfds); j++ {
syscall.Close(g.lfds[j])
}
for j := 0; j < len(g.listeners); j++ {
g.listeners[j].stop()
}
for j := 0; j < i; j++ {
g.pollers[j].stop()
}
return err
}
}
for i := 0; i < g.pollerNum; i++ {
g.pollers[i].ReadBuffer = make([]byte, g.readBufferSize)
g.Add(1)
go g.pollers[i].start()
}
for _, l := range g.listeners {
g.Add(1)
go l.start()
}
g.Add(1)
go g.timerLoop()
if len(g.addrs) == 0 {
logging.Info("Gopher[%v] start", g.Name)
} else {
logging.Info("Gopher[%v] start listen on: [\"%v\"]", g.Name, strings.Join(g.addrs, `", "`))
}
return nil
}
// NewGopher is a factory impl.
func NewGopher(conf Config) *Gopher {
cpuNum := runtime.NumCPU()
if conf.Name == "" {
conf.Name = "NB"
}
if conf.NPoller <= 0 {
conf.NPoller = cpuNum
}
if len(conf.Addrs) > 0 && conf.NListener <= 0 {
conf.NListener = 1
}
if conf.Backlog <= 0 {
conf.Backlog = 1024 * 64
}
if conf.ReadBufferSize <= 0 {
conf.ReadBufferSize = DefaultReadBufferSize
}
if conf.MinConnCacheSize == 0 {
conf.MinConnCacheSize = DefaultMinConnCacheSize
}
if conf.MaxReadTimesPerEventLoop <= 0 {
conf.MaxReadTimesPerEventLoop = DefaultMaxReadTimesPerEventLoop
}
g := &Gopher{
Name: conf.Name,
network: conf.Network,
addrs: conf.Addrs,
pollerNum: conf.NPoller,
backlogSize: conf.Backlog,
readBufferSize: conf.ReadBufferSize,
maxWriteBufferSize: conf.MaxWriteBufferSize,
maxReadTimesPerEventLoop: conf.MaxReadTimesPerEventLoop,
minConnCacheSize: conf.MinConnCacheSize,
epollMod: conf.EpollMod,
lockListener: conf.LockListener,
lockPoller: conf.LockPoller,
listeners: make([]*poller, len(conf.Addrs)),
pollers: make([]*poller, conf.NPoller),
connsUnix: make([]*Conn, MaxOpenFiles),
callings: []func(){},
chCalling: make(chan struct{}, 1),
trigger: time.NewTimer(timeForever),
chTimer: make(chan struct{}),
}
g.initHandlers()
return g
}