1
2
3
4
5
6
7 package net
8
9 import (
10 "os"
11 "syscall"
12 )
13
14 type pollster struct {
15 kq int
16 eventbuf [10]syscall.Kevent_t
17 events []syscall.Kevent_t
18
19
20
21 kbuf [1]syscall.Kevent_t
22 }
23
24 func newpollster() (p *pollster, err os.Error) {
25 p = new(pollster)
26 var e int
27 if p.kq, e = syscall.Kqueue(); e != 0 {
28 return nil, os.NewSyscallError("kqueue", e)
29 }
30 p.events = p.eventbuf[0:0]
31 return p, nil
32 }
33
34 func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
35
36
37 var kmode int
38 if mode == 'r' {
39 kmode = syscall.EVFILT_READ
40 } else {
41 kmode = syscall.EVFILT_WRITE
42 }
43 ev := &p.kbuf[0]
44
45
46
47
48 flags := syscall.EV_ADD | syscall.EV_RECEIPT
49 if !repeat {
50 flags |= syscall.EV_ONESHOT
51 }
52 syscall.SetKevent(ev, fd, kmode, flags)
53
54 n, e := syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
55 if e != 0 {
56 return false, os.NewSyscallError("kevent", e)
57 }
58 if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
59 return false, os.NewError("kqueue phase error")
60 }
61 if ev.Data != 0 {
62 return false, os.Errno(int(ev.Data))
63 }
64 return false, nil
65 }
66
67 func (p *pollster) DelFD(fd int, mode int) {
68
69
70 var kmode int
71 if mode == 'r' {
72 kmode = syscall.EVFILT_READ
73 } else {
74 kmode = syscall.EVFILT_WRITE
75 }
76 ev := &p.kbuf[0]
77
78
79
80 syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE|syscall.EV_RECEIPT)
81 syscall.Kevent(p.kq, p.kbuf[0:], p.kbuf[0:], nil)
82 }
83
84 func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
85 var t *syscall.Timespec
86 for len(p.events) == 0 {
87 if nsec > 0 {
88 if t == nil {
89 t = new(syscall.Timespec)
90 }
91 *t = syscall.NsecToTimespec(nsec)
92 }
93
94 s.Unlock()
95 nn, e := syscall.Kevent(p.kq, nil, p.eventbuf[0:], t)
96 s.Lock()
97
98 if e != 0 {
99 if e == syscall.EINTR {
100 continue
101 }
102 return -1, 0, os.NewSyscallError("kevent", e)
103 }
104 if nn == 0 {
105 return -1, 0, nil
106 }
107 p.events = p.eventbuf[0:nn]
108 }
109 ev := &p.events[0]
110 p.events = p.events[1:]
111 fd = int(ev.Ident)
112 if ev.Filter == syscall.EVFILT_READ {
113 mode = 'r'
114 } else {
115 mode = 'w'
116 }
117 return fd, mode, nil
118 }
119
120 func (p *pollster) Close() os.Error { return os.NewSyscallError("close", syscall.Close(p.kq)) }