summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-08-26 12:42:22 -0700
committerRuss Cox <rsc@golang.org>2009-08-26 12:42:22 -0700
commit3450f2fbdb6de7f3ed69f24fe8daf02813192d3e (patch)
tree86bdea9f257b365fedb7a403eedb327ad5397643
parentea40944a877af0851eb56349ba9ad1e41396ea54 (diff)
downloadgolang-3450f2fbdb6de7f3ed69f24fe8daf02813192d3e.tar.gz
finish ChanValue: Len and Cap.
R=r DELTA=45 (45 added, 0 deleted, 0 changed) OCL=33873 CL=33881
-rw-r--r--src/pkg/reflect/all_test.go11
-rw-r--r--src/pkg/reflect/value.go12
-rw-r--r--src/pkg/runtime/chan.c12
-rw-r--r--src/pkg/runtime/reflect.cgo8
-rw-r--r--src/pkg/runtime/runtime.h2
5 files changed, 45 insertions, 0 deletions
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index 3a1c220da..2a30ddd87 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -757,6 +757,17 @@ func TestChan(t *testing.T) {
if cv.TryRecv() != nil {
t.Errorf("TryRecv on sync chan succeeded");
}
+
+ // len/cap
+ cv = MakeChan(Typeof(c).(*ChanType), 10);
+ c = cv.Interface().(chan int);
+ for i := 0; i < 3; i++ {
+ c <- i;
+ }
+ if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
+ t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c));
+ }
+
}
// Difficult test for function call because of
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index daa3f11ba..014ea933c 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -636,6 +636,8 @@ func chansend(ch, val *byte, pres *bool)
func chanrecv(ch, val *byte, pres *bool)
func chanclosed(ch *byte) 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 {
@@ -649,6 +651,16 @@ func (v *ChanValue) Close() {
chanclose(ch);
}
+func (v *ChanValue) Len() int {
+ ch := *(**byte)(v.addr);
+ return int(chanlen(ch));
+}
+
+func (v *ChanValue) Cap() int {
+ ch := *(**byte)(v.addr);
+ return int(chancap(ch));
+}
+
// internal send; non-blocking if b != nil
func (v *ChanValue) send(x Value, b *bool) {
t := v.Type().(*ChanType);
diff --git a/src/pkg/runtime/chan.c b/src/pkg/runtime/chan.c
index 00d020749..46cf18a18 100644
--- a/src/pkg/runtime/chan.c
+++ b/src/pkg/runtime/chan.c
@@ -917,6 +917,18 @@ chanclosed(Hchan *c)
return (c->closed & Rclosed) != 0;
}
+int32
+chanlen(Hchan *c)
+{
+ return c->qcount;
+}
+
+int32
+chancap(Hchan *c)
+{
+ return c->dataqsiz;
+}
+
// closedchan(sel *byte) bool;
void
diff --git a/src/pkg/runtime/reflect.cgo b/src/pkg/runtime/reflect.cgo
index 81c1d4a12..7406e9bc3 100644
--- a/src/pkg/runtime/reflect.cgo
+++ b/src/pkg/runtime/reflect.cgo
@@ -86,6 +86,14 @@ func chanclosed(ch *byte) (r bool) {
r = chanclosed((Hchan*)ch);
}
+func chanlen(ch *byte) (r int32) {
+ r = chanlen((Hchan*)ch);
+}
+
+func chancap(ch *byte) (r int32) {
+ r = chancap((Hchan*)ch);
+}
+
/*
* Go wrappers around the functions in iface.c
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 1e89a4578..d4936afa3 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -493,5 +493,7 @@ void chansend(Hchan*, void*, bool*);
void chanrecv(Hchan*, void*, bool*);
void chanclose(Hchan*);
bool chanclosed(Hchan*);
+int32 chanlen(Hchan*);
+int32 chancap(Hchan*);
void ifaceE2I(struct InterfaceType*, Eface, Iface*);