From 363b2e8f4250886aa37d73a99b2143d94f36b090 Mon Sep 17 00:00:00 2001 From: wangzhuowei Date: Tue, 23 Jul 2024 11:25:50 +0800 Subject: [PATCH] fix: support windows compiler --- netpoll.go | 89 ----------------- netpoll_config.go | 45 +++++++++ netpoll_options.go => netpoll_unix.go | 122 ++++++++++++++++-------- netpoll_test.go => netpoll_unix_test.go | 0 netpoll_windows.go | 5 + 5 files changed, 134 insertions(+), 127 deletions(-) delete mode 100644 netpoll.go create mode 100644 netpoll_config.go rename netpoll_options.go => netpoll_unix.go (78%) rename netpoll_test.go => netpoll_unix_test.go (100%) diff --git a/netpoll.go b/netpoll.go deleted file mode 100644 index 7f53f2a2..00000000 --- a/netpoll.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2022 CloudWeGo Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build darwin || netbsd || freebsd || openbsd || dragonfly || linux -// +build darwin netbsd freebsd openbsd dragonfly linux - -package netpoll - -import ( - "context" - "net" - "runtime" - "sync" -) - -// NewEventLoop . -func NewEventLoop(onRequest OnRequest, ops ...Option) (EventLoop, error) { - opts := &options{ - onRequest: onRequest, - } - for _, do := range ops { - do.f(opts) - } - return &eventLoop{ - opts: opts, - stop: make(chan error, 1), - }, nil -} - -type eventLoop struct { - sync.Mutex - opts *options - svr *server - stop chan error -} - -// Serve implements EventLoop. -func (evl *eventLoop) Serve(ln net.Listener) error { - npln, err := ConvertListener(ln) - if err != nil { - return err - } - evl.Lock() - evl.svr = newServer(npln, evl.opts, evl.quit) - evl.svr.Run() - evl.Unlock() - - err = evl.waitQuit() - // ensure evl will not be finalized until Serve returns - runtime.SetFinalizer(evl, nil) - return err -} - -// Shutdown signals a shutdown a begins server closing. -func (evl *eventLoop) Shutdown(ctx context.Context) error { - evl.Lock() - var svr = evl.svr - evl.svr = nil - evl.Unlock() - - if svr == nil { - return nil - } - evl.quit(nil) - return svr.Close(ctx) -} - -// waitQuit waits for a quit signal -func (evl *eventLoop) waitQuit() error { - return <-evl.stop -} - -func (evl *eventLoop) quit(err error) { - select { - case evl.stop <- err: - default: - } -} diff --git a/netpoll_config.go b/netpoll_config.go new file mode 100644 index 00000000..3ac8ccee --- /dev/null +++ b/netpoll_config.go @@ -0,0 +1,45 @@ +// Copyright 2022 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package netpoll + +import ( + "context" + "io" +) + +// global config +var ( + defaultLinkBufferSize = pagesize + featureAlwaysNoCopyRead = false +) + +// Config expose some tuning parameters to control the internal behaviors of netpoll. +// Every parameter with the default zero value should keep the default behavior of netpoll. +type Config struct { + PollerNum int // number of pollers + BufferSize int // default size of a new connection's LinkBuffer + Runner func(ctx context.Context, f func()) // runner for event handler, most of the time use a goroutine pool. + LoggerOutput io.Writer // logger output + LoadBalance LoadBalance // load balance for poller picker + Feature // define all features that not enable by default +} + +// Feature expose some new features maybe promoted as a default behavior but not yet. +type Feature struct { + // AlwaysNoCopyRead allows some copy Read functions like ReadBinary/ReadString + // will use NoCopy read and will not reuse the underlying buffer. + // It gains more performance benefits when need read much big string/bytes in codec. + AlwaysNoCopyRead bool +} diff --git a/netpoll_options.go b/netpoll_unix.go similarity index 78% rename from netpoll_options.go rename to netpoll_unix.go index 7b225256..cc69b402 100644 --- a/netpoll_options.go +++ b/netpoll_unix.go @@ -12,43 +12,47 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build darwin || netbsd || freebsd || openbsd || dragonfly || linux +// +build darwin netbsd freebsd openbsd dragonfly linux + package netpoll import ( "context" "io" "log" + "net" "os" "runtime" + "sync" "time" ) var ( pollmanager = newManager(runtime.GOMAXPROCS(0)/20 + 1) // pollmanager manage all pollers logger = log.New(os.Stderr, "", log.LstdFlags) - - // global config - defaultLinkBufferSize = pagesize - featureAlwaysNoCopyRead = false ) -// Config expose some tuning parameters to control the internal behaviors of netpoll. -// Every parameter with the default zero value should keep the default behavior of netpoll. -type Config struct { - PollerNum int // number of pollers - BufferSize int // default size of a new connection's LinkBuffer - Runner func(ctx context.Context, f func()) // runner for event handler, most of the time use a goroutine pool. - LoggerOutput io.Writer // logger output - LoadBalance LoadBalance // load balance for poller picker - Feature // define all features that not enable by default +// Option . +type Option struct { + f func(*options) } -// Feature expose some new features maybe promoted as a default behavior but not yet. -type Feature struct { - // AlwaysNoCopyRead allows some copy Read functions like ReadBinary/ReadString - // will use NoCopy read and will not reuse the underlying buffer. - // It gains more performance benefits when need read much big string/bytes in codec. - AlwaysNoCopyRead bool +type options struct { + onPrepare OnPrepare + onConnect OnConnect + onDisconnect OnDisconnect + onRequest OnRequest + readTimeout time.Duration + writeTimeout time.Duration + idleTimeout time.Duration +} + +// Initialize the pollers actively. By default, it's lazy initialized. +// It's safe to call it multi times. +func Initialize() { + // The first call of Pick() will init pollers + _ = pollmanager.Pick() } // Configure the internal behaviors of netpoll. @@ -79,17 +83,10 @@ func Configure(config Config) (err error) { return nil } -// Initialize the pollers actively. By default, it's lazy initialized. -// It's safe to call it multi times. -func Initialize() { - // The first call of Pick() will init pollers - _ = pollmanager.Pick() -} - // SetNumLoops is used to set the number of pollers, generally do not need to actively set. // By default, the number of pollers is equal to runtime.GOMAXPROCS(0)/20+1. // If the number of cores in your service process is less than 20c, theoretically only one poller is needed. -// Otherwise you may need to adjust the number of pollers to achieve the best results. +// Otherwise, you may need to adjust the number of pollers to achieve the best results. // Experience recommends assigning a poller every 20c. // // You can only use SetNumLoops before any connection is created. An example usage: @@ -175,17 +172,66 @@ func WithIdleTimeout(timeout time.Duration) Option { }} } -// Option . -type Option struct { - f func(*options) +// NewEventLoop . +func NewEventLoop(onRequest OnRequest, ops ...Option) (EventLoop, error) { + opts := &options{ + onRequest: onRequest, + } + for _, do := range ops { + do.f(opts) + } + return &eventLoop{ + opts: opts, + stop: make(chan error, 1), + }, nil } -type options struct { - onPrepare OnPrepare - onConnect OnConnect - onDisconnect OnDisconnect - onRequest OnRequest - readTimeout time.Duration - writeTimeout time.Duration - idleTimeout time.Duration +type eventLoop struct { + sync.Mutex + opts *options + svr *server + stop chan error +} + +// Serve implements EventLoop. +func (evl *eventLoop) Serve(ln net.Listener) error { + npln, err := ConvertListener(ln) + if err != nil { + return err + } + evl.Lock() + evl.svr = newServer(npln, evl.opts, evl.quit) + evl.svr.Run() + evl.Unlock() + + err = evl.waitQuit() + // ensure evl will not be finalized until Serve returns + runtime.SetFinalizer(evl, nil) + return err +} + +// Shutdown signals a shutdown a begins server closing. +func (evl *eventLoop) Shutdown(ctx context.Context) error { + evl.Lock() + var svr = evl.svr + evl.svr = nil + evl.Unlock() + + if svr == nil { + return nil + } + evl.quit(nil) + return svr.Close(ctx) +} + +// waitQuit waits for a quit signal +func (evl *eventLoop) waitQuit() error { + return <-evl.stop +} + +func (evl *eventLoop) quit(err error) { + select { + case evl.stop <- err: + default: + } } diff --git a/netpoll_test.go b/netpoll_unix_test.go similarity index 100% rename from netpoll_test.go rename to netpoll_unix_test.go diff --git a/netpoll_windows.go b/netpoll_windows.go index 634d1ef9..4f50e078 100644 --- a/netpoll_windows.go +++ b/netpoll_windows.go @@ -23,6 +23,11 @@ import ( "time" ) +// Configure the internal behaviors of netpoll. +func Configure(config Config) (err error) { + return nil +} + // Option . type Option struct { f func(*options)