9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.awt;
27
28 import java.awt.AWTEvent;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.IdentityHashMap;
32 import java.util.Map;
33 import sun.util.logging.PlatformLogger;
34
35 /**
36 * This class is to let AWT shutdown automatically when a user is done
37 * with AWT. It tracks AWT state using the following parameters:
38 * <ul>
39 * <li><code>peerMap</code> - the map between the existing peer objects
40 * and their associated targets
41 * <li><code>toolkitThreadBusy</code> - whether the toolkit thread
42 * is waiting for a new native event to appear in its queue
43 * or is dispatching an event
44 * <li><code>busyThreadSet</code> - a set of all the event dispatch
45 * threads that are busy at this moment, i.e. those that are not
46 * waiting for a new event to appear in their event queue.
47 * </ul><p>
48 * AWT is considered to be in ready-to-shutdown state when
49 * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
50 * is false and <code>busyThreadSet</code> is empty.
51 * The internal AWTAutoShutdown logic secures that the single non-daemon
52 * thread (<code>blockerThread</code>) is running when AWT is not in
64
65 /**
66 * This lock object is used to synchronize shutdown operations.
67 */
68 private final Object mainLock = new Object();
69
70 /**
71 * This lock object is to secure that when a new blocker thread is
72 * started it will be the first who acquire the main lock after
73 * the thread that created the new blocker released the main lock
74 * by calling lock.wait() to wait for the blocker to start.
75 */
76 private final Object activationLock = new Object();
77
78 /**
79 * This set keeps references to all the event dispatch threads that
80 * are busy at this moment, i.e. those that are not waiting for a
81 * new event to appear in their event queue.
82 * Access is synchronized on the main lock object.
83 */
84 private final HashSet busyThreadSet = new HashSet(7);
85
86 /**
87 * Indicates whether the toolkit thread is waiting for a new native
88 * event to appear or is dispatching an event.
89 */
90 private boolean toolkitThreadBusy = false;
91
92 /**
93 * This is a map between components and their peers.
94 * we should work with in under activationLock&mainLock lock.
95 */
96 private final Map peerMap = new IdentityHashMap();
97
98 /**
99 * References the alive non-daemon thread that is currently used
100 * for keeping AWT from exiting.
101 */
102 private Thread blockerThread = null;
103
104 /**
105 * We need this flag to secure that AWT state hasn't changed while
106 * we were waiting for the safety timeout to pass.
107 */
108 private boolean timeoutPassed = false;
109
110 /**
111 * Once we detect that AWT is ready to shutdown we wait for a certain
112 * timeout to pass before stopping event dispatch threads.
113 */
114 private static final int SAFETY_TIMEOUT = 1000;
115
116 /**
302 blockerThread = null;
303 break;
304 }
305 timeoutPassed = true;
306 mainLock.wait(SAFETY_TIMEOUT);
307 }
308 }
309 } catch (InterruptedException e) {
310 interrupted = true;
311 } finally {
312 if (blockerThread == currentThread) {
313 blockerThread = null;
314 }
315 }
316 }
317 if (!interrupted) {
318 AppContext.stopEventDispatchThreads();
319 }
320 }
321
322 static AWTEvent getShutdownEvent() {
323 return new AWTEvent(getInstance(), 0) {};
324 }
325
326 /**
327 * Creates and starts a new blocker thread. Doesn't return until
328 * the new blocker thread starts.
329 */
330 private void activateBlockerThread() {
331 Thread thread = new Thread(this, "AWT-Shutdown");
332 thread.setDaemon(false);
333 blockerThread = thread;
334 thread.start();
335 try {
336 /* Wait for the blocker thread to start. */
337 mainLock.wait();
338 } catch (InterruptedException e) {
339 System.err.println("AWT blocker activation interrupted:");
340 e.printStackTrace();
341 }
342 }
343
|
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.awt;
27
28 import java.awt.AWTEvent;
29
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.IdentityHashMap;
33 import java.util.Map;
34 import java.util.Set;
35
36 import sun.util.logging.PlatformLogger;
37
38 /**
39 * This class is to let AWT shutdown automatically when a user is done
40 * with AWT. It tracks AWT state using the following parameters:
41 * <ul>
42 * <li><code>peerMap</code> - the map between the existing peer objects
43 * and their associated targets
44 * <li><code>toolkitThreadBusy</code> - whether the toolkit thread
45 * is waiting for a new native event to appear in its queue
46 * or is dispatching an event
47 * <li><code>busyThreadSet</code> - a set of all the event dispatch
48 * threads that are busy at this moment, i.e. those that are not
49 * waiting for a new event to appear in their event queue.
50 * </ul><p>
51 * AWT is considered to be in ready-to-shutdown state when
52 * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
53 * is false and <code>busyThreadSet</code> is empty.
54 * The internal AWTAutoShutdown logic secures that the single non-daemon
55 * thread (<code>blockerThread</code>) is running when AWT is not in
67
68 /**
69 * This lock object is used to synchronize shutdown operations.
70 */
71 private final Object mainLock = new Object();
72
73 /**
74 * This lock object is to secure that when a new blocker thread is
75 * started it will be the first who acquire the main lock after
76 * the thread that created the new blocker released the main lock
77 * by calling lock.wait() to wait for the blocker to start.
78 */
79 private final Object activationLock = new Object();
80
81 /**
82 * This set keeps references to all the event dispatch threads that
83 * are busy at this moment, i.e. those that are not waiting for a
84 * new event to appear in their event queue.
85 * Access is synchronized on the main lock object.
86 */
87 private final Set<Thread> busyThreadSet = new HashSet<>(7);
88
89 /**
90 * Indicates whether the toolkit thread is waiting for a new native
91 * event to appear or is dispatching an event.
92 */
93 private boolean toolkitThreadBusy = false;
94
95 /**
96 * This is a map between components and their peers.
97 * we should work with in under activationLock&mainLock lock.
98 */
99 private final Map<Object, Object> peerMap = new IdentityHashMap<>();
100
101 /**
102 * References the alive non-daemon thread that is currently used
103 * for keeping AWT from exiting.
104 */
105 private Thread blockerThread = null;
106
107 /**
108 * We need this flag to secure that AWT state hasn't changed while
109 * we were waiting for the safety timeout to pass.
110 */
111 private boolean timeoutPassed = false;
112
113 /**
114 * Once we detect that AWT is ready to shutdown we wait for a certain
115 * timeout to pass before stopping event dispatch threads.
116 */
117 private static final int SAFETY_TIMEOUT = 1000;
118
119 /**
305 blockerThread = null;
306 break;
307 }
308 timeoutPassed = true;
309 mainLock.wait(SAFETY_TIMEOUT);
310 }
311 }
312 } catch (InterruptedException e) {
313 interrupted = true;
314 } finally {
315 if (blockerThread == currentThread) {
316 blockerThread = null;
317 }
318 }
319 }
320 if (!interrupted) {
321 AppContext.stopEventDispatchThreads();
322 }
323 }
324
325 @SuppressWarnings("serial")
326 static AWTEvent getShutdownEvent() {
327 return new AWTEvent(getInstance(), 0) {
328 };
329 }
330
331 /**
332 * Creates and starts a new blocker thread. Doesn't return until
333 * the new blocker thread starts.
334 */
335 private void activateBlockerThread() {
336 Thread thread = new Thread(this, "AWT-Shutdown");
337 thread.setDaemon(false);
338 blockerThread = thread;
339 thread.start();
340 try {
341 /* Wait for the blocker thread to start. */
342 mainLock.wait();
343 } catch (InterruptedException e) {
344 System.err.println("AWT blocker activation interrupted:");
345 e.printStackTrace();
346 }
347 }
348
|