diff --git a/reactor_epoll_default.go b/reactor_default.go similarity index 68% rename from reactor_epoll_default.go rename to reactor_default.go index 4f150e6ec..a8935c879 100644 --- a/reactor_epoll_default.go +++ b/reactor_default.go @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build linux && !poll_opt -// +build linux,!poll_opt +//go:build (linux || freebsd || dragonfly || netbsd || openbsd || darwin) && !poll_opt +// +build linux freebsd dragonfly netbsd openbsd darwin +// +build !poll_opt package gnet @@ -53,8 +54,13 @@ func (el *eventloop) orbit() error { err := el.poller.Polling(func(fd int, ev netpoll.IOEvent, flags netpoll.IOFlags) error { c := el.connections.getConn(fd) if c == nil { - // Somehow epoll notified with an event for a stale fd that is not in our connection set. - // We need to delete it from the epoll set. + // For kqueue, this might happen when the connection has already been closed, + // the file descriptor will be deleted from kqueue automatically as documented + // in the manual pages. + // For epoll, it somehow notified with an event for a stale fd that is not in + // our connection set. We need to explicitly delete it from the epoll set. + // Also print a warning log for this kind of irregularity. + el.getLogger().Warnf("received event[fd=%d|ev=%d|flags=%d] of a stale connection from event-loop(%d)", fd, ev, flags, el.idx) return el.poller.Delete(fd) } return c.processIO(fd, ev, flags) @@ -84,8 +90,13 @@ func (el *eventloop) run() error { if _, ok := el.listeners[fd]; ok { return el.accept(fd, ev, flags) } - // Somehow epoll notified with an event for a stale fd that is not in our connection set. - // We need to delete it from the epoll set. + // For kqueue, this might happen when the connection has already been closed, + // the file descriptor will be deleted from kqueue automatically as documented + // in the manual pages. + // For epoll, it somehow notified with an event for a stale fd that is not in + // our connection set. We need to explicitly delete it from the epoll set. + // Also print a warning log for this kind of irregularity. + el.getLogger().Warnf("received event[fd=%d|ev=%d|flags=%d] of a stale connection from event-loop(%d)", fd, ev, flags, el.idx) return el.poller.Delete(fd) } return c.processIO(fd, ev, flags) diff --git a/reactor_epoll_ultimate.go b/reactor_epoll_ultimate.go deleted file mode 100644 index 2fd3dd693..000000000 --- a/reactor_epoll_ultimate.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2021 The Gnet Authors. All rights reserved. -// -// 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 linux && poll_opt -// +build linux,poll_opt - -package gnet - -import ( - "errors" - "runtime" - - errorx "github.com/panjf2000/gnet/v2/pkg/errors" -) - -func (el *eventloop) rotate() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling() - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("main reactor is exiting in terms of the demand from user, %v", err) - err = nil - } else if err != nil { - el.getLogger().Errorf("main reactor is exiting due to error: %v", err) - } - - el.engine.shutdown(err) - - return err -} - -func (el *eventloop) orbit() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling() - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("event-loop(%d) is exiting in terms of the demand from user, %v", el.idx, err) - err = nil - } else if err != nil { - el.getLogger().Errorf("event-loop(%d) is exiting due to error: %v", el.idx, err) - } - - el.closeConns() - el.engine.shutdown(err) - - return err -} - -func (el *eventloop) run() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling() - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("event-loop(%d) is exiting in terms of the demand from user, %v", el.idx, err) - err = nil - } else if err != nil { - el.getLogger().Errorf("event-loop(%d) is exiting due to error: %v", el.idx, err) - } - - el.closeConns() - el.engine.shutdown(err) - - return err -} diff --git a/reactor_kqueue_default.go b/reactor_kqueue_default.go deleted file mode 100644 index 7426c74e0..000000000 --- a/reactor_kqueue_default.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2019 The Gnet Authors. All rights reserved. -// -// 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 (freebsd || dragonfly || netbsd || openbsd || darwin) && !poll_opt -// +build freebsd dragonfly netbsd openbsd darwin -// +build !poll_opt - -package gnet - -import ( - "errors" - "runtime" - - "github.com/panjf2000/gnet/v2/internal/netpoll" - errorx "github.com/panjf2000/gnet/v2/pkg/errors" -) - -func (el *eventloop) rotate() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling(el.accept0) - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("main reactor is exiting in terms of the demand from user, %v", err) - err = nil - } else if err != nil { - el.getLogger().Errorf("main reactor is exiting due to error: %v", err) - } - - el.engine.shutdown(err) - - return err -} - -func (el *eventloop) orbit() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling(func(fd int, filter netpoll.IOEvent, flags netpoll.IOFlags) error { - c := el.connections.getConn(fd) - if c == nil { - // This might happen when the connection has already been closed, - // the file descriptor will be deleted from kqueue automatically - // as documented in the manual pages, So we just print a warning log. - el.getLogger().Warnf("received event[fd=%d|filter=%d|flags=%d] of a stale connection from event-loop(%d)", fd, filter, flags, el.idx) - return nil - } - return c.processIO(fd, filter, flags) - }) - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("event-loop(%d) is exiting in terms of the demand from user, %v", el.idx, err) - err = nil - } else if err != nil { - el.getLogger().Errorf("event-loop(%d) is exiting due to error: %v", el.idx, err) - } - - el.closeConns() - el.engine.shutdown(err) - - return err -} - -func (el *eventloop) run() error { - if el.engine.opts.LockOSThread { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - } - - err := el.poller.Polling(func(fd int, filter netpoll.IOEvent, flags netpoll.IOFlags) error { - c := el.connections.getConn(fd) - if c == nil { - if _, ok := el.listeners[fd]; ok { - return el.accept(fd, filter, flags) - } - // This might happen when the connection has already been closed, - // the file descriptor will be deleted from kqueue automatically - // as documented in the manual pages, So we just print a warning log. - el.getLogger().Warnf("received event[fd=%d|filter=%d|flags=%d] of a stale connection from event-loop(%d)", fd, filter, flags, el.idx) - return nil - } - return c.processIO(fd, filter, flags) - }) - if errors.Is(err, errorx.ErrEngineShutdown) { - el.getLogger().Debugf("event-loop(%d) is exiting in terms of the demand from user, %v", el.idx, err) - err = nil - } else if err != nil { - el.getLogger().Errorf("event-loop(%d) is exiting due to error: %v", el.idx, err) - } - - el.closeConns() - el.engine.shutdown(err) - - return err -} diff --git a/reactor_kqueue_ultimate.go b/reactor_ultimate.go similarity index 93% rename from reactor_kqueue_ultimate.go rename to reactor_ultimate.go index 93b998625..08ab1c8c6 100644 --- a/reactor_kqueue_ultimate.go +++ b/reactor_ultimate.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build (freebsd || dragonfly || netbsd || openbsd || darwin) && poll_opt -// +build freebsd dragonfly netbsd openbsd darwin +//go:build (linux || freebsd || dragonfly || netbsd || openbsd || darwin) && poll_opt +// +build linux freebsd dragonfly netbsd openbsd darwin // +build poll_opt package gnet