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:
parent
b99ab40ba2
commit
6d5597b070
@ -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?"));
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user