~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/net/fd_bsd.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 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
// +build freebsd netbsd openbsd
 
6
 
 
7
// Waiting for FDs via kqueue/kevent.
 
8
 
 
9
package net
 
10
 
 
11
import (
 
12
        "os"
 
13
        "syscall"
 
14
)
 
15
 
 
16
type pollster struct {
 
17
        kq       int
 
18
        eventbuf [10]syscall.Kevent_t
 
19
        events   []syscall.Kevent_t
 
20
 
 
21
        // An event buffer for AddFD/DelFD.
 
22
        // Must hold pollServer lock.
 
23
        kbuf [1]syscall.Kevent_t
 
24
}
 
25
 
 
26
func newpollster() (p *pollster, err error) {
 
27
        p = new(pollster)
 
28
        if p.kq, err = syscall.Kqueue(); err != nil {
 
29
                return nil, os.NewSyscallError("kqueue", err)
 
30
        }
 
31
        syscall.CloseOnExec(p.kq)
 
32
        p.events = p.eventbuf[0:0]
 
33
        return p, nil
 
34
}
 
35
 
 
36
// First return value is whether the pollServer should be woken up.
 
37
// This version always returns false.
 
38
func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) {
 
39
        // pollServer is locked.
 
40
 
 
41
        var kmode int
 
42
        if mode == 'r' {
 
43
                kmode = syscall.EVFILT_READ
 
44
        } else {
 
45
                kmode = syscall.EVFILT_WRITE
 
46
        }
 
47
        ev := &p.kbuf[0]
 
48
        // EV_ADD - add event to kqueue list
 
49
        // EV_ONESHOT - delete the event the first time it triggers
 
50
        flags := syscall.EV_ADD
 
51
        if !repeat {
 
52
                flags |= syscall.EV_ONESHOT
 
53
        }
 
54
        syscall.SetKevent(ev, fd, kmode, flags)
 
55
 
 
56
        n, err := syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
 
57
        if err != nil {
 
58
                return false, os.NewSyscallError("kevent", err)
 
59
        }
 
60
        if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
 
61
                return false, os.NewSyscallError("kqueue phase error", err)
 
62
        }
 
63
        if ev.Data != 0 {
 
64
                return false, syscall.Errno(int(ev.Data))
 
65
        }
 
66
        return false, nil
 
67
}
 
68
 
 
69
// Return value is whether the pollServer should be woken up.
 
70
// This version always returns false.
 
71
func (p *pollster) DelFD(fd int, mode int) bool {
 
72
        // pollServer is locked.
 
73
 
 
74
        var kmode int
 
75
        if mode == 'r' {
 
76
                kmode = syscall.EVFILT_READ
 
77
        } else {
 
78
                kmode = syscall.EVFILT_WRITE
 
79
        }
 
80
        ev := &p.kbuf[0]
 
81
        // EV_DELETE - delete event from kqueue list
 
82
        syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE)
 
83
        syscall.Kevent(p.kq, p.kbuf[:], nil, nil)
 
84
        return false
 
85
}
 
86
 
 
87
func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) {
 
88
        var t *syscall.Timespec
 
89
        for len(p.events) == 0 {
 
90
                if nsec > 0 {
 
91
                        if t == nil {
 
92
                                t = new(syscall.Timespec)
 
93
                        }
 
94
                        *t = syscall.NsecToTimespec(nsec)
 
95
                }
 
96
 
 
97
                s.Unlock()
 
98
                n, err := syscall.Kevent(p.kq, nil, p.eventbuf[:], t)
 
99
                s.Lock()
 
100
 
 
101
                if err != nil {
 
102
                        if err == syscall.EINTR {
 
103
                                continue
 
104
                        }
 
105
                        return -1, 0, os.NewSyscallError("kevent", err)
 
106
                }
 
107
                if n == 0 {
 
108
                        return -1, 0, nil
 
109
                }
 
110
                p.events = p.eventbuf[:n]
 
111
        }
 
112
        ev := &p.events[0]
 
113
        p.events = p.events[1:]
 
114
        fd = int(ev.Ident)
 
115
        if ev.Filter == syscall.EVFILT_READ {
 
116
                mode = 'r'
 
117
        } else {
 
118
                mode = 'w'
 
119
        }
 
120
        return fd, mode, nil
 
121
}
 
122
 
 
123
func (p *pollster) Close() error { return os.NewSyscallError("close", syscall.Close(p.kq)) }