KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > UISynchronizer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.swt.widgets.Display;
18 import org.eclipse.swt.widgets.Synchronizer;
19 import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
20
21 public class UISynchronizer extends Synchronizer {
22     protected UILockListener lockListener;
23     
24     /**
25      * Indicates that the UI is in startup mode and that no non-workbench
26      * runnables should be invoked.
27      */

28     protected boolean isStarting = true;
29
30     /**
31      * List of non-workbench Runnables that need executing at some point in the future
32      */

33     protected List JavaDoc pendingStartup = new ArrayList JavaDoc();
34
35     /**
36      * Setting this variable to the value {@link Boolean#TRUE} will allow a
37      * thread to execute code during the startup sequence.
38      */

39     public static final ThreadLocal JavaDoc startupThread = new ThreadLocal JavaDoc() {
40
41         /*
42          * (non-Javadoc)
43          *
44          * @see java.lang.ThreadLocal#initialValue()
45          */

46         protected Object JavaDoc initialValue() {
47             return Boolean.FALSE;
48         }
49         
50         /* (non-Javadoc)
51          * @see java.lang.ThreadLocal#set(java.lang.Object)
52          */

53         public void set(Object JavaDoc value) {
54             if (value != Boolean.TRUE && value != Boolean.FALSE)
55                 throw new IllegalArgumentException JavaDoc();
56             super.set(value);
57         }
58     };
59     
60     public UISynchronizer(Display display, UILockListener lock) {
61         super(display);
62         this.lockListener = lock;
63     }
64     
65     public void started() {
66         synchronized (this) {
67             if (!isStarting)
68                 throw new IllegalStateException JavaDoc();
69             isStarting = false;
70             for (Iterator JavaDoc i = pendingStartup.iterator(); i.hasNext();) {
71                 Runnable JavaDoc runnable = (Runnable JavaDoc) i.next();
72                 try {
73                     //queue up all pending asyncs
74
super.asyncExec(runnable);
75                 } catch (RuntimeException JavaDoc e) {
76                     // do nothing
77
}
78             }
79             pendingStartup = null;
80             // wake up all pending syncExecs
81
this.notifyAll();
82         }
83     }
84     
85     /* (non-Javadoc)
86      * @see org.eclipse.swt.widgets.Synchronizer#asyncExec(java.lang.Runnable)
87      */

88     protected void asyncExec(Runnable JavaDoc runnable) {
89         if (runnable != null) {
90             synchronized (this) {
91                 if (isStarting
92                         && !(runnable instanceof StartupRunnable)) {
93                     pendingStartup.add(runnable);
94                     
95                     return;
96                 }
97             }
98         }
99         super.asyncExec(runnable);
100     }
101
102     public void syncExec(Runnable JavaDoc runnable) {
103         
104         synchronized (this) {
105             if (isStarting && UISynchronizer.startupThread.get() == Boolean.FALSE) {
106                 do {
107                     try {
108                         this.wait();
109                     } catch (InterruptedException JavaDoc e) {
110                     }
111                 } while (isStarting);
112             }
113         }
114         
115         //if this thread is the UI or this thread does not own any locks, just do the syncExec
116
if ((runnable == null) || lockListener.isUI()
117                 || !lockListener.isLockOwner()) {
118             super.syncExec(runnable);
119             return;
120         }
121         Semaphore work = new Semaphore(runnable);
122         work.setOperationThread(Thread.currentThread());
123         lockListener.addPendingWork(work);
124         asyncExec(new Runnable JavaDoc() {
125             public void run() {
126                 lockListener.doPendingWork();
127             }
128         });
129         try {
130             //even if the UI was not blocked earlier, it might become blocked
131
//before it can serve the asyncExec to do the pending work
132
do {
133                 if (lockListener.isUIWaiting()) {
134                     lockListener.interruptUI();
135                 }
136             } while (!work.acquire(1000));
137         } catch (InterruptedException JavaDoc e) {
138         }
139     }
140 }
141
Popular Tags