]> Cypherpunks repositories - gostls13.git/commitdiff
add Close() and Closed() to ChanValue
authorRuss Cox <rsc@golang.org>
Wed, 26 Aug 2009 17:47:18 +0000 (10:47 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 26 Aug 2009 17:47:18 +0000 (10:47 -0700)
R=r
DELTA=60  (56 added, 3 deleted, 1 changed)
OCL=33868
CL=33872

src/pkg/reflect/all_test.go
src/pkg/reflect/value.go
src/pkg/runtime/chan.c
src/pkg/runtime/reflect.cgo
src/pkg/runtime/runtime.h

index 5f0211c6a598a953047f3a0b197996d0f578aecf..3a1c220daf780d79143b2b67177df9f7b353b053 100644 (file)
@@ -726,6 +726,25 @@ func TestChan(t *testing.T) {
                                t.Errorf("TrySend 6, recv %d", i);
                        }
                }
+
+               // Close
+               c <- 123;
+               cv.Close();
+               if cv.Closed() {
+                       t.Errorf("closed too soon - 1");
+               }
+               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");
+               }
        }
 
        // check creation of unbuffered channel
index e2df30b799e945d39f20ba33a7b8c17b813d47ae..daa3f11baaa3646b1e0397bea8e38397334b429d 100644 (file)
@@ -634,6 +634,20 @@ func (v *ChanValue) Get() uintptr {
 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 chanclose(ch *byte)
+
+// 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);
+       chanclose(ch);
+}
 
 // internal send; non-blocking if b != nil
 func (v *ChanValue) send(x Value, b *bool) {
index ceebebf8b3880e70af15a51b2c73888d75b62937..00d0207493a8bf135bf4df145eabefe70d81ff23 100644 (file)
@@ -905,14 +905,24 @@ sys·closechan(Hchan *c)
        unlock(&chanlock);
 }
 
+void
+chanclose(Hchan *c)
+{
+       sys·closechan(c);
+}
+
+bool
+chanclosed(Hchan *c)
+{
+       return (c->closed & Rclosed) != 0;
+}
+
+
 // closedchan(sel *byte) bool;
 void
 sys·closedchan(Hchan *c, bool closed)
 {
-       // test Rclosed
-       closed = 0;
-       if(c->closed & Rclosed)
-               closed = 1;
+       closed = chanclosed(c);
        FLUSH(&closed);
 }
 
index 016b9e9ec013361d281785dbbc67ff606cbbda76..81c1d4a12309299a89b92c2dbbb04c96d13e1ec3 100644 (file)
@@ -78,6 +78,14 @@ func chanrecv(ch *byte, val *byte, pres *bool) {
        chanrecv((Hchan*)ch, val, pres);
 }
 
+func chanclose(ch *byte) {
+       chanclose((Hchan*)ch);
+}
+
+func chanclosed(ch *byte) (r bool) {
+       r = chanclosed((Hchan*)ch);
+}
+
 
 /*
  * Go wrappers around the functions in iface.c
index c346c692f69439a2fc95b8ad271b022ac34ebb38..1e89a4578056b47553926712d8ccd21e0cb30c97 100644 (file)
@@ -73,7 +73,7 @@ typedef       struct  Hchan           Hchan;
  * amd64: allocated downwards from R15
  * x86: allocated upwards from 0(FS)
  * arm: allocated upwards from R9
- * 
+ *
  * every C file linked into a Go program must include runtime.h
  * so that the C compiler knows to avoid other uses of these registers.
  * the Go compilers know to avoid them.
@@ -491,5 +491,7 @@ Hmap*       makemap(uint32, uint32, uint32, uint32, uint32);
 Hchan* makechan(uint32, uint32, uint32);
 void   chansend(Hchan*, void*, bool*);
 void   chanrecv(Hchan*, void*, bool*);
+void   chanclose(Hchan*);
+bool   chanclosed(Hchan*);
 
 void   ifaceE2I(struct InterfaceType*, Eface, Iface*);