1 11 package org.eclipse.core.internal.jobs; 12 13 import org.eclipse.core.runtime.Assert; 14 import org.eclipse.core.runtime.IStatus; 15 import org.eclipse.core.runtime.jobs.Job; 16 17 27 class WorkerPool { 28 31 private static final int BEST_BEFORE = 60000; 32 35 private static final int MIN_THREADS = 1; 36 40 private int busyThreads = 0; 41 42 45 protected final ClassLoader defaultContextLoader; 46 47 50 private boolean isDaemon = false; 51 52 private JobManager manager; 53 56 private int numThreads = 0; 57 60 private int sleepingThreads = 0; 61 64 private Worker[] threads = new Worker[10]; 65 66 protected WorkerPool(JobManager manager) { 67 this.manager = manager; 68 this.defaultContextLoader = Thread.currentThread().getContextClassLoader(); 69 } 70 71 74 private synchronized void add(Worker worker) { 75 int size = threads.length; 76 if (numThreads + 1 > size) { 77 Worker[] newThreads = new Worker[2 * size]; 78 System.arraycopy(threads, 0, newThreads, 0, size); 79 threads = newThreads; 80 } 81 threads[numThreads++] = worker; 82 } 83 84 private synchronized void decrementBusyThreads() { 85 if (--busyThreads < 0) { 87 if (JobManager.DEBUG) 88 Assert.isTrue(false, Integer.toString(busyThreads)); 89 busyThreads = 0; 90 } 91 } 92 93 97 protected void endJob(InternalJob job, IStatus result) { 98 decrementBusyThreads(); 99 if ((job.getRule() != null) && !(job instanceof ThreadJob)) { 102 manager.getLockManager().removeLockCompletely(Thread.currentThread(), job.getRule()); 104 } 105 manager.endJob(job, result, true); 106 manager.implicitJobs.endJob(job); 108 } 109 110 114 protected synchronized void endWorker(Worker worker) { 115 if (remove(worker) && JobManager.DEBUG) 116 JobManager.debug("worker removed from pool: " + worker); } 118 119 private synchronized void incrementBusyThreads() { 120 if (++busyThreads > numThreads) { 122 if (JobManager.DEBUG) 123 Assert.isTrue(false, Integer.toString(busyThreads) + ',' + numThreads); 124 busyThreads = numThreads; 125 } 126 } 127 128 132 protected synchronized void jobQueued() { 133 if (sleepingThreads > 0) { 135 notify(); 136 return; 137 } 138 if (busyThreads >= numThreads) { 140 Worker worker = new Worker(this); 141 worker.setDaemon(isDaemon); 142 add(worker); 143 if (JobManager.DEBUG) 144 JobManager.debug("worker added to pool: " + worker); worker.start(); 146 return; 147 } 148 } 149 150 154 private synchronized boolean remove(Worker worker) { 155 for (int i = 0; i < threads.length; i++) { 156 if (threads[i] == worker) { 157 System.arraycopy(threads, i + 1, threads, i, numThreads - i - 1); 158 threads[--numThreads] = null; 159 return true; 160 } 161 } 162 return false; 163 } 164 165 168 void setDaemon(boolean value) { 169 this.isDaemon = value; 170 } 171 172 protected synchronized void shutdown() { 173 notifyAll(); 174 } 175 176 179 private synchronized void sleep(long duration) { 180 sleepingThreads++; 181 busyThreads--; 182 if (JobManager.DEBUG) 183 JobManager.debug("worker sleeping for: " + duration + "ms"); try { 185 wait(duration); 186 } catch (InterruptedException e) { 187 if (JobManager.DEBUG) 188 JobManager.debug("worker interrupted while waiting... :-|"); } finally { 190 sleepingThreads--; 191 busyThreads++; 192 } 193 } 194 195 198 protected InternalJob startJob(Worker worker) { 199 synchronized (this) { 201 if (!manager.isActive()) { 202 endWorker(worker); 204 return null; 205 } 206 incrementBusyThreads(); 208 } 209 Job job = null; 210 try { 211 job = manager.startJob(); 212 long idleStart = System.currentTimeMillis(); 214 while (manager.isActive() && job == null) { 215 long hint = manager.sleepHint(); 216 if (hint > 0) 217 sleep(Math.min(hint, BEST_BEFORE)); 218 job = manager.startJob(); 219 synchronized (this) { 222 if (job == null && (System.currentTimeMillis() - idleStart > BEST_BEFORE) && (numThreads - busyThreads) > MIN_THREADS) { 223 endWorker(worker); 225 return null; 226 } 227 } 228 } 229 if (job != null) { 230 if ((job.getRule() != null) && !(job instanceof ThreadJob)) { 232 manager.getLockManager().addLockThread(Thread.currentThread(), job.getRule()); 235 } 236 if (manager.sleepHint() <= 0) 238 jobQueued(); 239 } 240 } finally { 241 if (job == null) 243 decrementBusyThreads(); 244 } 245 return job; 246 } 247 } 248 | Popular Tags |