< prev index next >

src/java.desktop/share/classes/sun/awt/AppContext.java

Print this page

244                 });
245 
246         // Initialize push/pop lock and its condition to be used by all the
247         // EventQueues within this AppContext
248         Lock eventQueuePushPopLock = new ReentrantLock();
249         put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock);
250         Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition();
251         put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond);
252     }
253 
254     private static final ThreadLocal<AppContext> threadAppContext =
255             new ThreadLocal<AppContext>();
256 
257     @SuppressWarnings("removal")
258     private static void initMainAppContext() {
259         // On the main Thread, we get the ThreadGroup, make a corresponding
260         // AppContext, and instantiate the Java EventQueue.  This way, legacy
261         // code is unaffected by the move to multiple AppContext ability.
262         AccessController.doPrivileged(new PrivilegedAction<Void>() {
263             public Void run() {

264                 ThreadGroup currentThreadGroup =
265                         Thread.currentThread().getThreadGroup();
266                 ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
267                 while (parentThreadGroup != null) {
268                     // Find the root ThreadGroup to construct our main AppContext
269                     currentThreadGroup = parentThreadGroup;
270                     parentThreadGroup = currentThreadGroup.getParent();
271                 }
272 
273                 mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
274                 return null;
275             }
276         });
277     }
278 
279     /**
280      * Returns the appropriate AppContext for the caller,
281      * as determined by its ThreadGroup.
282      *
283      * @return  the AppContext for the caller.
284      * @see     java.lang.ThreadGroup
285      * @since   1.2
286      */
287     @SuppressWarnings("removal")
288     public static AppContext getAppContext() {
289         // we are standalone app, return the main app context
290         if (numAppContexts.get() == 1 && mainAppContext != null) {
291             return mainAppContext;
292         }
293 
294         AppContext appContext = threadAppContext.get();
295 
296         if (null == appContext) {
297             appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
298             {
299                 public AppContext run() {
300                     // Get the current ThreadGroup, and look for it and its
301                     // parents in the hash from ThreadGroup to AppContext --
302                     // it should be found, because we use createNewContext()
303                     // when new AppContext objects are created.

304                     ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
305                     ThreadGroup threadGroup = currentThreadGroup;
306 
307                     // Special case: we implicitly create the main app context
308                     // if no contexts have been created yet. This covers standalone apps
309                     // and excludes applets because by the time applet starts
310                     // a number of contexts have already been created by the plugin.
311                     synchronized (getAppContextLock) {
312                         if (numAppContexts.get() == 0) {
313                             if (System.getProperty("javaplugin.version") == null &&
314                                     System.getProperty("javawebstart.version") == null) {
315                                 initMainAppContext();
316                             } else if (System.getProperty("javafx.version") != null &&
317                                     threadGroup.getParent() != null) {
318                                 // Swing inside JavaFX case
319                                 SunToolkit.createNewAppContext();
320                             }
321                         }
322                     }
323 
324                     AppContext context = threadGroup2appContext.get(threadGroup);
325                     while (context == null) {
326                         threadGroup = threadGroup.getParent();
327                         if (threadGroup == null) {
328                             // We've got up to the root thread group and did not find an AppContext
329                             // Try to get it from the security manager
330                             SecurityManager securityManager = System.getSecurityManager();
331                             if (securityManager != null) {

332                                 ThreadGroup smThreadGroup = securityManager.getThreadGroup();
333                                 if (smThreadGroup != null) {
334                                     /*
335                                      * If we get this far then it's likely that
336                                      * the ThreadGroup does not actually belong
337                                      * to the applet, so do not cache it.
338                                      */
339                                     return threadGroup2appContext.get(smThreadGroup);
340                                 }
341                             }
342                             return null;
343                         }
344                         context = threadGroup2appContext.get(threadGroup);
345                     }
346 
347                     // In case we did anything in the above while loop, we add
348                     // all the intermediate ThreadGroups to threadGroup2appContext
349                     // so we won't spin again.
350                     for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
351                         threadGroup2appContext.put(tg, context);

487         // Next, we interrupt all Threads in the ThreadGroup
488         this.threadGroup.interrupt();
489             // Note, the EventDispatchThread we've interrupted may dump an
490             // InterruptedException to the console here.  This needs to be
491             // fixed in the EventDispatchThread, not here.
492 
493         // Next, we sleep 10ms at a time, waiting for all of the active
494         // Threads in the ThreadGroup to exit.
495 
496         long startTime = System.currentTimeMillis();
497         long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
498         while ((this.threadGroup.activeCount() > 0) &&
499                (System.currentTimeMillis() < endTime)) {
500             try {
501                 Thread.sleep(10);
502             } catch (InterruptedException e) { }
503         }
504 
505         // Then, we stop any remaining Threads
506         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
507             threadGroup.stop();





508             return null;
509         });
510 
511         // Next, we sleep 10ms at a time, waiting for all of the active
512         // Threads in the ThreadGroup to die.
513 
514         startTime = System.currentTimeMillis();
515         endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
516         while ((this.threadGroup.activeCount() > 0) &&
517                (System.currentTimeMillis() < endTime)) {
518             try {
519                 Thread.sleep(10);
520             } catch (InterruptedException e) { }
521         }
522 
523         // Next, we remove this and all subThreadGroups from threadGroup2appContext
524         int numSubGroups = this.threadGroup.activeGroupCount();
525         if (numSubGroups > 0) {
526             ThreadGroup [] subGroups = new ThreadGroup[numSubGroups];
527             numSubGroups = this.threadGroup.enumerate(subGroups);

557         }
558 
559         public void run() {
560             final EventQueue eq = (EventQueue)appContext.get(EVENT_QUEUE_KEY);
561             if (eq != null) {
562                 eq.postEvent(AWTAutoShutdown.getShutdownEvent());
563             }
564         }
565     }
566 
567     static final class CreateThreadAction implements PrivilegedAction<Thread> {
568         private final AppContext appContext;
569         private final Runnable runnable;
570 
571         CreateThreadAction(AppContext ac, Runnable r) {
572             appContext = ac;
573             runnable = r;
574         }
575 
576         public Thread run() {

577             Thread t = new Thread(appContext.getThreadGroup(),
578                                   runnable, "AppContext Disposer", 0, false);
579             t.setContextClassLoader(appContext.getContextClassLoader());
580             t.setPriority(Thread.NORM_PRIORITY + 1);
581             t.setDaemon(true);
582             return t;
583         }
584     }
585 
586     static void stopEventDispatchThreads() {
587         for (AppContext appContext: getAppContexts()) {
588             if (appContext.isDisposed()) {
589                 continue;
590             }
591             Runnable r = new PostShutdownEventRunnable(appContext);
592             // For security reasons EventQueue.postEvent should only be called
593             // on a thread that belongs to the corresponding thread group.
594             if (appContext != AppContext.getAppContext()) {
595                 // Create a thread that belongs to the thread group associated
596                 // with the AppContext and invokes EventQueue.postEvent.

244                 });
245 
246         // Initialize push/pop lock and its condition to be used by all the
247         // EventQueues within this AppContext
248         Lock eventQueuePushPopLock = new ReentrantLock();
249         put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock);
250         Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition();
251         put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond);
252     }
253 
254     private static final ThreadLocal<AppContext> threadAppContext =
255             new ThreadLocal<AppContext>();
256 
257     @SuppressWarnings("removal")
258     private static void initMainAppContext() {
259         // On the main Thread, we get the ThreadGroup, make a corresponding
260         // AppContext, and instantiate the Java EventQueue.  This way, legacy
261         // code is unaffected by the move to multiple AppContext ability.
262         AccessController.doPrivileged(new PrivilegedAction<Void>() {
263             public Void run() {
264                 @SuppressWarnings("deprecation")
265                 ThreadGroup currentThreadGroup =
266                         Thread.currentThread().getThreadGroup();
267                 ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
268                 while (parentThreadGroup != null) {
269                     // Find the root ThreadGroup to construct our main AppContext
270                     currentThreadGroup = parentThreadGroup;
271                     parentThreadGroup = currentThreadGroup.getParent();
272                 }
273 
274                 mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
275                 return null;
276             }
277         });
278     }
279 
280     /**
281      * Returns the appropriate AppContext for the caller,
282      * as determined by its ThreadGroup.
283      *
284      * @return  the AppContext for the caller.
285      * @see     java.lang.ThreadGroup
286      * @since   1.2
287      */
288     @SuppressWarnings("removal")
289     public static AppContext getAppContext() {
290         // we are standalone app, return the main app context
291         if (numAppContexts.get() == 1 && mainAppContext != null) {
292             return mainAppContext;
293         }
294 
295         AppContext appContext = threadAppContext.get();
296 
297         if (null == appContext) {
298             appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
299             {
300                 public AppContext run() {
301                     // Get the current ThreadGroup, and look for it and its
302                     // parents in the hash from ThreadGroup to AppContext --
303                     // it should be found, because we use createNewContext()
304                     // when new AppContext objects are created.
305                     @SuppressWarnings("deprecation")
306                     ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
307                     ThreadGroup threadGroup = currentThreadGroup;
308 
309                     // Special case: we implicitly create the main app context
310                     // if no contexts have been created yet. This covers standalone apps
311                     // and excludes applets because by the time applet starts
312                     // a number of contexts have already been created by the plugin.
313                     synchronized (getAppContextLock) {
314                         if (numAppContexts.get() == 0) {
315                             if (System.getProperty("javaplugin.version") == null &&
316                                     System.getProperty("javawebstart.version") == null) {
317                                 initMainAppContext();
318                             } else if (System.getProperty("javafx.version") != null &&
319                                     threadGroup.getParent() != null) {
320                                 // Swing inside JavaFX case
321                                 SunToolkit.createNewAppContext();
322                             }
323                         }
324                     }
325 
326                     AppContext context = threadGroup2appContext.get(threadGroup);
327                     while (context == null) {
328                         threadGroup = threadGroup.getParent();
329                         if (threadGroup == null) {
330                             // We've got up to the root thread group and did not find an AppContext
331                             // Try to get it from the security manager
332                             SecurityManager securityManager = System.getSecurityManager();
333                             if (securityManager != null) {
334                                 @SuppressWarnings("deprecation")
335                                 ThreadGroup smThreadGroup = securityManager.getThreadGroup();
336                                 if (smThreadGroup != null) {
337                                     /*
338                                      * If we get this far then it's likely that
339                                      * the ThreadGroup does not actually belong
340                                      * to the applet, so do not cache it.
341                                      */
342                                     return threadGroup2appContext.get(smThreadGroup);
343                                 }
344                             }
345                             return null;
346                         }
347                         context = threadGroup2appContext.get(threadGroup);
348                     }
349 
350                     // In case we did anything in the above while loop, we add
351                     // all the intermediate ThreadGroups to threadGroup2appContext
352                     // so we won't spin again.
353                     for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
354                         threadGroup2appContext.put(tg, context);

490         // Next, we interrupt all Threads in the ThreadGroup
491         this.threadGroup.interrupt();
492             // Note, the EventDispatchThread we've interrupted may dump an
493             // InterruptedException to the console here.  This needs to be
494             // fixed in the EventDispatchThread, not here.
495 
496         // Next, we sleep 10ms at a time, waiting for all of the active
497         // Threads in the ThreadGroup to exit.
498 
499         long startTime = System.currentTimeMillis();
500         long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
501         while ((this.threadGroup.activeCount() > 0) &&
502                (System.currentTimeMillis() < endTime)) {
503             try {
504                 Thread.sleep(10);
505             } catch (InterruptedException e) { }
506         }
507 
508         // Then, we stop any remaining Threads
509         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
510             int threadCount = threadGroup.activeCount() + 16;
511             Thread[] threads = new Thread[threadCount];
512             threadCount = threadGroup.enumerate(threads);
513             for (int i = 0; i < threadCount; i++) {
514                 threads[i].stop();
515             }
516             return null;
517         });
518 
519         // Next, we sleep 10ms at a time, waiting for all of the active
520         // Threads in the ThreadGroup to die.
521 
522         startTime = System.currentTimeMillis();
523         endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
524         while ((this.threadGroup.activeCount() > 0) &&
525                (System.currentTimeMillis() < endTime)) {
526             try {
527                 Thread.sleep(10);
528             } catch (InterruptedException e) { }
529         }
530 
531         // Next, we remove this and all subThreadGroups from threadGroup2appContext
532         int numSubGroups = this.threadGroup.activeGroupCount();
533         if (numSubGroups > 0) {
534             ThreadGroup [] subGroups = new ThreadGroup[numSubGroups];
535             numSubGroups = this.threadGroup.enumerate(subGroups);

565         }
566 
567         public void run() {
568             final EventQueue eq = (EventQueue)appContext.get(EVENT_QUEUE_KEY);
569             if (eq != null) {
570                 eq.postEvent(AWTAutoShutdown.getShutdownEvent());
571             }
572         }
573     }
574 
575     static final class CreateThreadAction implements PrivilegedAction<Thread> {
576         private final AppContext appContext;
577         private final Runnable runnable;
578 
579         CreateThreadAction(AppContext ac, Runnable r) {
580             appContext = ac;
581             runnable = r;
582         }
583 
584         public Thread run() {
585             @SuppressWarnings("deprecation")
586             Thread t = new Thread(appContext.getThreadGroup(),
587                                   runnable, "AppContext Disposer", 0, false);
588             t.setContextClassLoader(appContext.getContextClassLoader());
589             t.setPriority(Thread.NORM_PRIORITY + 1);
590             t.setDaemon(true);
591             return t;
592         }
593     }
594 
595     static void stopEventDispatchThreads() {
596         for (AppContext appContext: getAppContexts()) {
597             if (appContext.isDisposed()) {
598                 continue;
599             }
600             Runnable r = new PostShutdownEventRunnable(appContext);
601             // For security reasons EventQueue.postEvent should only be called
602             // on a thread that belongs to the corresponding thread group.
603             if (appContext != AppContext.getAppContext()) {
604                 // Create a thread that belongs to the thread group associated
605                 // with the AppContext and invokes EventQueue.postEvent.
< prev index next >