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