1 37 package net.sourceforge.cruisecontrol; 38 39 import java.util.ArrayList ; 40 import java.util.EventListener ; 41 import java.util.Iterator ; 42 import java.util.LinkedList ; 43 import java.util.List ; 44 45 import net.sourceforge.cruisecontrol.util.threadpool.ThreadQueue; 46 47 import org.apache.log4j.Logger; 48 49 58 public class BuildQueue implements Runnable { 59 private static final Logger LOG = Logger.getLogger(BuildQueue.class); 60 61 private final LinkedList queue = new LinkedList (); 62 private boolean waiting = false; 63 private Thread buildQueueThread; 64 65 private List listeners = new ArrayList (); 66 67 70 public void requestBuild(Project project) { 71 LOG.debug("BuildQueue.requestBuild Thread = " + Thread.currentThread().getName()); 72 73 notifyListeners(); 74 synchronized (queue) { 75 queue.add(project); 76 queue.notify(); 77 } 78 } 79 80 84 public String findPosition(Project project) { 85 int position; 86 int length; 87 synchronized (queue) { 88 position = queue.indexOf(project); 89 length = queue.size(); 90 } 91 if (position < 0) { 92 return ThreadQueue.findPosition(project.getName()); 93 } 94 return "BUILD_REQUESTED[ " + (position + 1) + " / " + length + " ]"; 96 } 97 98 void serviceQueue() { 99 while (!queue.isEmpty()) { 100 Project nextProject; 101 synchronized (queue) { 102 nextProject = (Project) queue.remove(0); 103 } 104 if (nextProject != null) { 105 LOG.info("now adding to the thread queue: " + nextProject.getName()); 106 ProjectWrapper pw = new ProjectWrapper(nextProject); 107 String name = nextProject.getName(); 109 if (ThreadQueue.isActive(name)) { 110 } else { 114 ThreadQueue.addTask(pw); 115 } 116 } 117 } 118 } 119 120 public void run() { 121 try { 122 LOG.info("BuildQueue started"); 123 while (true) { 124 synchronized (queue) { 125 if (queue.isEmpty()) { 126 waiting = true; 127 queue.wait(); 128 } 129 waiting = false; 130 } 131 serviceQueue(); 132 } 133 } catch (InterruptedException e) { 134 String message = "BuildQueue.run() interrupted. Stopping?"; 135 LOG.debug(message, e); 136 } catch (Throwable e) { 137 LOG.error("BuildQueue.run()", e); 138 } finally { 139 waiting = false; 140 LOG.info("BuildQueue thread is no longer alive"); 141 } 142 } 143 144 void start() { 145 buildQueueThread = new Thread (this, "BuildQueueThread"); 146 buildQueueThread.setDaemon(false); 147 buildQueueThread.start(); 148 while (!buildQueueThread.isAlive()) { 149 try { 150 Thread.sleep(500); 151 } catch (InterruptedException e) { 152 String message = "BuildQueue.start() interrupted"; 153 LOG.error(message, e); 154 throw new RuntimeException (message); 155 } 156 } 157 } 158 159 void stop() { 160 LOG.info("Stopping BuildQueue"); 161 buildQueueThread.interrupt(); 162 synchronized (queue) { 163 queue.notify(); 164 } 165 } 166 167 public boolean isAlive() { 168 return true; 169 } 170 171 public boolean isWaiting() { 172 return waiting; 173 } 174 175 public void addListener(Listener listener) { 176 listeners.add(listener); 177 } 178 179 private void notifyListeners() { 180 Iterator toNotify = listeners.iterator(); 181 while (toNotify.hasNext()) { 182 try { 183 ((Listener) toNotify.next()).buildRequested(); 184 } catch (Exception e) { 185 LOG.error("exception notifying listener before project queued", e); 186 } 187 } 188 189 } 190 191 public static interface Listener extends EventListener { 192 void buildRequested(); 193 } 194 } 195 | Popular Tags |