summaryrefslogtreecommitdiff
path: root/test/closedchan.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
commit758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch)
tree6d6b34f8c678862fe9b56c945a7b63f68502c245 /test/closedchan.go
parent3e45412327a2654a77944249962b3652e6142299 (diff)
downloadgolang-758ff64c69e34965f8af5b2d6ffd65e8d7ab2150.tar.gz
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'test/closedchan.go')
-rw-r--r--test/closedchan.go106
1 files changed, 92 insertions, 14 deletions
diff --git a/test/closedchan.go b/test/closedchan.go
index c7c759be3..46d9d0f5d 100644
--- a/test/closedchan.go
+++ b/test/closedchan.go
@@ -21,14 +21,21 @@ type Chan interface {
Impl() string
}
-// direct channel operations
+// direct channel operations when possible
type XChan chan int
+
func (c XChan) Send(x int) {
c <- x
}
func (c XChan) Nbsend(x int) bool {
- return c <- x
+ select {
+ case c <- x:
+ return true
+ default:
+ return false
+ }
+ panic("nbsend")
}
func (c XChan) Recv() int {
@@ -36,8 +43,13 @@ func (c XChan) Recv() int {
}
func (c XChan) Nbrecv() (int, bool) {
- x, ok := <-c
- return x, ok
+ select {
+ case x := <-c:
+ return x, true
+ default:
+ return 0, false
+ }
+ panic("nbrecv")
}
func (c XChan) Close() {
@@ -54,6 +66,7 @@ func (c XChan) Impl() string {
// indirect operations via select
type SChan chan int
+
func (c SChan) Send(x int) {
select {
case c <- x:
@@ -62,10 +75,10 @@ func (c SChan) Send(x int) {
func (c SChan) Nbsend(x int) bool {
select {
- case c <- x:
- return true
default:
return false
+ case c <- x:
+ return true
}
panic("nbsend")
}
@@ -80,10 +93,10 @@ func (c SChan) Recv() int {
func (c SChan) Nbrecv() (int, bool) {
select {
- case x := <-c:
- return x, true
default:
return 0, false
+ case x := <-c:
+ return x, true
}
panic("nbrecv")
}
@@ -100,6 +113,71 @@ func (c SChan) Impl() string {
return "(select)"
}
+// indirect operations via larger selects
+var dummy = make(chan bool)
+
+type SSChan chan int
+
+func (c SSChan) Send(x int) {
+ select {
+ case c <- x:
+ case <-dummy:
+ }
+}
+
+func (c SSChan) Nbsend(x int) bool {
+ select {
+ default:
+ return false
+ case <-dummy:
+ case c <- x:
+ return true
+ }
+ panic("nbsend")
+}
+
+func (c SSChan) Recv() int {
+ select {
+ case <-dummy:
+ case x := <-c:
+ return x
+ }
+ panic("recv")
+}
+
+func (c SSChan) Nbrecv() (int, bool) {
+ select {
+ case <-dummy:
+ default:
+ return 0, false
+ case x := <-c:
+ return x, true
+ }
+ panic("nbrecv")
+}
+
+func (c SSChan) Close() {
+ close(c)
+}
+
+func (c SSChan) Closed() bool {
+ return closed(c)
+}
+
+func (c SSChan) Impl() string {
+ return "(select)"
+}
+
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("did not panic")
+ }
+ }()
+ f()
+}
+
func test1(c Chan) {
// not closed until the close signal (a zero value) has been received.
if c.Closed() {
@@ -128,18 +206,15 @@ func test1(c Chan) {
}
// send should work with ,ok too: sent a value without blocking, so ok == true.
- ok := c.Nbsend(1)
- if !ok {
- println("test1: send on closed got not ok", c.Impl())
- }
+ shouldPanic(func() { c.Nbsend(1) })
- // but the value should have been discarded.
+ // the value should have been discarded.
if x := c.Recv(); x != 0 {
println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
}
// similarly Send.
- c.Send(2)
+ shouldPanic(func() { c.Send(2) })
if x := c.Recv(); x != 0 {
println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
}
@@ -189,9 +264,12 @@ func closedasync() chan int {
func main() {
test1(XChan(closedsync()))
test1(SChan(closedsync()))
+ test1(SSChan(closedsync()))
testasync1(XChan(closedasync()))
testasync1(SChan(closedasync()))
+ testasync1(SSChan(closedasync()))
testasync2(XChan(closedasync()))
testasync2(SChan(closedasync()))
+ testasync2(SSChan(closedasync()))
}