aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2011-03-11 14:47:44 -0500
committerRuss Cox <rsc@golang.org>2011-03-11 14:47:44 -0500
commit3f915f51a8d16e97ac631dfb4dd5946ca675a2b8 (patch)
tree296090b5a1d922cdddce36fc4160f8d411b57f50 /src/pkg
parent8bf34e335686816f7fe7e28614b2c7a3e04e9e7c (diff)
downloadgo-3f915f51a8d16e97ac631dfb4dd5946ca675a2b8.tar.xz
go code: replace closed(c) with x, ok := <-c
R=golang-dev, rog, bradfitzwork, r CC=golang-dev https://golang.org/cl/4243072
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/netchan/common.go4
-rw-r--r--src/pkg/netchan/export.go4
-rw-r--r--src/pkg/netchan/import.go4
-rw-r--r--src/pkg/netchan/netchan_test.go16
-rw-r--r--src/pkg/os/inotify/inotify_linux_test.go16
-rw-r--r--src/pkg/reflect/all_test.go37
-rw-r--r--src/pkg/reflect/value.go56
-rw-r--r--src/pkg/template/template.go4
-rw-r--r--src/pkg/testing/script/script.go4
9 files changed, 68 insertions, 77 deletions
diff --git a/src/pkg/netchan/common.go b/src/pkg/netchan/common.go
index dd06050ee5..d2cd8efc55 100644
--- a/src/pkg/netchan/common.go
+++ b/src/pkg/netchan/common.go
@@ -306,7 +306,7 @@ func (nch *netChan) sender() {
}
// Receive value from local side for sending to remote side.
-func (nch *netChan) recv() (val reflect.Value, closed bool) {
+func (nch *netChan) recv() (val reflect.Value, ok bool) {
if nch.dir != Send {
panic("recv on wrong direction of channel")
}
@@ -317,7 +317,7 @@ func (nch *netChan) recv() (val reflect.Value, closed bool) {
nch.space++
}
nch.space--
- return nch.ch.Recv(), nch.ch.Closed()
+ return nch.ch.Recv()
}
// acked is called when the remote side indicates that
diff --git a/src/pkg/netchan/export.go b/src/pkg/netchan/export.go
index 55eba0e2e0..e91e777e30 100644
--- a/src/pkg/netchan/export.go
+++ b/src/pkg/netchan/export.go
@@ -181,8 +181,8 @@ func (client *expClient) run() {
// The header is passed by value to avoid issues of overwriting.
func (client *expClient) serveRecv(nch *netChan, hdr header, count int64) {
for {
- val, closed := nch.recv()
- if closed {
+ val, ok := nch.recv()
+ if !ok {
if err := client.encode(&hdr, payClosed, nil); err != nil {
expLog("error encoding server closed message:", err)
}
diff --git a/src/pkg/netchan/import.go b/src/pkg/netchan/import.go
index 30edcd8123..5db679a3ed 100644
--- a/src/pkg/netchan/import.go
+++ b/src/pkg/netchan/import.go
@@ -213,8 +213,8 @@ func (imp *Importer) ImportNValues(name string, chT interface{}, dir Dir, size,
if dir == Send {
go func() {
for i := 0; n == -1 || i < n; i++ {
- val, closed := nch.recv()
- if closed {
+ val, ok := nch.recv()
+ if !ok {
if err = imp.encode(hdr, payClosed, nil); err != nil {
impLog("error encoding client closed message:", err)
}
diff --git a/src/pkg/netchan/netchan_test.go b/src/pkg/netchan/netchan_test.go
index 1c84a9d14d..1b5c560872 100644
--- a/src/pkg/netchan/netchan_test.go
+++ b/src/pkg/netchan/netchan_test.go
@@ -41,8 +41,8 @@ func exportReceive(exp *Exporter, t *testing.T, expDone chan bool) {
t.Fatal("exportReceive:", err)
}
for i := 0; i < count; i++ {
- v := <-ch
- if closed(ch) {
+ v, ok := <-ch
+ if !ok {
if i != closeCount {
t.Errorf("exportReceive expected close at %d; got one at %d", closeCount, i)
}
@@ -78,8 +78,8 @@ func importReceive(imp *Importer, t *testing.T, done chan bool) {
t.Fatal("importReceive:", err)
}
for i := 0; i < count; i++ {
- v := <-ch
- if closed(ch) {
+ v, ok := <-ch
+ if !ok {
if i != closeCount {
t.Errorf("importReceive expected close at %d; got one at %d", closeCount, i)
}
@@ -212,8 +212,8 @@ func TestExportHangup(t *testing.T) {
}
// Now hang up the channel. Importer should see it close.
exp.Hangup("exportedSend")
- v = <-ich
- if !closed(ich) {
+ v, ok := <-ich
+ if ok {
t.Fatal("expected channel to be closed; got value", v)
}
}
@@ -242,8 +242,8 @@ func TestImportHangup(t *testing.T) {
}
// Now hang up the channel. Exporter should see it close.
imp.Hangup("exportedRecv")
- v = <-ech
- if !closed(ech) {
+ v, ok := <-ech
+ if ok {
t.Fatal("expected channel to be closed; got value", v)
}
}
diff --git a/src/pkg/os/inotify/inotify_linux_test.go b/src/pkg/os/inotify/inotify_linux_test.go
index 332edcb644..79c3bfa36e 100644
--- a/src/pkg/os/inotify/inotify_linux_test.go
+++ b/src/pkg/os/inotify/inotify_linux_test.go
@@ -35,6 +35,7 @@ func TestInotifyEvents(t *testing.T) {
// Receive events on the event channel on a separate goroutine
eventstream := watcher.Event
var eventsReceived = 0
+ done := make(chan bool)
go func() {
for event := range eventstream {
// Only count relevant events
@@ -45,6 +46,7 @@ func TestInotifyEvents(t *testing.T) {
t.Logf("unexpected event received: %s", event)
}
}
+ done <- true
}()
// Create a file
@@ -64,16 +66,12 @@ func TestInotifyEvents(t *testing.T) {
t.Log("calling Close()")
watcher.Close()
t.Log("waiting for the event channel to become closed...")
- var i = 0
- for !closed(eventstream) {
- if i >= 20 {
- t.Fatal("event stream was not closed after 1 second, as expected")
- }
- t.Log("waiting for 50 ms...")
- time.Sleep(50e6) // 50 ms
- i++
+ select {
+ case <-done:
+ t.Log("event channel closed")
+ case <-time.After(1e9):
+ t.Fatal("event stream was not closed after 1 second")
}
- t.Log("event channel closed")
}
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index 7a97ea1737..f616adaac3 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -968,28 +968,28 @@ func TestChan(t *testing.T) {
// Recv
c <- 3
- if i := cv.Recv().(*IntValue).Get(); i != 3 {
- t.Errorf("native send 3, reflect Recv %d", i)
+ if i, ok := cv.Recv(); i.(*IntValue).Get() != 3 || !ok {
+ t.Errorf("native send 3, reflect Recv %d, %t", i.(*IntValue).Get(), ok)
}
// TryRecv fail
- val := cv.TryRecv()
- if val != nil {
- t.Errorf("TryRecv on empty chan: %s", valueToString(val))
+ val, ok := cv.TryRecv()
+ if val != nil || ok {
+ t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
}
// TryRecv success
c <- 4
- val = cv.TryRecv()
+ val, ok = cv.TryRecv()
if val == nil {
t.Errorf("TryRecv on ready chan got nil")
- } else if i := val.(*IntValue).Get(); i != 4 {
- t.Errorf("native send 4, TryRecv %d", i)
+ } else if i := val.(*IntValue).Get(); i != 4 || !ok {
+ t.Errorf("native send 4, TryRecv %d, %t", i, ok)
}
// TrySend fail
c <- 100
- ok := cv.TrySend(NewValue(5))
+ ok = cv.TrySend(NewValue(5))
i := <-c
if ok {
t.Errorf("TrySend on full chan succeeded: value %d", i)
@@ -1008,20 +1008,11 @@ func TestChan(t *testing.T) {
// Close
c <- 123
cv.Close()
- if cv.Closed() {
- t.Errorf("closed too soon - 1")
+ if i, ok := cv.Recv(); i.(*IntValue).Get() != 123 || !ok {
+ t.Errorf("send 123 then close; Recv %d, %t", i.(*IntValue).Get(), ok)
}
- if i := cv.Recv().(*IntValue).Get(); i != 123 {
- t.Errorf("send 123 then close; Recv %d", i)
- }
- if cv.Closed() {
- t.Errorf("closed too soon - 2")
- }
- if i := cv.Recv().(*IntValue).Get(); i != 0 {
- t.Errorf("after close Recv %d", i)
- }
- if !cv.Closed() {
- t.Errorf("not closed")
+ if i, ok := cv.Recv(); i.(*IntValue).Get() != 0 || ok {
+ t.Errorf("after close Recv %d, %t", i.(*IntValue).Get(), ok)
}
}
@@ -1032,7 +1023,7 @@ func TestChan(t *testing.T) {
if cv.TrySend(NewValue(7)) {
t.Errorf("TrySend on sync chan succeeded")
}
- if cv.TryRecv() != nil {
+ if v, ok := cv.TryRecv(); v != nil || ok {
t.Errorf("TryRecv on sync chan succeeded")
}
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index 0b70b17f8f..01a40ec9a4 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -671,19 +671,12 @@ func (v *ChanValue) Get() uintptr { return *(*uintptr)(v.addr) }
// implemented in ../pkg/runtime/reflect.cgo
func makechan(typ *runtime.ChanType, size uint32) (ch *byte)
-func chansend(ch, val *byte, pres *bool)
-func chanrecv(ch, val *byte, pres *bool)
-func chanclosed(ch *byte) bool
+func chansend(ch, val *byte, selected *bool)
+func chanrecv(ch, val *byte, selected *bool, ok *bool)
func chanclose(ch *byte)
func chanlen(ch *byte) int32
func chancap(ch *byte) int32
-// Closed returns the result of closed(c) on the underlying channel.
-func (v *ChanValue) Closed() bool {
- ch := *(**byte)(v.addr)
- return chanclosed(ch)
-}
-
// Close closes the channel.
func (v *ChanValue) Close() {
ch := *(**byte)(v.addr)
@@ -700,52 +693,61 @@ func (v *ChanValue) Cap() int {
return int(chancap(ch))
}
-// internal send; non-blocking if b != nil
-func (v *ChanValue) send(x Value, b *bool) {
+// internal send; non-blocking if selected != nil
+func (v *ChanValue) send(x Value, selected *bool) {
t := v.Type().(*ChanType)
if t.Dir()&SendDir == 0 {
panic("send on recv-only channel")
}
typesMustMatch(t.Elem(), x.Type())
ch := *(**byte)(v.addr)
- chansend(ch, (*byte)(x.getAddr()), b)
+ chansend(ch, (*byte)(x.getAddr()), selected)
}
-// internal recv; non-blocking if b != nil
-func (v *ChanValue) recv(b *bool) Value {
+// internal recv; non-blocking if selected != nil
+func (v *ChanValue) recv(selected *bool) (Value, bool) {
t := v.Type().(*ChanType)
if t.Dir()&RecvDir == 0 {
panic("recv on send-only channel")
}
ch := *(**byte)(v.addr)
x := MakeZero(t.Elem())
- chanrecv(ch, (*byte)(x.getAddr()), b)
- return x
+ var ok bool
+ chanrecv(ch, (*byte)(x.getAddr()), selected, &ok)
+ return x, ok
}
// Send sends x on the channel v.
func (v *ChanValue) Send(x Value) { v.send(x, nil) }
// Recv receives and returns a value from the channel v.
-func (v *ChanValue) Recv() Value { return v.recv(nil) }
+// The receive blocks until a value is ready.
+// The boolean value ok is true if the value x corresponds to a send
+// on the channel, false if it is a zero value received because the channel is closed.
+func (v *ChanValue) Recv() (x Value, ok bool) {
+ return v.recv(nil)
+}
// TrySend attempts to sends x on the channel v but will not block.
// It returns true if the value was sent, false otherwise.
func (v *ChanValue) TrySend(x Value) bool {
- var ok bool
- v.send(x, &ok)
- return ok
+ var selected bool
+ v.send(x, &selected)
+ return selected
}
// TryRecv attempts to receive a value from the channel v but will not block.
-// It returns the value if one is received, nil otherwise.
-func (v *ChanValue) TryRecv() Value {
- var ok bool
- x := v.recv(&ok)
- if !ok {
- return nil
+// If the receive cannot finish without blocking, TryRecv instead returns x == nil.
+// If the receive can finish without blocking, TryRecv returns x != nil.
+// The boolean value ok is true if the value x corresponds to a send
+// on the channel, false if it is a zero value received because the channel is closed.
+func (v *ChanValue) TryRecv() (x Value, ok bool) {
+ var selected bool
+ x, ok = v.recv(&selected)
+ if !selected {
+ return nil, false
}
- return x
+ return x, ok
}
// MakeChan creates a new channel with the specified type and buffer size.
diff --git a/src/pkg/template/template.go b/src/pkg/template/template.go
index c3cb8901a0..f27c987abe 100644
--- a/src/pkg/template/template.go
+++ b/src/pkg/template/template.go
@@ -896,8 +896,8 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
}
} else if ch := iter(field); ch != nil {
for {
- e := ch.Recv()
- if ch.Closed() {
+ e, ok := ch.Recv()
+ if !ok {
break
}
loopBody(st.clone(e))
diff --git a/src/pkg/testing/script/script.go b/src/pkg/testing/script/script.go
index 11f5a74251..b341b1f896 100644
--- a/src/pkg/testing/script/script.go
+++ b/src/pkg/testing/script/script.go
@@ -306,8 +306,8 @@ func recvValues(multiplex chan<- interface{}, channel interface{}) {
c := reflect.NewValue(channel).(*reflect.ChanValue)
for {
- v := c.Recv()
- if c.Closed() {
+ v, ok := c.Recv()
+ if !ok {
multiplex <- channelClosed{channel}
return
}