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), receive of closed channel.
9 // TODO(rsc): Doesn't check behavior of close(c) when there
10 // are blocked senders/receivers.
24 Nbrecv2() (int, bool, bool)
29 // direct channel operations when possible
32 func (c XChan) Send(x int) {
36 func (c XChan) Nbsend(x int) bool {
46 func (c XChan) Recv() int {
50 func (c XChan) Nbrecv() (int, bool) {
60 func (c XChan) Recv2() (int, bool) {
65 func (c XChan) Nbrecv2() (int, bool, bool) {
70 return 0, false, false
75 func (c XChan) Close() {
79 func (c XChan) Impl() string {
80 return "(<- operator)"
83 // indirect operations via select
86 func (c SChan) Send(x int) {
92 func (c SChan) Nbsend(x int) bool {
102 func (c SChan) Recv() int {
110 func (c SChan) Nbrecv() (int, bool) {
120 func (c SChan) Recv2() (int, bool) {
128 func (c SChan) Nbrecv2() (int, bool, bool) {
131 return 0, false, false
138 func (c SChan) Close() {
142 func (c SChan) Impl() string {
146 // indirect operations via larger selects
147 var dummy = make(chan bool)
151 func (c SSChan) Send(x int) {
158 func (c SSChan) Nbsend(x int) bool {
169 func (c SSChan) Recv() int {
178 func (c SSChan) Nbrecv() (int, bool) {
189 func (c SSChan) Recv2() (int, bool) {
198 func (c SSChan) Nbrecv2() (int, bool, bool) {
202 return 0, false, false
209 func (c SSChan) Close() {
213 func (c SSChan) Impl() string {
218 func shouldPanic(f func()) {
220 if recover() == nil {
221 panic("did not panic")
228 for i := 0; i < 3; i++ {
229 // recv a close signal (a zero value)
230 if x := c.Recv(); x != 0 {
231 println("test1: recv on closed:", x, c.Impl())
234 if x, ok := c.Recv2(); x != 0 || ok {
235 println("test1: recv2 on closed:", x, ok, c.Impl())
239 // should work with select: received a value without blocking, so selected == true.
240 x, selected := c.Nbrecv()
241 if x != 0 || !selected {
242 println("test1: recv on closed nb:", x, selected, c.Impl())
245 x, ok, selected := c.Nbrecv2()
246 if x != 0 || ok || !selected {
247 println("test1: recv2 on closed nb:", x, ok, selected, c.Impl())
252 // send should work with ,ok too: sent a value without blocking, so ok == true.
253 shouldPanic(func() { c.Nbsend(1) })
255 // the value should have been discarded.
256 if x := c.Recv(); x != 0 {
257 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
262 shouldPanic(func() { c.Send(2) })
263 if x := c.Recv(); x != 0 {
264 println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
269 func testasync1(c Chan) {
270 // should be able to get the last value via Recv
271 if x := c.Recv(); x != 1 {
272 println("testasync1: Recv did not get 1:", x, c.Impl())
279 func testasync2(c Chan) {
280 // should be able to get the last value via Recv2
281 if x, ok := c.Recv2(); x != 1 || !ok {
282 println("testasync1: Recv did not get 1, true:", x, ok, c.Impl())
289 func testasync3(c Chan) {
290 // should be able to get the last value via Nbrecv
291 if x, selected := c.Nbrecv(); x != 1 || !selected {
292 println("testasync2: Nbrecv did not get 1, true:", x, selected, c.Impl())
299 func testasync4(c Chan) {
300 // should be able to get the last value via Nbrecv2
301 if x, ok, selected := c.Nbrecv2(); x != 1 || !ok || !selected {
302 println("testasync2: Nbrecv did not get 1, true, true:", x, ok, selected, c.Impl())
308 func closedsync() chan int {
314 func closedasync() chan int {
315 c := make(chan int, 2)
321 var mks = []func(chan int) Chan {
322 func(c chan int) Chan { return XChan(c) },
323 func(c chan int) Chan { return SChan(c) },
324 func(c chan int) Chan { return SSChan(c) },
327 var testcloseds = []func(Chan) {
335 for _, mk := range mks {
336 test1(mk(closedsync()))
339 for _, testclosed := range testcloseds {
340 for _, mk := range mks {
341 testclosed(mk(closedasync()))