KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 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 - Initial API and implementation
10  * Jeremiah Lott (jeremiah.lott@timesys.com) - fix for deadlock bug 76378
11  *
12  *******************************************************************************/

13 package org.eclipse.ui.internal;
14
15 import org.eclipse.core.runtime.jobs.LockListener;
16 import org.eclipse.swt.widgets.Display;
17
18 /**
19  * The UI lock listener is used to prevent the UI thread from deadlocking on
20  * a lock when the thread owning the lock is attempting to syncExec.
21  */

22 public class UILockListener extends LockListener {
23
24     /**
25      * The Queue is the construct that keeps track of Semaphores.
26      */

27     public class Queue {
28         private static final int BASE_SIZE = 8;
29
30         protected Semaphore[] elements = new Semaphore[BASE_SIZE];
31
32         protected int head = 0;
33
34         protected int tail = 0;
35
36         /**
37          * Add the semaphore to the queue.
38          * @param element
39          */

40         public synchronized void add(Semaphore element) {
41             int newTail = increment(tail);
42             if (newTail == head) {
43                 grow();
44                 newTail = tail + 1;
45             }
46             elements[tail] = element;
47             tail = newTail;
48         }
49
50         private void grow() {
51             int newSize = elements.length * 2;
52             Semaphore[] newElements = new Semaphore[newSize];
53             if (tail >= head) {
54                 System.arraycopy(elements, head, newElements, head, size());
55             } else {
56                 int newHead = newSize - (elements.length - head);
57                 System.arraycopy(elements, 0, newElements, 0, tail + 1);
58                 System.arraycopy(elements, head, newElements, newHead,
59                         (newSize - newHead));
60                 head = newHead;
61             }
62             elements = newElements;
63         }
64
65         private int increment(int index) {
66             return (index == (elements.length - 1)) ? 0 : index + 1;
67         }
68
69         /**
70          * Remove the next semaphore to be woken up.
71          * @return
72          */

73         public synchronized Semaphore remove() {
74             if (tail == head) {
75                 return null;
76             }
77             Semaphore result = elements[head];
78             elements[head] = null;
79             head = increment(head);
80             //reset the queue if it is empty and it has grown
81
if (tail == head && elements.length > BASE_SIZE) {
82                 elements = new Semaphore[BASE_SIZE];
83                 tail = head = 0;
84             }
85             return result;
86         }
87
88         private int size() {
89             return tail > head ? (tail - head)
90                     : ((elements.length - head) + tail);
91         }
92     }
93
94     protected Display display;
95
96     protected final Queue pendingWork = new Queue();
97
98     protected Semaphore currentWork = null;
99
100     protected Thread JavaDoc ui;
101
102     /**
103      * Create a new instance of the receiver.
104      * @param display
105      */

106     public UILockListener(Display display) {
107         this.display = display;
108     }
109
110     public void aboutToRelease() {
111         if (isUI()) {
112             ui = null;
113         }
114     }
115
116     public boolean aboutToWait(Thread JavaDoc lockOwner) {
117         if (isUI()) {
118             // If a syncExec was executed from the current operation, it
119
// has already acquired the lock. So, just return true.
120
if (currentWork != null
121                     && currentWork.getOperationThread() == lockOwner) {
122                 return true;
123             }
124             ui = Thread.currentThread();
125             try {
126                 doPendingWork();
127             } finally {
128                 //UI field may be nulled if there is a nested wait during execution
129
//of pending work, so make sure it is assigned before we start waiting
130
ui = Thread.currentThread();
131             }
132         }
133         return false;
134     }
135
136     void addPendingWork(Semaphore work) {
137         pendingWork.add(work);
138     }
139
140     /**
141      * Should always be called from the UI thread.
142      */

143     void doPendingWork() {
144         //clear the interrupt flag that we may have set in interruptUI()
145
Thread.interrupted();
146         Semaphore work;
147         while ((work = pendingWork.remove()) != null) {
148             //remember the old current work before replacing, to handle
149
//the nested waiting case (bug 76378)
150
Semaphore oldWork = currentWork;
151             try {
152                 currentWork = work;
153                 Runnable JavaDoc runnable = work.getRunnable();
154                 if (runnable != null) {
155                     runnable.run();
156                 }
157
158             } finally {
159                 currentWork = oldWork;
160                 work.release();
161             }
162         }
163     }
164
165     void interruptUI() {
166         display.getThread().interrupt();
167     }
168
169     boolean isLockOwner() {
170         return isLockOwnerThread();
171     }
172
173     boolean isUI() {
174         return (!display.isDisposed())
175                 && (display.getThread() == Thread.currentThread());
176     }
177
178     boolean isUIWaiting() {
179         return (ui != null) && (Thread.currentThread() != ui);
180     }
181 }
182
Popular Tags