Skip to content

Commit

Permalink
support closed event
Browse files Browse the repository at this point in the history
  • Loading branch information
cheng-zhongliang committed Jul 29, 2023
1 parent dcb48a3 commit 112aa4a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 31 deletions.
79 changes: 49 additions & 30 deletions epoll.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type FdEvent struct {
R *Event
// W is the write event.
W *Event
// C is the close event.
C *Event
}

// Epoll is the epoll poller implementation.
Expand Down Expand Up @@ -77,27 +79,32 @@ func (ep *Epoll) Add(ev *Event) error {
es, ok := ep.FdEvs[ev.Fd]
if ok {
op = syscall.EPOLL_CTL_MOD
if es.R != nil {
epEv.Events |= syscall.EPOLLIN
}
if es.W != nil {
epEv.Events |= syscall.EPOLLOUT
}
} else {
es = &FdEvent{}
ep.FdEvs[ev.Fd] = es
}

*(**FdEvent)(unsafe.Pointer(&epEv.Fd)) = es

if ev.Events&EvRead != 0 {
epEv.Events |= syscall.EPOLLIN
es.R = ev
}
if ev.Events&EvWrite != 0 {
epEv.Events |= syscall.EPOLLOUT
es.W = ev
}
if ev.Events&EvClosed != 0 {
es.C = ev
}

if es.R != nil {
epEv.Events |= syscall.EPOLLIN
}
if es.W != nil {
epEv.Events |= syscall.EPOLLOUT
}
if es.C != nil {
epEv.Events |= syscall.EPOLLRDHUP
}

*(**FdEvent)(unsafe.Pointer(&epEv.Fd)) = es

return syscall.EpollCtl(ep.Fd, op, ev.Fd, epEv)
}
Expand All @@ -112,36 +119,39 @@ func (ep *Epoll) Del(ev *Event) error {
return nil
}

epEv := &syscall.EpollEvent{}
op := syscall.EPOLL_CTL_DEL
es := ep.FdEvs[ev.Fd]

if ev.Events&EvRead != 0 {
epEv.Events |= syscall.EPOLLIN
es.R = nil
}
if ev.Events&EvWrite != 0 {
epEv.Events |= syscall.EPOLLOUT
es.W = nil
}
if ev.Events&EvClosed != 0 {
es.C = nil
}

es := ep.FdEvs[ev.Fd]

*(**FdEvent)(unsafe.Pointer(&epEv.Fd)) = es
epEv := &syscall.EpollEvent{}
op := syscall.EPOLL_CTL_DEL

if epEv.Events&(syscall.EPOLLIN|syscall.EPOLLOUT) != (syscall.EPOLLIN | syscall.EPOLLOUT) {
if epEv.Events&syscall.EPOLLIN != 0 && ep.FdEvs[ev.Fd].W != nil {
op = syscall.EPOLL_CTL_MOD
epEv.Events = syscall.EPOLLOUT
ep.FdEvs[ev.Fd].R = nil
} else if epEv.Events&syscall.EPOLLOUT != 0 && ep.FdEvs[ev.Fd].R != nil {
op = syscall.EPOLL_CTL_MOD
epEv.Events = syscall.EPOLLIN
ep.FdEvs[ev.Fd].W = nil
}
if es.R != nil {
epEv.Events |= syscall.EPOLLIN
}
if es.W != nil {
epEv.Events |= syscall.EPOLLOUT
}
if es.C != nil {
epEv.Events |= syscall.EPOLLRDHUP
}

if op == syscall.EPOLL_CTL_DEL {
if epEv.Events == 0 {
delete(ep.FdEvs, ev.Fd)
} else {
op = syscall.EPOLL_CTL_MOD
}

*(**FdEvent)(unsafe.Pointer(&epEv.Fd)) = es

return syscall.EpollCtl(ep.Fd, op, ev.Fd, epEv)
}

Expand All @@ -160,11 +170,14 @@ func (ep *Epoll) Polling(cb func(ev *Event, res uint32), timeout int) error {
continue
}

var evRead, evWrite *Event
var evRead, evWrite, evClosed *Event
what := ep.EpollEvs[i].Events
es := *(**FdEvent)(unsafe.Pointer(&ep.EpollEvs[i].Fd))

if what&(syscall.EPOLLERR|syscall.EPOLLHUP) != 0 {
if what&syscall.EPOLLERR != 0 {
evRead = es.R
evWrite = es.W
} else if what&syscall.EPOLLHUP != 0 && what&syscall.EPOLLRDHUP == 0 {
evRead = es.R
evWrite = es.W
} else {
Expand All @@ -174,6 +187,9 @@ func (ep *Epoll) Polling(cb func(ev *Event, res uint32), timeout int) error {
if what&syscall.EPOLLOUT != 0 {
evWrite = es.W
}
if what&syscall.EPOLLRDHUP != 0 {
evClosed = es.C
}
}

if evRead != nil {
Expand All @@ -182,6 +198,9 @@ func (ep *Epoll) Polling(cb func(ev *Event, res uint32), timeout int) error {
if evWrite != nil {
cb(evWrite, EvWrite)
}
if evClosed != nil {
cb(evClosed, EvClosed)
}
}

return nil
Expand Down
2 changes: 2 additions & 0 deletions event.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const (
EvTimeout = 1 << iota
// EvSignal is signal event.
EvSignal = 1 << iota
// EvClosed is closed event.
EvClosed = 1 << iota

// EvPersist is persistent event.
EvPersist = 0x10
Expand Down
2 changes: 1 addition & 1 deletion signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type SignalPoller struct {
}

// NewSignalPoller creates a new signal poller.
func NewSignalPoller(cb func(Signal int)) *SignalPoller {
func NewSignalPoller(cb func(signal int)) *SignalPoller {
sp := &SignalPoller{
Feedback: cb,
SignalCh: make(chan os.Signal, 1),
Expand Down

0 comments on commit 112aa4a

Please sign in to comment.