]> Cypherpunks.ru repositories - gostls13.git/blob - test/closedchan.go
test: remove semiocolons.
[gostls13.git] / test / closedchan.go
1 // $G $D/$F.go && $L $F.$A && ./$A.out
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test close(c), closed(c).
8 //
9 // TODO(rsc): Doesn't check behavior of close(c) when there
10 // are blocked senders/receivers.
11
12 package main
13
14 type Chan interface {
15         Send(int)
16         Nbsend(int) bool
17         Recv() int
18         Nbrecv() (int, bool)
19         Close()
20         Closed() bool
21         Impl() string
22 }
23
24 // direct channel operations
25 type XChan chan int
26 func (c XChan) Send(x int) {
27         c <- x
28 }
29
30 func (c XChan) Nbsend(x int) bool {
31         return c <- x
32 }
33
34 func (c XChan) Recv() int {
35         return <-c
36 }
37
38 func (c XChan) Nbrecv() (int, bool) {
39         x, ok := <-c
40         return x, ok
41 }
42
43 func (c XChan) Close() {
44         close(c)
45 }
46
47 func (c XChan) Closed() bool {
48         return closed(c)
49 }
50
51 func (c XChan) Impl() string {
52         return "(<- operator)"
53 }
54
55 // indirect operations via select
56 type SChan chan int
57 func (c SChan) Send(x int) {
58         select {
59         case c <- x:
60         }
61 }
62
63 func (c SChan) Nbsend(x int) bool {
64         select {
65         case c <- x:
66                 return true
67         default:
68                 return false
69         }
70         panic("nbsend")
71 }
72
73 func (c SChan) Recv() int {
74         select {
75         case x := <-c:
76                 return x
77         }
78         panic("recv")
79 }
80
81 func (c SChan) Nbrecv() (int, bool) {
82         select {
83         case x := <-c:
84                 return x, true
85         default:
86                 return 0, false
87         }
88         panic("nbrecv")
89 }
90
91 func (c SChan) Close() {
92         close(c)
93 }
94
95 func (c SChan) Closed() bool {
96         return closed(c)
97 }
98
99 func (c SChan) Impl() string {
100         return "(select)"
101 }
102
103 func test1(c Chan) {
104         // not closed until the close signal (a zero value) has been received.
105         if c.Closed() {
106                 println("test1: Closed before Recv zero:", c.Impl())
107         }
108
109         for i := 0; i < 3; i++ {
110                 // recv a close signal (a zero value)
111                 if x := c.Recv(); x != 0 {
112                         println("test1: recv on closed got non-zero:", x, c.Impl())
113                 }
114
115                 // should now be closed.
116                 if !c.Closed() {
117                         println("test1: not closed after recv zero", c.Impl())
118                 }
119
120                 // should work with ,ok: received a value without blocking, so ok == true.
121                 x, ok := c.Nbrecv()
122                 if !ok {
123                         println("test1: recv on closed got not ok", c.Impl())
124                 }
125                 if x != 0 {
126                         println("test1: recv ,ok on closed got non-zero:", x, c.Impl())
127                 }
128         }
129
130         // send should work with ,ok too: sent a value without blocking, so ok == true.
131         ok := c.Nbsend(1)
132         if !ok {
133                 println("test1: send on closed got not ok", c.Impl())
134         }
135
136         // but the value should have been discarded.
137         if x := c.Recv(); x != 0 {
138                 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
139         }
140
141         // similarly Send.
142         c.Send(2)
143         if x := c.Recv(); x != 0 {
144                 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
145         }
146 }
147
148 func testasync1(c Chan) {
149         // not closed until the close signal (a zero value) has been received.
150         if c.Closed() {
151                 println("testasync1: Closed before Recv zero:", c.Impl())
152         }
153
154         // should be able to get the last value via Recv
155         if x := c.Recv(); x != 1 {
156                 println("testasync1: Recv did not get 1:", x, c.Impl())
157         }
158
159         test1(c)
160 }
161
162 func testasync2(c Chan) {
163         // not closed until the close signal (a zero value) has been received.
164         if c.Closed() {
165                 println("testasync2: Closed before Recv zero:", c.Impl())
166         }
167
168         // should be able to get the last value via Nbrecv
169         if x, ok := c.Nbrecv(); !ok || x != 1 {
170                 println("testasync2: Nbrecv did not get 1, true:", x, ok, c.Impl())
171         }
172
173         test1(c)
174 }
175
176 func closedsync() chan int {
177         c := make(chan int)
178         close(c)
179         return c
180 }
181
182 func closedasync() chan int {
183         c := make(chan int, 2)
184         c <- 1
185         close(c)
186         return c
187 }
188
189 func main() {
190         test1(XChan(closedsync()))
191         test1(SChan(closedsync()))
192
193         testasync1(XChan(closedasync()))
194         testasync1(SChan(closedasync()))
195         testasync2(XChan(closedasync()))
196         testasync2(SChan(closedasync()))
197 }