Merge branch 'Bug_fix_high_cpu_usage'
diff --git a/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java b/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
index e8bf32a..942acf8 100644
--- a/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
+++ b/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
@@ -15,66 +15,77 @@
 
 public abstract class DatagramChannelRunnable implements Runnable {
 
-   private LinkedBlockingQueue<DatagramChannelData> data;
-   private DatagramChannel channel;
-   private InetSocketAddress address;   
-   
-   DatagramChannelRunnable(InetSocketAddress address){
-      this.address = address;
-   }
-   
-   void setQueue(LinkedBlockingQueue<DatagramChannelData> data) {
-      this.data = data;
-   }
-   
-   @Override
-   public void run() {
-      try {
-         channel = openAndInitializeDatagramChannel(address); 
-         boolean keepRunning = true;
-         List<DatagramChannelData> dataToSend = new ArrayList<DatagramChannelData>();
-         while(keepRunning){
-            try{
-               dataToSend.clear();
-               data.drainTo(dataToSend);
-               for(DatagramChannelData datagramChannelData: dataToSend){
-                  if(datagramChannelData == DatagramChannelWorker.POISON_PILL){
-                     keepRunning = false;
-                  }
-               }
-               if(keepRunning){
-                  doSend(channel, dataToSend);
-               }
-            } catch (ClosedByInterruptException ex){
-               OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
-               channel = openAndInitializeDatagramChannel(address);
-            } catch (AsynchronousCloseException ex){
-               OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
-               channel = openAndInitializeDatagramChannel(address);
-            } catch (ClosedChannelException ex){
-               OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
-               channel = openAndInitializeDatagramChannel(address);
-            } catch (IOException ex){
-               OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
-            } finally {
-               for(DatagramChannelData datagramChannelData: dataToSend){
-                  datagramChannelData.postProcess();
-               }
-            }
-         } 
-      } catch (IOException ex){
-         OseeLog.log(getClass(), Level.SEVERE, "Error opening DatagramChannel.  Ending DatagramChannelRunnable unexpectedly.", ex);
-      } finally{
-         try {
-            channel.close();
-         } catch (IOException e) {
-            OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", e);
-         }
-      }
-   }
+	private LinkedBlockingQueue<DatagramChannelData> data;
+	private InetSocketAddress address;   
 
-   public abstract void doSend(DatagramChannel channel2, List<DatagramChannelData> dataToSend) throws ClosedChannelException, AsynchronousCloseException, ClosedByInterruptException, IOException;
+	DatagramChannelRunnable(InetSocketAddress address){
+		this.address = address;
+	}
 
-   public abstract DatagramChannel openAndInitializeDatagramChannel(InetSocketAddress address) throws IOException;
-   
+	void setQueue(LinkedBlockingQueue<DatagramChannelData> data) {
+		this.data = data;
+	}
+
+	@Override
+	public void run() {
+		DatagramChannel channel = null; 
+		try {
+			channel = openAndInitializeDatagramChannel(address); 
+			boolean keepRunning = true;
+			final List<DatagramChannelData> dataToSend = new ArrayList<DatagramChannelData>(32);
+			while(keepRunning){
+				try{
+					dataToSend.clear();
+					if (data.drainTo(dataToSend) < 1) {
+						try {
+							// block until something is available
+							dataToSend.add(data.take());							
+						} catch (InterruptedException e) {
+							keepRunning = false;
+							continue;
+						}
+					}
+					for (DatagramChannelData data : dataToSend) {
+						if (data == DatagramChannelWorker.POISON_PILL) {
+							keepRunning = false;
+							break;
+						}
+					}
+					if(keepRunning){
+						doSend(channel, dataToSend);
+					}
+				} catch (ClosedByInterruptException ex){
+					OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
+					channel = openAndInitializeDatagramChannel(address);
+				} catch (AsynchronousCloseException ex){
+					OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
+					channel = openAndInitializeDatagramChannel(address);
+				} catch (ClosedChannelException ex){
+					OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
+					channel = openAndInitializeDatagramChannel(address);
+				} catch (IOException ex){
+					OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", ex);
+				} finally {
+					for(DatagramChannelData datagramChannelData: dataToSend){
+						datagramChannelData.postProcess();
+					}
+				}
+			} 
+		} catch (IOException ex){
+			OseeLog.log(getClass(), Level.SEVERE, "Error opening DatagramChannel.  Ending DatagramChannelRunnable unexpectedly.", ex);
+		} finally{
+			try {
+				if (channel != null) {
+					channel.close();
+				}
+			} catch (IOException e) {
+				OseeLog.log(getClass(), Level.SEVERE, "Error trying to send data", e);
+			}
+		}
+	}
+
+	public abstract void doSend(DatagramChannel channel2, List<DatagramChannelData> dataToSend) throws ClosedChannelException, AsynchronousCloseException, ClosedByInterruptException, IOException;
+
+	public abstract DatagramChannel openAndInitializeDatagramChannel(InetSocketAddress address) throws IOException;
+
 }