Skip to content

Commit 70bbe39

Browse files
author
Federico Fissore
committed
Network and Serial board ports discovery is now asynchronous, hence it does not block "tools" menu any more.
Fixes #2788
1 parent 046f335 commit 70bbe39

File tree

7 files changed

+265
-123
lines changed

7 files changed

+265
-123
lines changed

arduino-core/src/cc/arduino/packages/Discovery.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,27 @@
2929

3030
package cc.arduino.packages;
3131

32-
import processing.app.helpers.PreferencesMap;
33-
3432
import java.util.List;
3533

3634
public interface Discovery {
3735

38-
/**
39-
* Set discovery preferences
40-
*
41-
* @param options
42-
*/
43-
public void setPreferences(PreferencesMap options);
44-
4536
/**
4637
* Start discovery service
4738
*
4839
* @throws Exception
4940
*/
50-
public void start() throws Exception;
41+
void start() throws Exception;
5142

5243
/**
5344
* Stop discovery service
5445
*/
55-
public void stop() throws Exception;
46+
void stop() throws Exception;
5647

5748
/**
5849
* Return the list of discovered ports.
5950
*
6051
* @return
6152
*/
62-
public List<BoardPort> discovery();
53+
List<BoardPort> listDiscoveredBoards();
6354

6455
}

