Skip to content

Commit 549b0fb

Browse files
author
Massimiliano Pippi
authored
rewrite the list logic (arduino#382)
1 parent c67e23a commit 549b0fb

File tree

2 files changed

+54
-85
lines changed

2 files changed

+54
-85
lines changed

commands/board/list.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@ func List(instanceID int32) ([]*rpc.DetectedPort, error) {
8383
return nil, errors.New("invalid instance")
8484
}
8585

86-
serialDiscovery, err := commands.NewBuiltinSerialDiscovery(pm)
87-
if err != nil {
88-
return nil, errors.Wrap(err, "unable to instance serial-discovery")
89-
}
90-
91-
ports, err := serialDiscovery.List()
86+
ports, err := commands.ListBoards(pm)
9287
if err != nil {
9388
return nil, errors.Wrap(err, "error getting port list from serial-discovery")
9489
}

commands/bundled_tools_serial_discovery.go

Lines changed: 53 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ package commands
2020
import (
2121
"encoding/json"
2222
"fmt"
23-
"io"
24-
"os/exec"
25-
"strings"
2623
"sync"
2724
"time"
2825

@@ -36,6 +33,7 @@ import (
3633
)
3734

3835
var (
36+
mutex = sync.Mutex{}
3937
sdVersion = semver.ParseRelaxed("1.0.0")
4038
flavors = []*cores.Flavor{
4139
{
@@ -101,16 +99,6 @@ var (
10199
}
102100
)
103101

104-
// SerialDiscovery is an instance of a discovery tool
105-
type SerialDiscovery struct {
106-
sync.Mutex
107-
ID string
108-
in io.WriteCloser
109-
out io.ReadCloser
110-
outJSON *json.Decoder
111-
cmd *exec.Cmd
112-
}
113-
114102
// BoardPort is a generic port descriptor
115103
type BoardPort struct {
116104
Address string `json:"address"`
@@ -126,100 +114,86 @@ type eventJSON struct {
126114
Ports []*BoardPort `json:"ports"`
127115
}
128116

129-
// NewBuiltinSerialDiscovery returns a wrapper to control the serial-discovery program
130-
func NewBuiltinSerialDiscovery(pm *packagemanager.PackageManager) (*SerialDiscovery, error) {
117+
// ListBoards foo
118+
func ListBoards(pm *packagemanager.PackageManager) ([]*BoardPort, error) {
119+
// ensure the connection to the discoverer is unique to avoid messing up
120+
// the messages exchanged
121+
mutex.Lock()
122+
defer mutex.Unlock()
123+
124+
// get the bundled tool
131125
t, err := getBuiltinSerialDiscoveryTool(pm)
132126
if err != nil {
133127
return nil, err
134128
}
135129

130+
// determine if it's installed
136131
if !t.IsInstalled() {
137132
return nil, fmt.Errorf("missing serial-discovery tool")
138133
}
139134

140-
cmdArgs := []string{
141-
t.InstallDir.Join("serial-discovery").String(),
142-
}
143-
144-
cmd, err := executils.Command(cmdArgs)
135+
// build the command to be executed
136+
args := []string{t.InstallDir.Join("serial-discovery").String()}
137+
cmd, err := executils.Command(args)
145138
if err != nil {
146139
return nil, errors.Wrap(err, "creating discovery process")
147140
}
148141

149-
return &SerialDiscovery{
150-
ID: strings.Join(cmdArgs, " "),
151-
cmd: cmd,
152-
}, nil
153-
}
154-
155-
// Start starts the specified discovery
156-
func (d *SerialDiscovery) start() error {
157-
if in, err := d.cmd.StdinPipe(); err == nil {
158-
d.in = in
159-
} else {
160-
return fmt.Errorf("creating stdin pipe for discovery: %s", err)
161-
}
162-
163-
if out, err := d.cmd.StdoutPipe(); err == nil {
164-
d.out = out
165-
d.outJSON = json.NewDecoder(d.out)
166-
} else {
167-
return fmt.Errorf("creating stdout pipe for discovery: %s", err)
142+
// attach in/out pipes to the process
143+
in, err := cmd.StdinPipe()
144+
if err != nil {
145+
return nil, fmt.Errorf("creating stdin pipe for discovery: %s", err)
168146
}
169147

170-
if err := d.cmd.Start(); err != nil {
171-
return fmt.Errorf("starting discovery process: %s", err)
148+
out, err := cmd.StdoutPipe()
149+
if err != nil {
150+
return nil, fmt.Errorf("creating stdout pipe for discovery: %s", err)
172151
}
152+
outJSON := json.NewDecoder(out)
173153

174-
return nil
175-
}
176-
177-
// List retrieve the port list from this discovery
178-
func (d *SerialDiscovery) List() ([]*BoardPort, error) {
179-
// ensure the connection to the discoverer is unique to avoid messing up
180-
// the messages exchanged
181-
d.Lock()
182-
defer d.Unlock()
183-
184-
if err := d.start(); err != nil {
185-
return nil, fmt.Errorf("discovery hasn't started: %v", err)
154+
// start the process
155+
if err := cmd.Start(); err != nil {
156+
return nil, fmt.Errorf("starting discovery process: %s", err)
186157
}
187158

188-
if _, err := d.in.Write([]byte("LIST\n")); err != nil {
159+
// send the LIST command
160+
if _, err := in.Write([]byte("LIST\n")); err != nil {
189161
return nil, fmt.Errorf("sending LIST command to discovery: %s", err)
190162
}
163+
164+
// read the response from the pipe
165+
decodeResult := make(chan error)
191166
var event eventJSON
192-
done := make(chan bool)
193-
timeout := false
194167
go func() {
195-
select {
196-
case <-done:
197-
case <-time.After(10 * time.Second):
198-
timeout = true
199-
d.close()
200-
}
168+
decodeResult <- outJSON.Decode(&event)
201169
}()
202-
if err := d.outJSON.Decode(&event); err != nil {
203-
if timeout {
204-
return nil, fmt.Errorf("decoding LIST command: timeout")
170+
171+
var finalError error
172+
var retVal []*BoardPort
173+
174+
// wait for the response
175+
select {
176+
case err := <-decodeResult:
177+
if err == nil {
178+
retVal = event.Ports
179+
} else {
180+
finalError = err
205181
}
206-
return nil, fmt.Errorf("decoding LIST command: %s", err)
182+
case <-time.After(10 * time.Second):
183+
finalError = fmt.Errorf("decoding LIST command: timeout")
207184
}
208-
done <- true
209-
return event.Ports, d.close()
210-
}
211185

212-
// Close stops the Discovery and free the resources
213-
func (d *SerialDiscovery) close() error {
214-
_, _ = d.in.Write([]byte("QUIT\n"))
215-
_ = d.in.Close()
216-
_ = d.out.Close()
217-
timer := time.AfterFunc(time.Second, func() {
218-
_ = d.cmd.Process.Kill()
186+
// tell the process to quit
187+
in.Write([]byte("QUIT\n"))
188+
in.Close()
189+
out.Close()
190+
// kill the process if it takes too long to quit
191+
time.AfterFunc(time.Second, func() {
192+
cmd.Process.Kill()
219193
})
220-
err := d.cmd.Wait()
221-
_ = timer.Stop()
222-
return err
194+
cmd.Wait()
195+
196+
return retVal, finalError
223197
}
224198

225199
func getBuiltinSerialDiscoveryTool(pm *packagemanager.PackageManager) (*cores.ToolRelease, error) {

0 commit comments

Comments
 (0)
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