Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/widgets/Synchronizer.d @ 49:7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 27 Mar 2009 12:59:54 +0100 |
parents | ddbfe84d86df |
children | c01d033c633a |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2008 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.swt.widgets.Synchronizer; | |
14 | |
15 import org.eclipse.swt.widgets.Display; | |
16 import org.eclipse.swt.widgets.RunnableLock; | |
17 import org.eclipse.swt.internal.Compatibility; | |
18 import java.lang.all; | |
19 | |
20 import org.eclipse.swt.SWT; | |
47
65761bc28ab2
swt linux again compilable for d1.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
21 import java.lang.Thread; |
25 | 22 import org.eclipse.swt.graphics.Device; |
48 | 23 version(Tango){ |
25 | 24 import tango.core.Exception; |
48 | 25 } else { // Phobos |
26 } | |
25 | 27 |
28 /** | |
29 * Instances of this class provide synchronization support | |
30 * for displays. A default instance is created automatically | |
31 * for each display, and this instance is sufficient for almost | |
32 * all applications. | |
33 * <p> | |
34 * <b>IMPORTANT:</b> Typical application code <em>never</em> | |
35 * needs to deal with this class. It is provided only to | |
36 * allow applications which require non-standard | |
37 * synchronization behavior to plug in the support they | |
38 * require. <em>Subclasses which override the methods in | |
39 * this class must ensure that the superclass methods are | |
40 * invoked in their implementations</em> | |
41 * </p> | |
42 * | |
43 * @see Display#setSynchronizer | |
44 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
45 */ | |
46 public class Synchronizer { | |
47 Display display; | |
48 int messageCount; | |
49 RunnableLock [] messages; | |
50 Object messageLock; | |
51 Thread syncThread; | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
52 static const int GROW_SIZE = 4; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
48
diff
changeset
|
53 static const int MESSAGE_LIMIT = 64; |
25 | 54 |
55 /** | |
56 * Constructs a new instance of this class. | |
57 * | |
58 * @param display the display to create the synchronizer on | |
59 */ | |
60 public this (Display display) { | |
61 this.display = display; | |
62 messageLock = new Object (); | |
63 } | |
64 | |
65 void addLast (RunnableLock lock) { | |
66 bool wake = false; | |
67 synchronized (messageLock) { | |
68 if (messages is null) messages = new RunnableLock [GROW_SIZE]; | |
69 if (messageCount is messages.length) { | |
70 RunnableLock[] newMessages = new RunnableLock [messageCount + GROW_SIZE]; | |
71 System.arraycopy (messages, 0, newMessages, 0, messageCount); | |
72 messages = newMessages; | |
73 } | |
74 messages [messageCount++] = lock; | |
75 wake = messageCount is 1; | |
76 } | |
77 if (wake) display.wakeThread (); | |
78 } | |
79 | |
80 /** | |
81 * Causes the <code>run()</code> method of the runnable to | |
82 * be invoked by the user-interface thread at the next | |
83 * reasonable opportunity. The caller of this method continues | |
84 * to run in parallel, and is not notified when the | |
85 * runnable has completed. | |
86 * | |
87 * @param runnable code to run on the user-interface thread. | |
88 * | |
89 * @see #syncExec | |
90 */ | |
91 public void asyncExec (Runnable runnable) { | |
92 if (runnable is null) { | |
93 display.wake (); | |
94 return; | |
95 } | |
96 addLast (new RunnableLock (runnable)); | |
97 } | |
98 | |
99 int getMessageCount () { | |
100 synchronized (messageLock) { | |
101 return messageCount; | |
102 } | |
103 } | |
104 | |
105 void releaseSynchronizer () { | |
106 display = null; | |
107 messages = null; | |
108 messageLock = null; | |
109 syncThread = null; | |
110 } | |
111 | |
112 RunnableLock removeFirst () { | |
113 synchronized (messageLock) { | |
114 if (messageCount is 0) return null; | |
115 RunnableLock lock = messages [0]; | |
116 System.arraycopy (messages, 1, messages, 0, --messageCount); | |
117 messages [messageCount] = null; | |
118 if (messageCount is 0) { | |
119 if (messages.length > MESSAGE_LIMIT) messages = null; | |
120 } | |
121 return lock; | |
122 } | |
123 } | |
124 | |
125 bool runAsyncMessages () { | |
126 return runAsyncMessages (false); | |
127 } | |
128 | |
129 bool runAsyncMessages (bool all) { | |
130 bool run = false; | |
131 do { | |
132 RunnableLock lock = removeFirst (); | |
133 if (lock is null) return run; | |
134 run = true; | |
135 synchronized (lock) { | |
136 syncThread = lock.thread; | |
137 try { | |
138 lock.run (); | |
139 } catch (Exception t) { | |
140 lock.throwable = t; | |
141 SWT.error (SWT.ERROR_FAILED_EXEC, t); | |
142 } finally { | |
143 syncThread = null; | |
144 lock.notifyAll (); | |
145 } | |
146 } | |
147 } while (all); | |
148 return run; | |
149 } | |
150 | |
151 /** | |
152 * Causes the <code>run()</code> method of the runnable to | |
153 * be invoked by the user-interface thread at the next | |
154 * reasonable opportunity. The thread which calls this method | |
155 * is suspended until the runnable completes. | |
156 * | |
157 * @param runnable code to run on the user-interface thread. | |
158 * | |
159 * @exception SWTException <ul> | |
160 * <li>ERROR_FAILED_EXEC - if an exception occurred when executing the runnable</li> | |
161 * </ul> | |
162 * | |
163 * @see #asyncExec | |
164 */ | |
165 public void syncExec (Runnable runnable) { | |
166 RunnableLock lock = null; | |
167 synchronized (Device.classinfo) { | |
168 if (display is null || display.isDisposed ()) SWT.error (SWT.ERROR_DEVICE_DISPOSED); | |
169 if (!display.isValidThread ()) { | |
170 if (runnable is null) { | |
171 display.wake (); | |
172 return; | |
173 } | |
174 lock = new RunnableLock (runnable); | |
175 /* | |
176 * Only remember the syncThread for syncExec. | |
177 */ | |
47
65761bc28ab2
swt linux again compilable for d1.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
178 lock.thread = Thread.currentThread(); |
25 | 179 addLast (lock); |
180 } | |
181 } | |
182 if (lock is null) { | |
183 if (runnable !is null) runnable.run (); | |
184 return; | |
185 } | |
186 synchronized (lock) { | |
187 bool interrupted = false; | |
188 while (!lock.done ()) { | |
189 try { | |
190 lock.wait (); | |
191 } catch (SyncException e) { | |
192 interrupted = true; | |
193 } | |
194 } | |
195 if (interrupted) { | |
196 Compatibility.interrupt(); | |
197 } | |
198 if (lock.throwable !is null) { | |
199 SWT.error (SWT.ERROR_FAILED_EXEC, lock.throwable); | |
200 } | |
201 } | |
202 } | |
203 | |
204 } |