aboutsummaryrefslogtreecommitdiffstats
path: root/rpc/comms/ipc.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-10-29 20:28:00 +0800
committerFelix Lange <fjl@twurst.com>2015-10-30 00:26:26 +0800
commitfbdb44dcc17240a01b45e55d3aa4e4b8db0868cd (patch)
tree2363ce8738074226cfedf8ede1612e0ef3a03494 /rpc/comms/ipc.go
parent56f8699a6c6bfe613d2ab28c47631a1f4a29e36f (diff)
downloaddexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar.gz
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar.bz2
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar.lz
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar.xz
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.tar.zst
dexon-fbdb44dcc17240a01b45e55d3aa4e4b8db0868cd.zip
cmd/utils, rpc/comms: stop XEth when IPC connection ends
There are a bunch of changes required to make this work: - in miner: allow unregistering agents, fix RemoteAgent.Stop - in eth/filters: make FilterSystem.Stop not crash - in rpc/comms: move listen loop to platform-independent code Fixes #1930. I ran the shell loop there for a few minutes and didn't see any changes in the memory profile.
Diffstat (limited to 'rpc/comms/ipc.go')
-rw-r--r--rpc/comms/ipc.go43
1 files changed, 41 insertions, 2 deletions
diff --git a/rpc/comms/ipc.go b/rpc/comms/ipc.go
index 3de659b65..882d62ab4 100644
--- a/rpc/comms/ipc.go
+++ b/rpc/comms/ipc.go
@@ -20,13 +20,22 @@ import (
"fmt"
"math/rand"
"net"
+ "os"
"encoding/json"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
)
+type Stopper interface {
+ Stop()
+}
+
+type InitFunc func(conn net.Conn) (Stopper, shared.EthereumApi, error)
+
type IpcConfig struct {
Endpoint string
}
@@ -90,8 +99,38 @@ func NewIpcClient(cfg IpcConfig, codec codec.Codec) (*ipcClient, error) {
}
// Start IPC server
-func StartIpc(cfg IpcConfig, codec codec.Codec, initializer func(conn net.Conn) (shared.EthereumApi, error)) error {
- return startIpc(cfg, codec, initializer)
+func StartIpc(cfg IpcConfig, codec codec.Codec, initializer InitFunc) error {
+ l, err := ipcListen(cfg)
+ if err != nil {
+ return err
+ }
+ go ipcLoop(cfg, codec, initializer, l)
+ return nil
+}
+
+func ipcLoop(cfg IpcConfig, codec codec.Codec, initializer InitFunc, l net.Listener) {
+ glog.V(logger.Info).Infof("IPC service started (%s)\n", cfg.Endpoint)
+ defer os.Remove(cfg.Endpoint)
+ defer l.Close()
+ for {
+ conn, err := l.Accept()
+ if err != nil {
+ glog.V(logger.Debug).Infof("accept: %v", err)
+ return
+ }
+ id := newIpcConnId()
+ go func() {
+ defer conn.Close()
+ glog.V(logger.Debug).Infof("new connection with id %06d started", id)
+ stopper, api, err := initializer(conn)
+ if err != nil {
+ glog.V(logger.Error).Infof("Unable to initialize IPC connection: %v", err)
+ return
+ }
+ defer stopper.Stop()
+ handle(id, conn, api, codec)
+ }()
+ }
}
func newIpcConnId() int {