aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/rpc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-01-09 01:23:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 01:23:08 +0000
commit1a2f01efa63036a5104f203a4789e682c0e0915d (patch)
tree373e15778dc8295354584e1f86915ae493b604ff /libgo/go/net/rpc
parent8799df67f2dab88f9fda11739c501780a85575e2 (diff)
downloadgcc-1a2f01efa63036a5104f203a4789e682c0e0915d.zip
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.gz
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.bz2
libgo: update to Go1.10beta1
Update the Go library to the 1.10beta1 release. Requires a few changes to the compiler for modifications to the map runtime code, and to handle some nowritebarrier cases in the runtime. Reviewed-on: https://go-review.googlesource.com/86455 gotools/: * Makefile.am (go_cmd_vet_files): New variable. (go_cmd_buildid_files, go_cmd_test2json_files): New variables. (s-zdefaultcc): Change from constants to functions. (noinst_PROGRAMS): Add vet, buildid, and test2json. (cgo$(EXEEXT)): Link against $(LIBGOTOOL). (vet$(EXEEXT)): New target. (buildid$(EXEEXT)): New target. (test2json$(EXEEXT)): New target. (install-exec-local): Install all $(noinst_PROGRAMS). (uninstall-local): Uninstasll all $(noinst_PROGRAMS). (check-go-tool): Depend on $(noinst_PROGRAMS). Copy down objabi.go. (check-runtime): Depend on $(noinst_PROGRAMS). (check-cgo-test, check-carchive-test): Likewise. (check-vet): New target. (check): Depend on check-vet. Look at cmd_vet-testlog. (.PHONY): Add check-vet. * Makefile.in: Rebuild. From-SVN: r256365
Diffstat (limited to 'libgo/go/net/rpc')
-rw-r--r--libgo/go/net/rpc/server.go14
-rw-r--r--libgo/go/net/rpc/server_test.go52
2 files changed, 63 insertions, 3 deletions
diff --git a/libgo/go/net/rpc/server.go b/libgo/go/net/rpc/server.go
index 29aae7e..a021292 100644
--- a/libgo/go/net/rpc/server.go
+++ b/libgo/go/net/rpc/server.go
@@ -372,7 +372,10 @@ func (m *methodType) NumCalls() (n uint) {
return n
}
-func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+ if wg != nil {
+ defer wg.Done()
+ }
mtype.Lock()
mtype.numCalls++
mtype.Unlock()
@@ -456,6 +459,7 @@ func (server *Server) ServeConn(conn io.ReadWriteCloser) {
// decode requests and encode responses.
func (server *Server) ServeCodec(codec ServerCodec) {
sending := new(sync.Mutex)
+ wg := new(sync.WaitGroup)
for {
service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
if err != nil {
@@ -472,8 +476,12 @@ func (server *Server) ServeCodec(codec ServerCodec) {
}
continue
}
- go service.call(server, sending, mtype, req, argv, replyv, codec)
+ wg.Add(1)
+ go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
}
+ // We've seen that there are no more requests.
+ // Wait for responses to be sent before closing codec.
+ wg.Wait()
codec.Close()
}
@@ -493,7 +501,7 @@ func (server *Server) ServeRequest(codec ServerCodec) error {
}
return err
}
- service.call(server, sending, mtype, req, argv, replyv, codec)
+ service.call(server, sending, nil, mtype, req, argv, replyv, codec)
return nil
}
diff --git a/libgo/go/net/rpc/server_test.go b/libgo/go/net/rpc/server_test.go
index fb97f82..e5d7fe0 100644
--- a/libgo/go/net/rpc/server_test.go
+++ b/libgo/go/net/rpc/server_test.go
@@ -75,6 +75,11 @@ func (t *Arith) Error(args *Args, reply *Reply) error {
panic("ERROR")
}
+func (t *Arith) SleepMilli(args *Args, reply *Reply) error {
+ time.Sleep(time.Duration(args.A) * time.Millisecond)
+ return nil
+}
+
type hidden int
func (t *hidden) Exported(args Args, reply *Reply) error {
@@ -693,6 +698,53 @@ func TestAcceptExitAfterListenerClose(t *testing.T) {
newServer.Accept(l)
}
+func TestShutdown(t *testing.T) {
+ var l net.Listener
+ l, _ = listenTCP()
+ ch := make(chan net.Conn, 1)
+ go func() {
+ defer l.Close()
+ c, err := l.Accept()
+ if err != nil {
+ t.Error(err)
+ }
+ ch <- c
+ }()
+ c, err := net.Dial("tcp", l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ c1 := <-ch
+ if c1 == nil {
+ t.Fatal(err)
+ }
+
+ newServer := NewServer()
+ newServer.Register(new(Arith))
+ go newServer.ServeConn(c1)
+
+ args := &Args{7, 8}
+ reply := new(Reply)
+ client := NewClient(c)
+ err = client.Call("Arith.Add", args, reply)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // On an unloaded system 10ms is usually enough to fail 100% of the time
+ // with a broken server. On a loaded system, a broken server might incorrectly
+ // be reported as passing, but we're OK with that kind of flakiness.
+ // If the code is correct, this test will never fail, regardless of timeout.
+ args.A = 10 // 10 ms
+ done := make(chan *Call, 1)
+ call := client.Go("Arith.SleepMilli", args, reply, done)
+ c.(*net.TCPConn).CloseWrite()
+ <-done
+ if call.Error != nil {
+ t.Fatal(err)
+ }
+}
+
func benchmarkEndToEnd(dial func() (*Client, error), b *testing.B) {
once.Do(startServer)
client, err := dial()