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 flags := syscall.EV_ADD
47 if !repeat {
48 flags |= syscall.EV_ONESHOT
49 }
50 syscall.SetKevent(ev, fd, kmode, flags)
51
52 n, e := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
53 if e != 0 {
54 return false, os.NewSyscallError("kevent", e)
55 }
56 if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
57 return false, os.NewSyscallError("kqueue phase error", e)
58 }
59 if ev.Data != 0 {
60 return false, os.Errno(int(ev.Data))
61 }
62 return false, nil
63 }
64
65 func (p *pollster) DelFD(fd int, mode int) {
66
67
68 var kmode int
69 if mode == 'r' {
70 kmode = syscall.EVFILT_READ
71 } else {
72 kmode = syscall.EVFILT_WRITE
73 }
74 ev := &p.kbuf[0]
75
76 syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
77 syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
78 }
79
80 func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
81 var t *syscall.Timespec
82 for len(p.events) == 0 {
83 if nsec > 0 {
84 if t == nil {
85 t = new(syscall.Timespec)
86 }
87 *t = syscall.NsecToTimespec(nsec)
88 }
89
90 s.Unlock()
91 nn, e := syscall.Kevent(p.kq, nil, p.eventbuf[:], t)
92 s.Lock()
93
94 if e != 0 {
95 if e == syscall.EINTR {
96 continue
97 }
98 return -1, 0, os.NewSyscallError("kevent", e)
99 }
100 if nn == 0 {
101 return -1, 0, nil
102 }
103 p.events = p.eventbuf[0:nn]
104 }
105 ev := &p.events[0]
106 p.events = p.events[1:]
107 fd = int(ev.Ident)
108 if ev.Filter == syscall.EVFILT_READ {
109 mode = 'r'
110 } else {
111 mode = 'w'
112 }
113 return fd, mode, nil
114 }
115
116 func (p *pollster) Close() os.Error { return os.NewSyscallError("close", syscall.Close(p.kq)) }