1 // $G $D/$F.go && $L $F.$A && ./$A.out
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.
7 // Test close(c), closed(c).
9 // TODO(rsc): Doesn't check behavior of close(c) when there
10 // are blocked senders/receivers.
24 // direct channel operations when possible
27 func (c XChan) Send(x int) {
31 func (c XChan) Nbsend(x int) bool {
41 func (c XChan) Recv() int {
45 func (c XChan) Nbrecv() (int, bool) {
55 func (c XChan) Close() {
59 func (c XChan) Closed() bool {
63 func (c XChan) Impl() string {
64 return "(<- operator)"
67 // indirect operations via select
70 func (c SChan) Send(x int) {
76 func (c SChan) Nbsend(x int) bool {
86 func (c SChan) Recv() int {
94 func (c SChan) Nbrecv() (int, bool) {
104 func (c SChan) Close() {
108 func (c SChan) Closed() bool {
112 func (c SChan) Impl() string {
116 // indirect operations via larger selects
117 var dummy = make(chan bool)
121 func (c SSChan) Send(x int) {
128 func (c SSChan) Nbsend(x int) bool {
139 func (c SSChan) Recv() int {
148 func (c SSChan) Nbrecv() (int, bool) {
159 func (c SSChan) Close() {
163 func (c SSChan) Closed() bool {
167 func (c SSChan) Impl() string {
172 func shouldPanic(f func()) {
174 if recover() == nil {
175 panic("did not panic")
182 // not closed until the close signal (a zero value) has been received.
184 println("test1: Closed before Recv zero:", c.Impl())
187 for i := 0; i < 3; i++ {
188 // recv a close signal (a zero value)
189 if x := c.Recv(); x != 0 {
190 println("test1: recv on closed got non-zero:", x, c.Impl())
193 // should now be closed.
195 println("test1: not closed after recv zero", c.Impl())
198 // should work with ,ok: received a value without blocking, so ok == true.
201 println("test1: recv on closed got not ok", c.Impl())
204 println("test1: recv ,ok on closed got non-zero:", x, c.Impl())
208 // send should work with ,ok too: sent a value without blocking, so ok == true.
209 shouldPanic(func() { c.Nbsend(1) })
211 // the value should have been discarded.
212 if x := c.Recv(); x != 0 {
213 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
217 shouldPanic(func() { c.Send(2) })
218 if x := c.Recv(); x != 0 {
219 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
223 func testasync1(c Chan) {
224 // not closed until the close signal (a zero value) has been received.
226 println("testasync1: Closed before Recv zero:", c.Impl())
229 // should be able to get the last value via Recv
230 if x := c.Recv(); x != 1 {
231 println("testasync1: Recv did not get 1:", x, c.Impl())
237 func testasync2(c Chan) {
238 // not closed until the close signal (a zero value) has been received.
240 println("testasync2: Closed before Recv zero:", c.Impl())
243 // should be able to get the last value via Nbrecv
244 if x, ok := c.Nbrecv(); !ok || x != 1 {
245 println("testasync2: Nbrecv did not get 1, true:", x, ok, c.Impl())
251 func closedsync() chan int {
257 func closedasync() chan int {
258 c := make(chan int, 2)
265 test1(XChan(closedsync()))
266 test1(SChan(closedsync()))
267 test1(SSChan(closedsync()))
269 testasync1(XChan(closedasync()))
270 testasync1(SChan(closedasync()))
271 testasync1(SSChan(closedasync()))
272 testasync2(XChan(closedasync()))
273 testasync2(SChan(closedasync()))
274 testasync2(SSChan(closedasync()))