arduino-core/src/cc/arduino/packages/DiscoveryManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void run() {
6363
try {
6464
d.stop();
6565
} catch (Exception e) {
66-
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
66+
e.printStackTrace(); //just printing as the JVM is terminating
6767
}
6868
}
6969
}
@@ -74,7 +74,7 @@ public void run() {
7474
public List<BoardPort> discovery() {
7575
List<BoardPort> res = new ArrayList<BoardPort>();
7676
for (Discovery d : discoverers) {
77-
res.addAll(d.discovery());
77+
res.addAll(d.listDiscoveredBoards());
7878
}
7979
return res;
8080
}

arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,80 +31,65 @@
3131

3232
import cc.arduino.packages.BoardPort;
3333
import cc.arduino.packages.Discovery;
34+
import cc.arduino.packages.discoverers.network.BoardReachabilityFilter;
3435
import cc.arduino.packages.discoverers.network.NetworkChecker;
3536
import processing.app.BaseNoGui;
36-
import processing.app.helpers.NetUtils;
3737
import processing.app.helpers.PreferencesMap;
3838
import processing.app.zeroconf.jmdns.ArduinoDNSTaskStarter;
3939

4040
import javax.jmdns.*;
4141
import javax.jmdns.impl.DNSTaskStarter;
4242
import java.io.IOException;
4343
import java.net.InetAddress;
44-
import java.net.UnknownHostException;
4544
import java.util.*;
4645

4746
public class NetworkDiscovery implements Discovery, ServiceListener, cc.arduino.packages.discoverers.network.NetworkTopologyListener {
4847

49-
private Timer timer;
50-
private final List<BoardPort> ports;
48+
private final List<BoardPort> boardPortsDiscoveredWithJmDNS;
5149
private final Map<InetAddress, JmDNS> mappedJmDNSs;
50+
private Timer networkCheckerTimer;
51+
private Timer boardReachabilityFilterTimer;
52+
private final List<BoardPort> reachableBoardPorts;
5253

5354
public NetworkDiscovery() {
5455
DNSTaskStarter.Factory.setClassDelegate(new ArduinoDNSTaskStarter());
55-
this.ports = new ArrayList<BoardPort>();
56+
this.boardPortsDiscoveredWithJmDNS = new LinkedList<BoardPort>();
5657
this.mappedJmDNSs = new Hashtable<InetAddress, JmDNS>();
58+
this.reachableBoardPorts = new LinkedList<BoardPort>();
5759
}
5860

5961
@Override
60-
public List<BoardPort> discovery() {
61-
List<BoardPort> boardPorts = clonePortsList();
62-
Iterator<BoardPort> boardPortIterator = boardPorts.iterator();
63-
while (boardPortIterator.hasNext()) {
64-
try {
65-
BoardPort board = boardPortIterator.next();
66-
67-
InetAddress inetAddress = InetAddress.getByName(board.getAddress());
68-
int broadcastedPort = Integer.valueOf(board.getPrefs().get("port"));
69-
70-
List<Integer> ports = new LinkedList<Integer>();
71-
ports.add(broadcastedPort);
72-
73-
//dirty code: allows non up to date yuns to be discovered. Newer yuns will broadcast port 22
74-
if (broadcastedPort == 80) {
75-
ports.add(0, 22);
76-
}
77-
78-
boolean reachable = NetUtils.isReachable(inetAddress, ports);
79-
if (!reachable) {
80-
boardPortIterator.remove();
81-
}
82-
} catch (UnknownHostException e) {
83-
boardPortIterator.remove();
84-
}
62+
public List<BoardPort> listDiscoveredBoards() {
63+
synchronized (reachableBoardPorts) {
64+
return new LinkedList<BoardPort>(reachableBoardPorts);
8565
}
86-
return boardPorts;
8766
}
8867

89-
private List<BoardPort> clonePortsList() {
90-
synchronized (this) {
91-
return new ArrayList<BoardPort>(this.ports);
68+
public void setReachableBoardPorts(List<BoardPort> newReachableBoardPorts) {
69+
synchronized (reachableBoardPorts) {
70+
this.reachableBoardPorts.clear();
71+
this.reachableBoardPorts.addAll(newReachableBoardPorts);
9272
}
9373
}
9474

95-
@Override
96-
public void setPreferences(PreferencesMap options) {
75+
public List<BoardPort> getBoardPortsDiscoveredWithJmDNS() {
76+
synchronized (boardPortsDiscoveredWithJmDNS) {
77+
return new LinkedList<BoardPort>(boardPortsDiscoveredWithJmDNS);
78+
}
9779
}
9880

9981
@Override
10082
public void start() throws IOException {
101-
this.timer = new Timer(this.getClass().getName() + " timer");
102-
new NetworkChecker(this, NetworkTopologyDiscovery.Factory.getInstance()).start(timer);
83+
this.networkCheckerTimer = new Timer(NetworkChecker.class.getName());
84+
new NetworkChecker(this, NetworkTopologyDiscovery.Factory.getInstance()).start(networkCheckerTimer);
85+
this.boardReachabilityFilterTimer = new Timer(BoardReachabilityFilter.class.getName());
86+
new BoardReachabilityFilter(this).start(boardReachabilityFilterTimer);
10387
}
10488

10589
@Override
10690
public void stop() throws IOException {
107-
timer.purge();
91+
this.networkCheckerTimer.purge();
92+
this.boardReachabilityFilterTimer.purge();
10893
// we don't close each JmDNS instance as it's too slow
10994
}
11095

@@ -125,10 +110,11 @@ public void serviceAdded(ServiceEvent serviceEvent) {
125110
@Override
126111
public void serviceRemoved(ServiceEvent serviceEvent) {
127112
String name = serviceEvent.getName();
128-
synchronized (this) {
129-
for (BoardPort port : ports) {
130-
if (port.getBoardName().equals(name))
131-
ports.remove(port);
113+
synchronized (boardPortsDiscoveredWithJmDNS) {
114+
for (BoardPort port : boardPortsDiscoveredWithJmDNS) {
115+
if (port.getBoardName().equals(name)) {
116+
boardPortsDiscoveredWithJmDNS.remove(port);
117+
}
132118
}
133119
}
134120
}
@@ -147,10 +133,9 @@ public void serviceResolved(ServiceEvent serviceEvent) {
147133
board = info.getPropertyString("board");
148134
prefs.put("board", board);
149135
prefs.put("distro_version", info.getPropertyString("distro_version"));
136+
prefs.put("port", "" + info.getPort());
150137
}
151138

152-
prefs.put("port", "" + info.getPort());
153-
154139
String label = name + " at " + address;
155140
if (board != null) {
156141
String boardName = BaseNoGui.getPlatform().resolveDeviceByBoardID(BaseNoGui.packages, board);
@@ -166,19 +151,21 @@ public void serviceResolved(ServiceEvent serviceEvent) {
166151
port.setPrefs(prefs);
167152
port.setLabel(label);
168153

169-
synchronized (this) {
154+
synchronized (boardPortsDiscoveredWithJmDNS) {
170155
removeDuplicateBoards(port);
171-
ports.add(port);
156+
boardPortsDiscoveredWithJmDNS.add(port);
172157
}
173158
}
174159
}
175160

176161
private void removeDuplicateBoards(BoardPort newBoard) {
177-
Iterator<BoardPort> iterator = ports.iterator();
178-
while (iterator.hasNext()) {
179-
BoardPort board = iterator.next();
180-
if (newBoard.getAddress().equals(board.getAddress())) {
181-
iterator.remove();
162+
synchronized (boardPortsDiscoveredWithJmDNS) {
163+
Iterator<BoardPort> iterator = boardPortsDiscoveredWithJmDNS.iterator();
164+
while (iterator.hasNext()) {
165+
BoardPort board = iterator.next();
166+
if (newBoard.getAddress().equals(board.getAddress())) {
167+
iterator.remove();
168+
}
182169
}
183170
}
184171
}

arduino-core/src/cc/arduino/packages/discoverers/SerialDiscovery.java

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,11 @@
3131

3232
import cc.arduino.packages.BoardPort;
3333
import cc.arduino.packages.Discovery;
34-
import processing.app.BaseNoGui;
35-
import processing.app.Platform;
36-
import processing.app.Serial;
37-
import processing.app.debug.TargetBoard;
38-
import processing.app.helpers.PreferencesMap;
34+
import cc.arduino.packages.discoverers.serial.SerialBoardsLister;
3935

40-
import java.util.ArrayList;
41-
import java.util.HashMap;
36+
import java.util.LinkedList;
4237
import java.util.List;
43-
import java.util.Map;
38+
import java.util.Timer;
4439

4540
import static processing.app.I18n._;
4641

@@ -51,66 +46,39 @@ public class SerialDiscovery implements Discovery {
5146
_("Uncertified");
5247
}
5348

54-
@Override
55-
public List<BoardPort> discovery() {
56-
Platform os = BaseNoGui.getPlatform();
57-
String devicesListOutput = os.preListAllCandidateDevices();
58-
59-
List<BoardPort> res = new ArrayList<BoardPort>();
60-
61-
List<String> ports = Serial.list();
62-
63-
for (String port : ports) {
64-
Map<String, Object> boardData = os.resolveDeviceAttachedTo(port, BaseNoGui.packages, devicesListOutput);
65-
66-
BoardPort boardPort = new BoardPort();
67-
boardPort.setAddress(port);
68-
boardPort.setProtocol("serial");
69-
70-
String label = port;
71-
72-
PreferencesMap prefs = new PreferencesMap();
73-
74-
if (boardData != null) {
75-
prefs.put("vid", boardData.get("vid").toString());
76-
prefs.put("pid", boardData.get("pid").toString());
49+
private Timer serialBoardsListerTimer;
50+
private final List<BoardPort> serialBoardPorts;
7751

78-
TargetBoard board = (TargetBoard) boardData.get("board");
79-
if (board != null) {
80-
String warningKey = "vid." + boardData.get("vid").toString() + ".warning";
81-
String warning = board.getPreferences().get(warningKey);
82-
prefs.put("warning", warning);
83-
84-
String boardName = board.getName();
85-
if (boardName != null) {
86-
if (warning != null) {
87-
label += " (" + boardName + " - " + _(warning) + ")";
88-
} else {
89-
label += " (" + boardName + ")";
90-
}
91-
}
92-
boardPort.setBoardName(boardName);
93-
}
94-
}
52+
public SerialDiscovery() {
53+
this.serialBoardPorts = new LinkedList<BoardPort>();
54+
}
9555

96-
boardPort.setLabel(label);
97-
boardPort.setPrefs(prefs);
56+
@Override
57+
public List<BoardPort> listDiscoveredBoards() {
58+
return getSerialBoardPorts();
59+
}
9860

99-
res.add(boardPort);
61+
public List<BoardPort> getSerialBoardPorts() {
62+
synchronized (serialBoardPorts) {
63+
return new LinkedList<BoardPort>(serialBoardPorts);
10064
}
101-
return res;
10265
}
10366

104-
@Override
105-
public void setPreferences(PreferencesMap options) {
67+
public void setSerialBoardPorts(List<BoardPort> newSerialBoardPorts) {
68+
synchronized (serialBoardPorts) {
69+
serialBoardPorts.clear();
70+
serialBoardPorts.addAll(newSerialBoardPorts);
71+
}
10672
}
10773

10874
@Override
10975
public void start() {
76+
this.serialBoardsListerTimer = new Timer(SerialBoardsLister.class.getName());
77+
new SerialBoardsLister(this).start(serialBoardsListerTimer);
11078
}
11179

11280
@Override
11381
public void stop() {
82+
this.serialBoardsListerTimer.purge();
11483
}
115-
11684
}

0 commit comments

Comments
 (0)