From 2c229bac003b30908fd0dc0d69d35044c6cb2425 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Sun, 19 Apr 2015 09:55:41 +0200 Subject: [PATCH] Replaced channel pointer field with non pointer channel --- rpc/http.go | 2 +- rpc/types.go | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rpc/http.go b/rpc/http.go index 882aff7ea..5ff4f613b 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -45,7 +45,7 @@ func Start(pipe *xeth.XEth, config RpcConfig) error { c := cors.New(opts) handler = NewStoppableHandler(c.Handler(JSONRPC(pipe)), l.stop) } else { - handler = JSONRPC(pipe) + handler = NewStoppableHandler(JSONRPC(pipe), l.stop) } go http.Serve(l, handler) diff --git a/rpc/types.go b/rpc/types.go index b33621fef..71ed5df49 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -275,20 +275,21 @@ func (self ListenerStoppedError) Error() string { var listenerStoppedError = ListenerStoppedError{"Listener stopped"} +// When https://github.com/golang/go/issues/4674 is fixed this could be replaced type StoppableTCPListener struct { *net.TCPListener - stop *chan struct{} // closed when the listener must stop + stop chan struct{} // closed when the listener must stop } // Wraps the default handler and checks if the RPC service was stopped. In that case it returns an // error indicating that the service was stopped. This will only happen for connections which are // kept open (HTTP keep-alive) when the RPC service was shutdown. -func NewStoppableHandler(h http.Handler, stop *chan struct{}) http.Handler { +func NewStoppableHandler(h http.Handler, stop chan struct{}) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { select { - case <-*stop: + case <-stop: w.Header().Set("Content-Type", "application/json") - jsonerr := &RpcErrorObject{-32603, "RPC service stopt"} + jsonerr := &RpcErrorObject{-32603, "RPC service stopped"} send(w, &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: nil, Error: jsonerr}) default: h.ServeHTTP(w, r) @@ -298,7 +299,7 @@ func NewStoppableHandler(h http.Handler, stop *chan struct{}) http.Handler { // Stop the listener and all accepted and still active connections. func (self *StoppableTCPListener) Stop() { - close(*self.stop) + close(self.stop) } func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { @@ -309,7 +310,7 @@ func NewStoppableTCPListener(addr string) (*StoppableTCPListener, error) { if tcpl, ok := wl.(*net.TCPListener); ok { stop := make(chan struct{}) - l := &StoppableTCPListener{tcpl, &stop} + l := &StoppableTCPListener{tcpl, stop} return l, nil } @@ -322,8 +323,10 @@ func (self *StoppableTCPListener) Accept() (net.Conn, error) { c, err := self.TCPListener.AcceptTCP() select { - case <-*self.stop: - c.Close() + case <-self.stop: + if c != nil { // accept timeout + c.Close() + } self.TCPListener.Close() return nil, listenerStoppedError default: @@ -341,12 +344,12 @@ func (self *StoppableTCPListener) Accept() (net.Conn, error) { type ClosableConnection struct { *net.TCPConn - closed *chan struct{} + closed chan struct{} } func (self *ClosableConnection) Read(b []byte) (n int, err error) { select { - case <-*self.closed: + case <-self.closed: self.TCPConn.Close() return 0, io.EOF default: