]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/net/fd_rtems.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.git] / libgo / go / net / fd_rtems.go
1 // Copyright 2010 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 select(2).
6
7 package net
8
9 import (
10 "os"
11 "syscall"
12 )
13
14 type pollster struct {
15 readFds, writeFds, repeatFds *syscall.FdSet_t
16 maxFd int
17 readyReadFds, readyWriteFds *syscall.FdSet_t
18 nReady int
19 lastFd int
20 }
21
22 func newpollster() (p *pollster, err os.Error) {
23 p = new(pollster)
24 p.readFds = new(syscall.FdSet_t)
25 p.writeFds = new(syscall.FdSet_t)
26 p.repeatFds = new(syscall.FdSet_t)
27 p.readyReadFds = new(syscall.FdSet_t)
28 p.readyWriteFds = new(syscall.FdSet_t)
29 p.maxFd = -1
30 p.nReady = 0
31 p.lastFd = 0
32 return p, nil
33 }
34
35 func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
36 if mode == 'r' {
37 syscall.FDSet(fd, p.readFds)
38 } else {
39 syscall.FDSet(fd, p.writeFds)
40 }
41
42 if repeat {
43 syscall.FDSet(fd, p.repeatFds)
44 }
45
46 if fd > p.maxFd {
47 p.maxFd = fd
48 }
49
50 return nil
51 }
52
53 func (p *pollster) DelFD(fd int, mode int) {
54 if mode == 'r' {
55 if !syscall.FDIsSet(fd, p.readFds) {
56 print("Select unexpected fd=", fd, " for read\n")
57 return
58 }
59 syscall.FDClr(fd, p.readFds)
60 } else {
61 if !syscall.FDIsSet(fd, p.writeFds) {
62 print("Select unexpected fd=", fd, " for write\n")
63 return
64 }
65 syscall.FDClr(fd, p.writeFds)
66 }
67
68 // Doesn't matter if not already present.
69 syscall.FDClr(fd, p.repeatFds)
70
71 // We don't worry about maxFd here.
72 }
73
74 func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
75 if p.nReady == 0 {
76 var timeout *syscall.Timeval
77 var tv syscall.Timeval
78 timeout = nil
79 if nsec > 0 {
80 tv = syscall.NsecToTimeval(nsec)
81 timeout = &tv
82 }
83
84 var n, e int
85 var tmpReadFds, tmpWriteFds syscall.FdSet_t
86 for {
87 // Temporary syscall.FdSet_ts into which the values are copied
88 // because select mutates the values.
89 tmpReadFds = *p.readFds
90 tmpWriteFds = *p.writeFds
91
92 n, e = syscall.Select(p.maxFd + 1, &tmpReadFds, &tmpWriteFds, nil, timeout)
93 if e != syscall.EINTR {
94 break
95 }
96 }
97 if e != 0 {
98 return -1, 0, os.NewSyscallError("select", e)
99 }
100 if n == 0 {
101 return -1, 0, nil
102 }
103
104 p.nReady = n
105 *p.readyReadFds = tmpReadFds
106 *p.readyWriteFds = tmpWriteFds
107 p.lastFd = 0
108 }
109
110 flag := false
111 for i := p.lastFd; i < p.maxFd + 1; i++ {
112 if syscall.FDIsSet(i, p.readyReadFds) {
113 flag = true
114 mode = 'r'
115 syscall.FDClr(i, p.readyReadFds)
116 } else if syscall.FDIsSet(i, p.readyWriteFds) {
117 flag = true
118 mode = 'w'
119 syscall.FDClr(i, p.readyWriteFds)
120 }
121 if flag {
122 if !syscall.FDIsSet(i, p.repeatFds) {
123 p.DelFD(i, mode)
124 }
125 p.nReady--
126 p.lastFd = i
127 return i, mode, nil
128 }
129 }
130
131 // Will not reach here. Just to shut up the compiler.
132 return -1, 0, nil
133 }
134
135 func (p *pollster) Close() os.Error {
136 return nil
137 }