1 12 13 package org.eclipse.core.databinding.observable; 14 15 import java.util.LinkedList ; 16 17 import org.eclipse.core.databinding.Binding; 18 import org.eclipse.core.databinding.util.Policy; 19 import org.eclipse.core.runtime.ISafeRunnable; 20 import org.eclipse.core.runtime.IStatus; 21 import org.eclipse.core.runtime.SafeRunner; 22 import org.eclipse.core.runtime.Status; 23 24 78 public abstract class Realm { 79 80 private static ThreadLocal defaultRealm = new ThreadLocal (); 81 82 88 public static Realm getDefault() { 89 return (Realm) defaultRealm.get(); 90 } 91 92 102 protected static Realm setDefault(Realm realm) { 103 Realm oldValue = getDefault(); 104 defaultRealm.set(realm); 105 return oldValue; 106 } 107 108 113 abstract public boolean isCurrent(); 114 115 private Thread workerThread; 116 117 LinkedList workQueue = new LinkedList (); 118 119 127 protected static void safeRun(final Runnable runnable) { 128 ISafeRunnable safeRunnable; 129 if (runnable instanceof ISafeRunnable) { 130 safeRunnable = (ISafeRunnable) runnable; 131 } else { 132 safeRunnable = new ISafeRunnable() { 133 public void handleException(Throwable exception) { 134 Policy 135 .getLog() 136 .log( 137 new Status( 138 IStatus.ERROR, 139 Policy.JFACE_DATABINDING, 140 IStatus.OK, 141 "Unhandled exception: " + exception.getMessage(), exception)); } 143 public void run() throws Exception { 144 runnable.run(); 145 } 146 }; 147 } 148 SafeRunner.run(safeRunnable); 149 } 150 151 164 public void exec(Runnable runnable) { 165 if (isCurrent()) { 166 safeRun(runnable); 167 } else { 168 asyncExec(runnable); 169 } 170 } 171 172 188 public void asyncExec(Runnable runnable) { 189 synchronized (workQueue) { 190 ensureWorkerThreadIsRunning(); 191 workQueue.addLast(runnable); 192 workQueue.notifyAll(); 193 } 194 } 195 196 199 private void ensureWorkerThreadIsRunning() { 200 if (workerThread == null) { 201 workerThread = new Thread () { 202 public void run() { 203 try { 204 while (true) { 205 Runnable work = null; 206 synchronized (workQueue) { 207 while (workQueue.isEmpty()) { 208 workQueue.wait(); 209 } 210 work = (Runnable ) workQueue.removeFirst(); 211 } 212 syncExec(work); 213 } 214 } catch (InterruptedException e) { 215 } 217 } 218 }; 219 workerThread.start(); 220 } 221 } 222 223 242 protected void syncExec(Runnable runnable) { 243 SyncRunnable syncRunnable = new SyncRunnable(runnable); 244 asyncExec(syncRunnable); 245 synchronized (syncRunnable) { 246 while (!syncRunnable.hasRun) { 247 try { 248 syncRunnable.wait(); 249 } catch (InterruptedException e) { 250 Thread.currentThread().interrupt(); 251 } 252 } 253 } 254 } 255 256 static class SyncRunnable implements Runnable { 257 boolean hasRun = false; 258 259 private Runnable runnable; 260 261 SyncRunnable(Runnable runnable) { 262 this.runnable = runnable; 263 } 264 265 public void run() { 266 try { 267 safeRun(runnable); 268 } finally { 269 synchronized (this) { 270 hasRun = true; 271 this.notifyAll(); 272 } 273 } 274 } 275 } 276 277 285 public static void runWithDefault(Realm realm, Runnable runnable) { 286 Realm oldRealm = Realm.getDefault(); 287 try { 288 defaultRealm.set(realm); 289 runnable.run(); 290 } finally { 291 defaultRealm.set(oldRealm); 292 } 293 } 294 } 295 | Popular Tags |