corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java
--- 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;
}
/**