1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-19 08:52:15 +01:00

Avoid multiple concurrent compile/upload operations

Disable Compile/Run buttons as they get press, and reenable only on function exit.
The launched upload process has now a 2minutes timeout before being terminated forcefully.
10 second after pressing "Upload" the button comes pressable again, but this time the previous upload command gets killed explicitely
This commit is contained in:
Martino Facchin 2016-01-25 18:19:48 +01:00
parent b99ab40ba2
commit 6d5597b070
4 changed files with 53 additions and 8 deletions

View File

@ -146,6 +146,8 @@ public class Editor extends JFrame implements RunnerListener {
private int numTools = 0;
public boolean avoidMultipleOperations = false;
private final EditorToolbar toolbar;
// these menus are shared so that they needn't be rebuilt for all windows
// each time a sketch is created, renamed, or moved.
@ -198,7 +200,7 @@ public class Editor extends JFrame implements RunnerListener {
private Runnable stopHandler;
Runnable exportHandler;
private Runnable exportAppHandler;
private Runnable timeoutUploadHandler;
public Editor(Base ibase, File file, int[] storedLocation, int[] defaultLocation, Platform platform) throws Exception {
super("Arduino");
@ -1648,6 +1650,7 @@ public class Editor extends JFrame implements RunnerListener {
stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler();
timeoutUploadHandler = new TimeoutUploadHandler();
}
@ -1979,6 +1982,7 @@ public class Editor extends JFrame implements RunnerListener {
status.unprogress();
toolbar.deactivateRun();
avoidMultipleOperations = false;
}
}
@ -2367,6 +2371,7 @@ public class Editor extends JFrame implements RunnerListener {
console.clear();
status.progress(tr("Uploading to I/O Board..."));
new Thread(timeoutUploadHandler).start();
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
}
@ -2406,6 +2411,7 @@ public class Editor extends JFrame implements RunnerListener {
e.printStackTrace();
} finally {
populatePortMenu();
avoidMultipleOperations = false;
}
status.unprogress();
uploading = false;
@ -2500,6 +2506,7 @@ public class Editor extends JFrame implements RunnerListener {
} catch (Exception e) {
e.printStackTrace();
} finally {
avoidMultipleOperations = false;
populatePortMenu();
}
status.unprogress();
@ -2514,6 +2521,20 @@ public class Editor extends JFrame implements RunnerListener {
}
}
class TimeoutUploadHandler implements Runnable {
public void run() {
try {
//10 seconds, than reactivate upload functionality and let the programmer pid being killed
Thread.sleep(1000 * 10);
if (uploading) {
avoidMultipleOperations = false;
}
} catch (InterruptedException e) {
// noop
}
}
}
public void handleSerial() {
if(serialPlotter != null) {
@ -2558,7 +2579,7 @@ public class Editor extends JFrame implements RunnerListener {
// If currently uploading, disable the monitor (it will be later
// enabled when done uploading)
if (uploading) {
if (uploading || avoidMultipleOperations) {
try {
serialMonitor.suspend();
} catch (Exception e) {
@ -2582,8 +2603,10 @@ public class Editor extends JFrame implements RunnerListener {
}
try {
serialMonitor.open();
serialMonitor.setVisible(true);
if (!avoidMultipleOperations) {
serialMonitor.open();
}
success = true;
} catch (ConnectException e) {
statusError(tr("Unable to connect: is the sketch using the bridge?"));

View File

@ -341,7 +341,10 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
switch (sel) {
case RUN:
editor.handleRun(false, editor.presentHandler, editor.runHandler);
if (!editor.avoidMultipleOperations) {
editor.handleRun(false, editor.presentHandler, editor.runHandler);
editor.avoidMultipleOperations = true;
}
break;
// case STOP:
@ -370,7 +373,11 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
break;
case EXPORT:
editor.handleExport(e.isShiftDown());
// launch a timeout timer which can reenable to upload button functionality an
if (!editor.avoidMultipleOperations) {
editor.handleExport(e.isShiftDown());
editor.avoidMultipleOperations = true;
}
break;
case SERIAL:

View File

@ -44,6 +44,7 @@ import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static processing.app.I18n.tr;
@ -102,6 +103,9 @@ public abstract class Uploader implements MessageConsumer {
return null;
}
// static field for last executed programmer process ID
static protected Process programmerPid;
protected boolean executeUploadCommand(Collection<String> command) throws Exception {
return executeUploadCommand(command.toArray(new String[command.size()]));
}
@ -121,11 +125,16 @@ public abstract class Uploader implements MessageConsumer {
System.out.println();
}
Process process = ProcessUtils.exec(command);
programmerPid = process;
new MessageSiphon(process.getInputStream(), this, 100);
new MessageSiphon(process.getErrorStream(), this, 100);
// wait for the process to finish.
result = process.waitFor();
// wait for the process to finish, but not forever
// kill the flasher process after 2 minutes to avoid 100% cpu spinning
if (!process.waitFor(2, TimeUnit.MINUTES)) {
process.destroyForcibly();
}
result = process.exitValue();
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -78,6 +78,11 @@ public class SerialUploader extends Uploader {
}
prefs.putAll(targetPlatform.getTool(tool));
if (programmerPid != null && programmerPid.isAlive()) {
// kill the previous programmer
programmerPid.destroyForcibly();
}
// if no protocol is specified for this board, assume it lacks a
// bootloader and upload using the selected programmer.
if (usingProgrammer || prefs.get("upload.protocol") == null) {
@ -134,7 +139,7 @@ public class SerialUploader extends Uploader {
// Scanning for available ports seems to open the port or
// otherwise assert DTR, which would cancel the WDT reset if
// it happened within 250 ms. So we wait until the reset should
// have already occured before we start scanning.
// have already occurred before we start scanning.
actualUploadPort = waitForUploadPort(userSelectedUploadPort, before);
}
} catch (SerialException e) {
@ -213,6 +218,7 @@ public class SerialUploader extends Uploader {
finalUploadPort = userSelectedUploadPort;
}
BaseNoGui.selectSerialPort(finalUploadPort);
return uploadResult;
}