OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [fd_netbsd.go] - Blame information for rev 858

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Waiting for FDs via kqueue/kevent.
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
        // An event buffer for AddFD/DelFD.
20
        // Must hold pollServer lock.
21
        kbuf [1]syscall.Kevent_t
22
}
23
 
24
func newpollster() (p *pollster, err error) {
25
        p = new(pollster)
26
        if p.kq, err = syscall.Kqueue(); err != nil {
27
                return nil, os.NewSyscallError("kqueue", err)
28
        }
29
        syscall.CloseOnExec(p.kq)
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, error) {
35
        // pollServer is locked.
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
        // EV_ADD - add event to kqueue list
45
        // EV_ONESHOT - delete the event the first time it triggers
46
        flags := syscall.EV_ADD
47
        if !repeat {
48
                flags |= syscall.EV_ONESHOT
49
        }
50
        syscall.SetKevent(ev, fd, kmode, flags)
51
 
52
        n, err := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
53
        if err != nil {
54
                return false, os.NewSyscallError("kevent", err)
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", err)
58
        }
59
        if ev.Data != 0 {
60
                return false, syscall.Errno(int(ev.Data))
61
        }
62
        return false, nil
63
}
64
 
65
func (p *pollster) DelFD(fd int, mode int) {
66
        // pollServer is locked.
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
        // EV_DELETE - delete event from kqueue list
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 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
                n, err := syscall.Kevent(p.kq, nil, p.eventbuf[:], t)
92
                s.Lock()
93
 
94
                if err != nil {
95
                        if err == syscall.EINTR {
96
                                continue
97
                        }
98
                        return -1, 0, os.NewSyscallError("kevent", err)
99
                }
100
                if n == 0 {
101
                        return -1, 0, nil
102
                }
103
                p.events = p.eventbuf[:n]
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() error { return os.NewSyscallError("close", syscall.Close(p.kq)) }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.