Skip to content

Commit

Permalink
Avoid multiple concurrent compile/upload operations
Browse files Browse the repository at this point in the history
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
  • Loading branch information
facchinm committed Jan 25, 2016
1 parent f027003 commit 3f07b8a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
29 changes: 26 additions & 3 deletions app/src/processing/app/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public boolean test(Sketch sketch) {

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.
Expand Down Expand Up @@ -195,7 +197,7 @@ public boolean test(Sketch sketch) {
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");
Expand Down Expand Up @@ -1677,6 +1679,7 @@ private void resetHandlers() {
stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler();
timeoutUploadHandler = new TimeoutUploadHandler();
}


Expand Down Expand Up @@ -2008,6 +2011,7 @@ public void run() {

status.unprogress();
toolbar.deactivateRun();
avoidMultipleOperations = false;
}
}

Expand Down Expand Up @@ -2396,6 +2400,7 @@ synchronized public void handleExport(final boolean usingProgrammer) {
console.clear();
status.progress(tr("Uploading to I/O Board..."));

new Thread(timeoutUploadHandler).start();
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
}

Expand Down Expand Up @@ -2435,6 +2440,7 @@ public void run() {
e.printStackTrace();
} finally {
populatePortMenu();
avoidMultipleOperations = false;
}
status.unprogress();
uploading = false;
Expand Down Expand Up @@ -2529,6 +2535,7 @@ public void run() {
} catch (Exception e) {
e.printStackTrace();
} finally {
avoidMultipleOperations = false;
populatePortMenu();
}
status.unprogress();
Expand All @@ -2543,6 +2550,20 @@ public void run() {
}
}

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) {
Expand Down Expand Up @@ -2587,7 +2608,7 @@ public void handleSerial() {

// 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) {
Expand All @@ -2611,8 +2632,10 @@ public void handleSerial() {
}

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?"));
Expand Down
11 changes: 9 additions & 2 deletions app/src/processing/app/EditorToolbar.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,10 @@ public void mousePressed(MouseEvent e) {

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:
Expand Down Expand Up @@ -366,7 +369,11 @@ public void mousePressed(MouseEvent e) {
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:
Expand Down
13 changes: 11 additions & 2 deletions arduino-core/src/cc/arduino/packages/Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static processing.app.I18n.tr;

Expand Down Expand Up @@ -102,6 +103,9 @@ public String getAuthorizationKey() {
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()]));
}
Expand All @@ -121,11 +125,16 @@ protected boolean executeUploadCommand(String command[]) throws Exception {
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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
}
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) {
Expand Down Expand Up @@ -134,7 +139,7 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
// 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) {
Expand Down Expand Up @@ -213,6 +218,7 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
finalUploadPort = userSelectedUploadPort;
}
BaseNoGui.selectSerialPort(finalUploadPort);

return uploadResult;
}

Expand Down

0 comments on commit 3f07b8a

Please sign in to comment.