From c52861cfd63fc07e77cc3a441e53df3b13085516 Mon Sep 17 00:00:00 2001 From: Massimiliano Pippi Date: Thu, 29 Aug 2019 19:05:39 +0200 Subject: [PATCH] rewrite the list logic --- commands/board/list.go | 7 +- commands/bundled_tools_serial_discovery.go | 132 +++++++++------------ 2 files changed, 54 insertions(+), 85 deletions(-) diff --git a/commands/board/list.go b/commands/board/list.go index e8157422f7a..1df56f696bc 100644 --- a/commands/board/list.go +++ b/commands/board/list.go @@ -83,12 +83,7 @@ func List(instanceID int32) ([]*rpc.DetectedPort, error) { return nil, errors.New("invalid instance") } - serialDiscovery, err := commands.NewBuiltinSerialDiscovery(pm) - if err != nil { - return nil, errors.Wrap(err, "unable to instance serial-discovery") - } - - ports, err := serialDiscovery.List() + ports, err := commands.ListBoards(pm) if err != nil { return nil, errors.Wrap(err, "error getting port list from serial-discovery") } diff --git a/commands/bundled_tools_serial_discovery.go b/commands/bundled_tools_serial_discovery.go index ee5e8a976b0..1dd5077bfee 100644 --- a/commands/bundled_tools_serial_discovery.go +++ b/commands/bundled_tools_serial_discovery.go @@ -20,9 +20,6 @@ package commands import ( "encoding/json" "fmt" - "io" - "os/exec" - "strings" "sync" "time" @@ -36,6 +33,7 @@ import ( ) var ( + mutex = sync.Mutex{} sdVersion = semver.ParseRelaxed("1.0.0") flavors = []*cores.Flavor{ { @@ -101,16 +99,6 @@ var ( } ) -// SerialDiscovery is an instance of a discovery tool -type SerialDiscovery struct { - sync.Mutex - ID string - in io.WriteCloser - out io.ReadCloser - outJSON *json.Decoder - cmd *exec.Cmd -} - // BoardPort is a generic port descriptor type BoardPort struct { Address string `json:"address"` @@ -126,100 +114,86 @@ type eventJSON struct { Ports []*BoardPort `json:"ports"` } -// NewBuiltinSerialDiscovery returns a wrapper to control the serial-discovery program -func NewBuiltinSerialDiscovery(pm *packagemanager.PackageManager) (*SerialDiscovery, error) { +// ListBoards foo +func ListBoards(pm *packagemanager.PackageManager) ([]*BoardPort, error) { + // ensure the connection to the discoverer is unique to avoid messing up + // the messages exchanged + mutex.Lock() + defer mutex.Unlock() + + // get the bundled tool t, err := getBuiltinSerialDiscoveryTool(pm) if err != nil { return nil, err } + // determine if it's installed if !t.IsInstalled() { return nil, fmt.Errorf("missing serial-discovery tool") } - cmdArgs := []string{ - t.InstallDir.Join("serial-discovery").String(), - } - - cmd, err := executils.Command(cmdArgs) + // build the command to be executed + args := []string{t.InstallDir.Join("serial-discovery").String()} + cmd, err := executils.Command(args) if err != nil { return nil, errors.Wrap(err, "creating discovery process") } - return &SerialDiscovery{ - ID: strings.Join(cmdArgs, " "), - cmd: cmd, - }, nil -} - -// Start starts the specified discovery -func (d *SerialDiscovery) start() error { - if in, err := d.cmd.StdinPipe(); err == nil { - d.in = in - } else { - return fmt.Errorf("creating stdin pipe for discovery: %s", err) - } - - if out, err := d.cmd.StdoutPipe(); err == nil { - d.out = out - d.outJSON = json.NewDecoder(d.out) - } else { - return fmt.Errorf("creating stdout pipe for discovery: %s", err) + // attach in/out pipes to the process + in, err := cmd.StdinPipe() + if err != nil { + return nil, fmt.Errorf("creating stdin pipe for discovery: %s", err) } - if err := d.cmd.Start(); err != nil { - return fmt.Errorf("starting discovery process: %s", err) + out, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("creating stdout pipe for discovery: %s", err) } + outJSON := json.NewDecoder(out) - return nil -} - -// List retrieve the port list from this discovery -func (d *SerialDiscovery) List() ([]*BoardPort, error) { - // ensure the connection to the discoverer is unique to avoid messing up - // the messages exchanged - d.Lock() - defer d.Unlock() - - if err := d.start(); err != nil { - return nil, fmt.Errorf("discovery hasn't started: %v", err) + // start the process + if err := cmd.Start(); err != nil { + return nil, fmt.Errorf("starting discovery process: %s", err) } - if _, err := d.in.Write([]byte("LIST\n")); err != nil { + // send the LIST command + if _, err := in.Write([]byte("LIST\n")); err != nil { return nil, fmt.Errorf("sending LIST command to discovery: %s", err) } + + // read the response from the pipe + decodeResult := make(chan error) var event eventJSON - done := make(chan bool) - timeout := false go func() { - select { - case <-done: - case <-time.After(10 * time.Second): - timeout = true - d.close() - } + decodeResult <- outJSON.Decode(&event) }() - if err := d.outJSON.Decode(&event); err != nil { - if timeout { - return nil, fmt.Errorf("decoding LIST command: timeout") + + var finalError error + var retVal []*BoardPort + + // wait for the response + select { + case err := <-decodeResult: + if err == nil { + retVal = event.Ports + } else { + finalError = err } - return nil, fmt.Errorf("decoding LIST command: %s", err) + case <-time.After(10 * time.Second): + finalError = fmt.Errorf("decoding LIST command: timeout") } - done <- true - return event.Ports, d.close() -} -// Close stops the Discovery and free the resources -func (d *SerialDiscovery) close() error { - _, _ = d.in.Write([]byte("QUIT\n")) - _ = d.in.Close() - _ = d.out.Close() - timer := time.AfterFunc(time.Second, func() { - _ = d.cmd.Process.Kill() + // tell the process to quit + in.Write([]byte("QUIT\n")) + in.Close() + out.Close() + // kill the process if it takes too long to quit + time.AfterFunc(time.Second, func() { + cmd.Process.Kill() }) - err := d.cmd.Wait() - _ = timer.Stop() - return err + cmd.Wait() + + return retVal, finalError } func getBuiltinSerialDiscoveryTool(pm *packagemanager.PackageManager) (*cores.ToolRelease, error) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy