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

« back to all changes in this revision

Viewing changes to src/pkg/net/fd_freebsd.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
 
// 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)) }