diff options
author | Bas van Kervel <basvankervel@ziggo.nl> | 2015-04-16 18:56:51 +0800 |
---|---|---|
committer | Bas van Kervel <basvankervel@ziggo.nl> | 2015-04-16 18:56:51 +0800 |
commit | 57f93d25bd9a09f4a68307342ad44a5af1d5dc26 (patch) | |
tree | 9101de89d424d7ddf4c62d3390a528193dbb274b /rpc/types.go | |
parent | 205378016fc342a9ee683b3d040b3e7d0e2ebb51 (diff) | |
download | go-tangerine-57f93d25bd9a09f4a68307342ad44a5af1d5dc26.tar.gz go-tangerine-57f93d25bd9a09f4a68307342ad44a5af1d5dc26.tar.zst go-tangerine-57f93d25bd9a09f4a68307342ad44a5af1d5dc26.zip |
admin.stopRPC support added which stops the RPC HTTP listener
Diffstat (limited to 'rpc/types.go')
-rw-r--r-- | rpc/types.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/rpc/types.go b/rpc/types.go index bc9a46ed5..c7dc2cc9a 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -23,6 +23,10 @@ import ( "math/big" "strings" + "errors" + "net" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -257,3 +261,66 @@ type RpcErrorObject struct { Message string `json:"message"` // Data interface{} `json:"data"` } + +type ListenerStoppedError struct { + msg string +} + +func (self ListenerStoppedError) Timout() bool { + return false +} + +func (self ListenerStoppedError) Temporary() bool { + return false +} + +func (self ListenerStoppedError) Error() string { + return self.msg +} + +type ControllableTCPListener struct { + *net.TCPListener + stop chan struct{} +} + +var listenerStoppedError ListenerStoppedError + +func (self *ControllableTCPListener) Stop() { + close(self.stop) +} + +func (self *ControllableTCPListener) Accept() (net.Conn, error) { + for { + self.SetDeadline(time.Now().Add(time.Duration(500 * time.Millisecond))) + c, err := self.TCPListener.AcceptTCP() + + select { + case <-self.stop: + self.TCPListener.Close() + return nil, listenerStoppedError + default: // keep on going + } + + if err != nil { + if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() { + continue // regular timeout + } + } + + return c, err + } +} + +func NewControllableTCPListener(addr string) (*ControllableTCPListener, error) { + wl, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + if tcpl, ok := wl.(*net.TCPListener); ok { + l := &ControllableTCPListener{tcpl, make(chan struct{})} + return l, nil + } + + return nil, errors.New("Unable to create TCP listener for RPC") +} |