提交 c277b271 编写于 作者: A aarzilli

cmd/dlv: add flag to make headless server accept multiple clients

上级 3be65a4c
......@@ -32,6 +32,8 @@ var (
Log bool
// Headless is whether to run without terminal.
Headless bool
// Allows multiple clients to connect to the same server
AcceptMulti bool
// Addr is the debugging server listen address.
Addr string
// InitFile is the path to initialization file.
......@@ -74,6 +76,7 @@ func init() {
rootCommand.PersistentFlags().StringVarP(&Addr, "listen", "l", "localhost:0", "Debugging server listen address.")
rootCommand.PersistentFlags().BoolVarP(&Log, "log", "", false, "Enable debugging server logging.")
rootCommand.PersistentFlags().BoolVarP(&Headless, "headless", "", false, "Run debug server only, in headless mode.")
rootCommand.PersistentFlags().BoolVarP(&AcceptMulti, "accept-multiclient", "", false, "Allows a headless server to accept multiple client connection. Note that the server API is not reentrant and clients will have to coordinate")
rootCommand.PersistentFlags().StringVar(&InitFile, "init", "", "Init file, executed by the terminal client.")
rootCommand.PersistentFlags().StringVar(&BuildFlags, "build-flags", buildFlagsDefault, "Build flags, to be passed to the compiler.")
......@@ -351,6 +354,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config) int {
Listener: listener,
ProcessArgs: processArgs,
AttachPid: attachPid,
AcceptMulti: AcceptMulti,
}, Log)
if err := server.Run(); err != nil {
fmt.Fprintln(os.Stderr, err)
......
......@@ -16,4 +16,7 @@ type Config struct {
// AttachPid is the PID of an existing process to which the debugger should
// attach.
AttachPid int
// AcceptMulti configures the server to accept multiple connection
// Note that the server API is not reentrant and clients will have to coordinate
AcceptMulti bool
}
......@@ -23,6 +23,8 @@ type RPCServer struct {
config *service.Config
// listener is used to serve HTTP.
listener net.Listener
// stopChan is used to stop the listener goroutine
stopChan chan struct{}
// debugger is a debugger service.
debugger *debugger.Debugger
}
......@@ -38,13 +40,22 @@ func NewServer(config *service.Config, logEnabled bool) *ServerImpl {
&RPCServer{
config: config,
listener: config.Listener,
stopChan: make(chan struct{}),
},
}
}
// Stop detaches from the debugger and waits for it to stop.
func (s *ServerImpl) Stop(kill bool) error {
return s.s.debugger.Detach(kill)
if s.s.config.AcceptMulti {
close(s.s.stopChan)
s.s.listener.Close()
}
err := s.s.debugger.Detach(kill)
if err != nil {
return err
}
return nil
}
// Run starts a debugger and exposes it with an HTTP server. The debugger
......@@ -60,16 +71,27 @@ func (s *ServerImpl) Run() error {
return err
}
rpcs := grpc.NewServer()
rpcs.Register(s.s)
go func() {
c, err := s.s.listener.Accept()
if err != nil {
panic(err)
}
defer s.s.listener.Close()
rpcs := grpc.NewServer()
rpcs.Register(s.s)
rpcs.ServeCodec(jsonrpc.NewServerCodec(c))
for {
c, err := s.s.listener.Accept()
if err != nil {
select {
case <-s.s.stopChan:
// We were supposed to exit, do nothing and return
return
default:
panic(err)
}
}
go rpcs.ServeCodec(jsonrpc.NewServerCodec(c))
if !s.s.config.AcceptMulti {
break
}
}
}()
return nil
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册