corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java
changeset 13171 1ac5e9a54a6e
parent 5555 b2b5ed3f0d0d
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java	Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java	Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,15 @@
 
 package com.sun.corba.se.impl.orbutil.threadpool;
 
+import java.io.IOException;
+
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sun.corba.se.spi.orb.ORB;
+
 import com.sun.corba.se.spi.orbutil.threadpool.NoSuchThreadPoolException;
 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPool;
 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager;
@@ -33,21 +42,102 @@
 import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl;
 import com.sun.corba.se.impl.orbutil.ORBConstants;
 
+import com.sun.corba.se.impl.logging.ORBUtilSystemException;
+import com.sun.corba.se.impl.orbutil.ORBConstants;
+import com.sun.corba.se.spi.logging.CORBALogDomains;
+
+
 public class ThreadPoolManagerImpl implements ThreadPoolManager
 {
-    private ThreadPool threadPool ;
+    private ThreadPool threadPool;
+    private ThreadGroup threadGroup;
+
+    private static final ORBUtilSystemException wrapper =
+        ORBUtilSystemException.get(CORBALogDomains.RPC_TRANSPORT);
+
+    public ThreadPoolManagerImpl() {
+        threadGroup = getThreadGroup();
+        threadPool = new ThreadPoolImpl(threadGroup,
+            ORBConstants.THREADPOOL_DEFAULT_NAME);
+    }
+
+    private static AtomicInteger tgCount = new AtomicInteger();
+
+
+    private ThreadGroup getThreadGroup() {
+        ThreadGroup tg;
 
-    public ThreadPoolManagerImpl( ThreadGroup tg )
-    {
-        // Use unbounded threadpool in J2SE ORB
-        // ThreadPoolManager from s1as appserver code base can be set in the
-        // ORB. ThreadPools in the appserver are bounded. In that situation
-        // the ThreadPool in this ThreadPoolManager will have its threads
-        // die after the idle timeout.
-        // XXX Should there be cleanup when ORB.shutdown is called if the
-        // ORB owns the ThreadPool?
-        threadPool = new ThreadPoolImpl( tg,
-            ORBConstants.THREADPOOL_DEFAULT_NAME ) ;
+        // See bugs 4916766 and 4936203
+        // We intend to create new threads in a reliable thread group.
+        // This avoids problems if the application/applet
+        // creates a thread group, makes JavaIDL calls which create a new
+        // connection and ReaderThread, and then destroys the thread
+        // group. If our ReaderThreads were to be part of such destroyed thread
+        // group then it might get killed and cause other invoking threads
+        // sharing the same connection to get a non-restartable
+        // CommunicationFailure. We'd like to avoid that.
+        //
+        // Our solution is to create all of our threads in the highest thread
+        // group that we have access to, given our own security clearance.
+        //
+        try {
+            // try to get a thread group that's as high in the threadgroup
+            // parent-child hierarchy, as we can get to.
+            // this will prevent an ORB thread created during applet-init from
+            // being killed when an applet dies.
+            tg = AccessController.doPrivileged(
+                new PrivilegedAction<ThreadGroup>() {
+                    public ThreadGroup run() {
+                        ThreadGroup tg = Thread.currentThread().getThreadGroup();
+                        ThreadGroup ptg = tg;
+                        try {
+                            while (ptg != null) {
+                                tg = ptg;
+                                ptg = tg.getParent();
+                            }
+                        } catch (SecurityException se) {
+                            // Discontinue going higher on a security exception.
+                        }
+                        return new ThreadGroup(tg, "ORB ThreadGroup " + tgCount.getAndIncrement());
+                    }
+                }
+            );
+        } catch (SecurityException e) {
+            // something wrong, we go back to the original code
+            tg = Thread.currentThread().getThreadGroup();
+        }
+
+        return tg;
+    }
+
+    public void close() {
+        try {
+            threadPool.close();
+        } catch (IOException exc) {
+            wrapper.threadPoolCloseError();
+        }
+
+        try {
+            boolean isDestroyed = threadGroup.isDestroyed();
+            int numThreads = threadGroup.activeCount();
+            int numGroups = threadGroup.activeGroupCount();
+
+            if (isDestroyed) {
+                wrapper.threadGroupIsDestroyed(threadGroup);
+            } else {
+                if (numThreads > 0)
+                    wrapper.threadGroupHasActiveThreadsInClose(threadGroup, numThreads);
+
+                if (numGroups > 0)
+                    wrapper.threadGroupHasSubGroupsInClose(threadGroup, numGroups);
+
+                threadGroup.destroy();
+            }
+        } catch (IllegalThreadStateException exc) {
+            wrapper.threadGroupDestroyFailed(exc, threadGroup);
+        }
+
+        threadGroup = null;
     }
 
     /**