KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > Synchronizer


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.swt.widgets;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.internal.Compatibility;
16  
17 /**
18  * Instances of this class provide synchronization support
19  * for displays. A default instance is created automatically
20  * for each display, and this instance is sufficient for almost
21  * all applications.
22  * <p>
23  * <b>IMPORTANT:</b> Typical application code <em>never</em>
24  * needs to deal with this class. It is provided only to
25  * allow applications which require non-standard
26  * synchronization behavior to plug in the support they
27  * require. <em>Subclasses which override the methods in
28  * this class must ensure that the superclass methods are
29  * invoked in their implementations</em>
30  * </p>
31  *
32  * @see Display#setSynchronizer
33  */

34 public class Synchronizer {
35     Display display;
36     int messageCount;
37     RunnableLock [] messages;
38     Object JavaDoc messageLock = new Object JavaDoc ();
39     Thread JavaDoc syncThread;
40
41 /**
42  * Constructs a new instance of this class.
43  *
44  * @param display the display to create the synchronizer on
45  */

46 public Synchronizer (Display display) {
47     this.display = display;
48 }
49     
50 void addLast (RunnableLock lock) {
51     boolean wake = false;
52     synchronized (messageLock) {
53         if (messages == null) messages = new RunnableLock [4];
54         if (messageCount == messages.length) {
55             RunnableLock[] newMessages = new RunnableLock [messageCount + 4];
56             System.arraycopy (messages, 0, newMessages, 0, messageCount);
57             messages = newMessages;
58         }
59         messages [messageCount++] = lock;
60         wake = messageCount == 1;
61     }
62     if (wake) display.wakeThread ();
63 }
64
65 /**
66  * Causes the <code>run()</code> method of the runnable to
67  * be invoked by the user-interface thread at the next
68  * reasonable opportunity. The caller of this method continues
69  * to run in parallel, and is not notified when the
70  * runnable has completed.
71  *
72  * @param runnable code to run on the user-interface thread.
73  *
74  * @see #syncExec
75  */

76 protected void asyncExec (Runnable JavaDoc runnable) {
77     if (runnable == null) {
78         display.wake ();
79         return;
80     }
81     addLast (new RunnableLock (runnable));
82 }
83
84 int getMessageCount () {
85     synchronized (messageLock) {
86         return messageCount;
87     }
88 }
89
90 void releaseSynchronizer () {
91     display = null;
92     messages = null;
93     messageLock = null;
94     syncThread = null;
95 }
96
97 RunnableLock removeFirst () {
98     synchronized (messageLock) {
99         if (messageCount == 0) return null;
100         RunnableLock lock = messages [0];
101         System.arraycopy (messages, 1, messages, 0, --messageCount);
102         messages [messageCount] = null;
103         if (messageCount == 0) {
104             if (messages.length > 64) messages = null;
105         }
106         return lock;
107     }
108 }
109
110 boolean runAsyncMessages () {
111     return runAsyncMessages (false);
112 }
113
114 boolean runAsyncMessages (boolean all) {
115     boolean run = false;
116     do {
117         RunnableLock lock = removeFirst ();
118         if (lock == null) return run;
119         run = true;
120         synchronized (lock) {
121             syncThread = lock.thread;
122             try {
123                 lock.run ();
124             } catch (Throwable JavaDoc t) {
125                 lock.throwable = t;
126                 SWT.error (SWT.ERROR_FAILED_EXEC, t);
127             } finally {
128                 syncThread = null;
129                 lock.notifyAll ();
130             }
131         }
132     } while (all);
133     return run;
134 }
135
136 /**
137  * Causes the <code>run()</code> method of the runnable to
138  * be invoked by the user-interface thread at the next
139  * reasonable opportunity. The thread which calls this method
140  * is suspended until the runnable completes.
141  *
142  * @param runnable code to run on the user-interface thread.
143  *
144  * @exception SWTException <ul>
145  * <li>ERROR_FAILED_EXEC - if an exception occurred when executing the runnable</li>
146  * </ul>
147  *
148  * @see #asyncExec
149  */

150 protected void syncExec (Runnable JavaDoc runnable) {
151     if (display.isValidThread ()) {
152         if (runnable != null) runnable.run ();
153         return;
154     }
155     if (runnable == null) {
156         display.wake ();
157         return;
158     }
159     RunnableLock lock = new RunnableLock (runnable);
160     /*
161      * Only remember the syncThread for syncExec.
162      */

163     lock.thread = Thread.currentThread();
164     synchronized (lock) {
165         addLast (lock);
166         boolean interrupted = false;
167         while (!lock.done ()) {
168             try {
169                 lock.wait ();
170             } catch (InterruptedException JavaDoc e) {
171                 interrupted = true;
172             }
173         }
174         if (interrupted) {
175             Compatibility.interrupt();
176         }
177         if (lock.throwable != null) {
178             SWT.error (SWT.ERROR_FAILED_EXEC, lock.throwable);
179         }
180     }
181 }
182
183 }
184
Popular Tags