/
epool_unix.go
121 lines (106 loc) · 2.61 KB
/
epool_unix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2021 XinRui Hua. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package engine
// +build darwin netbsd freebsd openbsd dragonfly
import (
"syscall"
"github.com/huaxr/rx/logger"
)
type PollIF interface {
ChangeRW(fd int)
ChangeDetach(fd int)
ChangeRead(fd int)
AddRW(fd int)
AddRead(fd int)
Looping(execute func(fd int) error)
Close() error
Trigger(note interface{}) error
}
type poll struct {
srvFd int
changes []syscall.Kevent_t
}
func newPoll() PollIF {
pl := new(poll)
p, err := syscall.Kqueue()
if err != nil {
panic(err)
}
pl.srvFd = p
_, err = syscall.Kevent(pl.srvFd, []syscall.Kevent_t{{
Ident: 0,
Filter: syscall.EVFILT_USER,
Flags: syscall.EV_ADD | syscall.EV_CLEAR,
}}, nil, nil)
if err != nil {
panic(err)
}
return pl
}
func (p *poll) ChangeRW(fd int) {
p.changes = append(p.changes, syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_ADD, Filter: syscall.EVFILT_WRITE,
})
}
func (p *poll) ChangeDetach(fd int) {
p.changes = append(p.changes,
syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_DELETE, Filter: syscall.EVFILT_READ,
},
syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_DELETE, Filter: syscall.EVFILT_WRITE,
},
)
}
func (p *poll) ChangeRead(fd int) {
p.changes = append(p.changes, syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_DELETE, Filter: syscall.EVFILT_WRITE,
})
}
func (p *poll) AddRW(fd int) {
p.changes = append(p.changes,
syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_ADD, Filter: syscall.EVFILT_READ,
},
syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_ADD, Filter: syscall.EVFILT_WRITE,
},
)
}
func (p *poll) AddRead(fd int) {
p.changes = append(p.changes,
syscall.Kevent_t{
Ident: uint64(fd), Flags: syscall.EV_ADD, Filter: syscall.EVFILT_READ,
},
)
}
// Wait Poll Loop
func (p *poll) Looping(execute func(fd int) error) {
events := make([]syscall.Kevent_t, 2<<8)
for {
n, err := syscall.Kevent(p.srvFd, p.changes, events, nil)
if err != nil && err != syscall.EINTR {
logger.Log.Error("err while Looping", err)
}
p.changes = p.changes[:0]
for i := 0; i < n; i++ {
if fd := int(events[i].Ident); fd != 0 {
if err := execute(fd); err != nil {
logger.Log.Error("err while Looping", err)
}
}
}
}
}
func (p *poll) Close() error {
return syscall.Close(p.srvFd)
}
func (p *poll) Trigger(note interface{}) error {
_, err := syscall.Kevent(p.srvFd, []syscall.Kevent_t{{
Ident: 0,
Filter: syscall.EVFILT_USER,
Fflags: syscall.NOTE_TRIGGER,
}}, nil, nil)
return err
}