From 9da24d1091c1c82a5a386cbaf554f38d9439b407 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Wed, 22 Mar 2017 11:46:41 +0100
Subject: [PATCH] Avoid board change during compilation/upload

By threading the boardChange callback we can busy wait until
the compilation/upload phase has ended and change the board when done.

Fixes #6035
---
 app/src/processing/app/Base.java   | 26 ++++++++++++++++++++------
 app/src/processing/app/Editor.java |  4 ++++
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index f983ffe8f68..1023323dbd6 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -1291,7 +1291,7 @@ public void rebuildExamplesMenu(JMenu menu) {
   private static String priorPlatformFolder;
   private static boolean newLibraryImported;
 
-  public void onBoardOrPortChange() {
+  public synchronized void onBoardOrPortChange() {
     BaseNoGui.onBoardOrPortChange();
 
     // reload keywords when package/platform changes
@@ -1490,12 +1490,26 @@ private JRadioButtonMenuItem createBoardMenusAndCustomMenus(
     @SuppressWarnings("serial")
     Action action = new AbstractAction(board.getName()) {
       public void actionPerformed(ActionEvent actionevent) {
-        BaseNoGui.selectBoard((TargetBoard) getValue("b"));
-        filterVisibilityOfSubsequentBoardMenus(boardsCustomMenus, (TargetBoard) getValue("b"), 1);
 
-        onBoardOrPortChange();
-        rebuildImportMenu(Editor.importMenu);
-        rebuildExamplesMenu(Editor.examplesMenu);
+        new Thread()
+        {
+            public void run() {
+              if (activeEditor != null && activeEditor.isCompiling()) {
+                  // block until isCompiling becomes false, but aboid blocking the UI
+                  while (activeEditor.isCompiling()) {
+                    try {
+                      Thread.sleep(100);
+                    } catch (InterruptedException e) {}
+                  }
+              }
+
+              BaseNoGui.selectBoard((TargetBoard) getValue("b"));
+              filterVisibilityOfSubsequentBoardMenus(boardsCustomMenus, (TargetBoard) getValue("b"), 1);
+              onBoardOrPortChange();
+              rebuildImportMenu(Editor.importMenu);
+              rebuildExamplesMenu(Editor.examplesMenu);
+            }
+        }.start();
       }
     };
     action.putValue("b", board);
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 7d26271953b..4a06b779d96 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -2166,6 +2166,10 @@ public void run() {
     }
   }
 
+  public boolean isCompiling() {
+    return uploading;
+  }
+
   private void resumeOrCloseSerialMonitor() {
     // Return the serial monitor window to its initial state
     if (serialMonitor != null) {