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.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.HashSet;
32 import java.util.IdentityHashMap;
33 import java.util.Map;
34 import java.util.Set;
35
36 import sun.awt.util.ThreadGroupUtils;
37 import sun.misc.ManagedLocalsThread;
38 import sun.util.logging.PlatformLogger;
39
40 /**
41 * This class is to let AWT shutdown automatically when a user is done
42 * with AWT. It tracks AWT state using the following parameters:
43 * <ul>
44 * <li>{@code peerMap} - the map between the existing peer objects
45 * and their associated targets
46 * <li>{@code toolkitThreadBusy} - whether the toolkit thread
47 * is waiting for a new native event to appear in its queue
48 * or is dispatching an event
49 * <li>{@code busyThreadSet} - a set of all the event dispatch
50 * threads that are busy at this moment, i.e. those that are not
51 * waiting for a new event to appear in their event queue.
52 * </ul><p>
53 * AWT is considered to be in ready-to-shutdown state when
54 * {@code peerMap} is empty and {@code toolkitThreadBusy}
55 * is false and {@code busyThreadSet} is empty.
56 * The internal AWTAutoShutdown logic secures that the single non-daemon
57 * thread ({@code blockerThread}) is running when AWT is not in
320 }
321 }
322 if (!interrupted) {
323 AppContext.stopEventDispatchThreads();
324 }
325 }
326
327 @SuppressWarnings("serial")
328 static AWTEvent getShutdownEvent() {
329 return new AWTEvent(getInstance(), 0) {
330 };
331 }
332
333 /**
334 * Creates and starts a new blocker thread. Doesn't return until
335 * the new blocker thread starts.
336 */
337 private void activateBlockerThread() {
338 AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
339 String name = "AWT-Shutdown";
340 Thread thread = new ManagedLocalsThread(
341 ThreadGroupUtils.getRootThreadGroup(), this, name);
342 thread.setContextClassLoader(null);
343 thread.setDaemon(false);
344 blockerThread = thread;
345 return thread;
346 }).start();
347 try {
348 /* Wait for the blocker thread to start. */
349 mainLock.wait();
350 } catch (InterruptedException e) {
351 System.err.println("AWT blocker activation interrupted:");
352 e.printStackTrace();
353 }
354 }
355
356 void registerPeer(final Object target, final Object peer) {
357 synchronized (activationLock) {
358 synchronized (mainLock) {
359 peerMap.put(target, peer);
360 notifyPeerMapUpdated();
361 }
|
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.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.HashSet;
32 import java.util.IdentityHashMap;
33 import java.util.Map;
34 import java.util.Set;
35
36 import sun.awt.util.ThreadGroupUtils;
37 import sun.util.logging.PlatformLogger;
38
39 /**
40 * This class is to let AWT shutdown automatically when a user is done
41 * with AWT. It tracks AWT state using the following parameters:
42 * <ul>
43 * <li>{@code peerMap} - the map between the existing peer objects
44 * and their associated targets
45 * <li>{@code toolkitThreadBusy} - whether the toolkit thread
46 * is waiting for a new native event to appear in its queue
47 * or is dispatching an event
48 * <li>{@code busyThreadSet} - a set of all the event dispatch
49 * threads that are busy at this moment, i.e. those that are not
50 * waiting for a new event to appear in their event queue.
51 * </ul><p>
52 * AWT is considered to be in ready-to-shutdown state when
53 * {@code peerMap} is empty and {@code toolkitThreadBusy}
54 * is false and {@code busyThreadSet} is empty.
55 * The internal AWTAutoShutdown logic secures that the single non-daemon
56 * thread ({@code blockerThread}) is running when AWT is not in
319 }
320 }
321 if (!interrupted) {
322 AppContext.stopEventDispatchThreads();
323 }
324 }
325
326 @SuppressWarnings("serial")
327 static AWTEvent getShutdownEvent() {
328 return new AWTEvent(getInstance(), 0) {
329 };
330 }
331
332 /**
333 * Creates and starts a new blocker thread. Doesn't return until
334 * the new blocker thread starts.
335 */
336 private void activateBlockerThread() {
337 AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
338 String name = "AWT-Shutdown";
339 Thread thread = new Thread(
340 ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false);
341 thread.setContextClassLoader(null);
342 thread.setDaemon(false);
343 blockerThread = thread;
344 return thread;
345 }).start();
346 try {
347 /* Wait for the blocker thread to start. */
348 mainLock.wait();
349 } catch (InterruptedException e) {
350 System.err.println("AWT blocker activation interrupted:");
351 e.printStackTrace();
352 }
353 }
354
355 void registerPeer(final Object target, final Object peer) {
356 synchronized (activationLock) {
357 synchronized (mainLock) {
358 peerMap.put(target, peer);
359 notifyPeerMapUpdated();
360 }
|