7162902: Umbrella port of a number of corba bug fixes from JDK 6 to jdk7u/8
Reviewed-by: lancea
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package com.sun.corba.se.impl.encoding;
import java.util.Hashtable;
@@ -32,7 +31,8 @@
import com.sun.org.omg.SendingContext._CodeBaseImplBase;
import com.sun.org.omg.SendingContext._CodeBaseStub;
import com.sun.corba.se.spi.transport.CorbaConnection;
-
+import com.sun.corba.se.spi.ior.IOR;
+import com.sun.corba.se.spi.orb.ORB;
/**
* Provides the reading side with a per connection cache of
* info obtained via calls to the remote CodeBase.
@@ -51,14 +51,24 @@
*
* Needs cache management.
*/
-// REVISIT: revert to package protected after framework merge.
public class CachedCodeBase extends _CodeBaseImplBase
{
private Hashtable implementations, fvds, bases;
- private CodeBase delegate;
+ private volatile CodeBase delegate;
private CorbaConnection conn;
- private static Hashtable iorToCodeBaseObjMap = new Hashtable();
+ private static Object iorMapLock = new Object();
+ private static Hashtable<IOR,CodeBase> iorMap = new Hashtable<>();
+
+ public static synchronized void cleanCache( ORB orb ) {
+ synchronized (iorMapLock) {
+ for (IOR ior : iorMap.keySet()) {
+ if (ior.getORB() == orb) {
+ iorMap.remove(ior);
+ }
+ }
+ }
+ }
public CachedCodeBase(CorbaConnection connection) {
conn = connection;
@@ -68,7 +78,7 @@
return null;
}
- public String implementation (String repId) {
+ public synchronized String implementation (String repId) {
String urlResult = null;
if (implementations == null)
@@ -86,7 +96,7 @@
return urlResult;
}
- public String[] implementations (String[] repIds) {
+ public synchronized String[] implementations (String[] repIds) {
String[] urlResults = new String[repIds.length];
for (int i = 0; i < urlResults.length; i++)
@@ -95,7 +105,7 @@
return urlResults;
}
- public FullValueDescription meta (String repId) {
+ public synchronized FullValueDescription meta (String repId) {
FullValueDescription result = null;
if (fvds == null)
@@ -113,7 +123,7 @@
return result;
}
- public FullValueDescription[] metas (String[] repIds) {
+ public synchronized FullValueDescription[] metas (String[] repIds) {
FullValueDescription[] results
= new FullValueDescription[repIds.length];
@@ -123,7 +133,7 @@
return results;
}
- public String[] bases (String repId) {
+ public synchronized String[] bases (String repId) {
String[] results = null;
@@ -145,7 +155,7 @@
// Ensures that we've used the connection's IOR to create
// a valid CodeBase delegate. If this returns false, then
// it is not valid to access the delegate.
- private boolean connectedCodeBase() {
+ private synchronized boolean connectedCodeBase() {
if (delegate != null)
return true;
@@ -165,7 +175,7 @@
return false;
}
- synchronized(this) {
+ synchronized(iorMapLock) {
// Recheck the condition to make sure another
// thread didn't already do this while we waited
@@ -173,7 +183,8 @@
return true;
// Do we have a reference initialized by another connection?
- delegate = (CodeBase)CachedCodeBase.iorToCodeBaseObjMap.get(conn.getCodeBaseIOR());
+ delegate = CachedCodeBase.iorMap.get(conn.getCodeBaseIOR());
+
if (delegate != null)
return true;
@@ -181,8 +192,7 @@
delegate = CodeBaseHelper.narrow(getObjectFromIOR());
// Save it for the benefit of other connections
- CachedCodeBase.iorToCodeBaseObjMap.put(conn.getCodeBaseIOR(),
- delegate);
+ CachedCodeBase.iorMap.put(conn.getCodeBaseIOR(), delegate);
}
// It's now safe to use the delegate
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -58,7 +58,7 @@
import org.omg.PortableInterceptor.TRANSPORT_RETRY;
import org.omg.PortableInterceptor.USER_EXCEPTION;
import org.omg.PortableInterceptor.PolicyFactory;
-import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
+import org.omg.PortableInterceptor.ObjectReferenceTemplate;
import com.sun.corba.se.pept.encoding.OutputObject;
@@ -112,10 +112,10 @@
}
}
- private ORB orb ;
- InterceptorsSystemException wrapper ;
- ORBUtilSystemException orbutilWrapper ;
- OMGSystemException omgWrapper ;
+ private ORB orb;
+ InterceptorsSystemException wrapper;
+ ORBUtilSystemException orbutilWrapper;
+ OMGSystemException omgWrapper;
// A unique id used in ServerRequestInfo.
// This does not correspond to the GIOP request id.
@@ -178,6 +178,21 @@
}
};
+ public void close() {
+ orb = null;
+ wrapper = null;
+ orbutilWrapper = null;
+ omgWrapper = null;
+ codecFactory = null;
+ arguments = null;
+ interceptorList = null;
+ interceptorInvoker = null;
+ current = null;
+ policyFactoryTable = null;
+ threadLocalClientRequestInfoStack = null;
+ threadLocalServerRequestInfoStack = null;
+ }
+
// Class to contain all ThreadLocal data for ClientRequestInfo
// maintenance.
//
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, 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
@@ -69,6 +69,9 @@
public PINoOpHandlerImpl( ) {
}
+ public void close() {
+ }
+
public void initialize() {
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -34,14 +34,18 @@
private HashMap monitoringManagerTable = new HashMap();
public synchronized MonitoringManager createMonitoringManager(
- String nameOfTheRoot, String description )
+ String nameOfTheRoot, String description)
{
MonitoringManagerImpl m = null;
m = (MonitoringManagerImpl)monitoringManagerTable.get(nameOfTheRoot);
if (m == null) {
- m = new MonitoringManagerImpl( nameOfTheRoot, description );
+ m = new MonitoringManagerImpl(nameOfTheRoot, description);
monitoringManagerTable.put(nameOfTheRoot, m);
}
return m;
}
+
+ public synchronized void remove(String nameOfTheRoot) {
+ monitoringManagerTable.remove(nameOfTheRoot);
+ }
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -26,6 +26,7 @@
package com.sun.corba.se.impl.monitoring;
import com.sun.corba.se.spi.monitoring.MonitoringManager;
+import com.sun.corba.se.spi.monitoring.MonitoringManagerFactory;
import com.sun.corba.se.spi.monitoring.MonitoredObject;
import com.sun.corba.se.spi.monitoring.MonitoredObjectFactory;
import com.sun.corba.se.spi.monitoring.MonitoringFactories;
@@ -33,18 +34,24 @@
public class MonitoringManagerImpl implements MonitoringManager {
private final MonitoredObject rootMonitoredObject;
- MonitoringManagerImpl( String nameOfTheRoot, String description ) {
+ MonitoringManagerImpl(String nameOfTheRoot, String description) {
MonitoredObjectFactory f =
MonitoringFactories.getMonitoredObjectFactory();
rootMonitoredObject =
- f.createMonitoredObject( nameOfTheRoot, description );
+ f.createMonitoredObject(nameOfTheRoot, description);
+ }
+
+ public void clearState() {
+ rootMonitoredObject.clearState();
}
- public void clearState( ) {
- rootMonitoredObject.clearState( );
+ public MonitoredObject getRootMonitoredObject() {
+ return rootMonitoredObject;
}
- public MonitoredObject getRootMonitoredObject( ) {
- return rootMonitoredObject;
+ public void close() {
+ MonitoringManagerFactory f =
+ MonitoringFactories.getMonitoringManagerFactory();
+ f.remove(rootMonitoredObject.getName());
}
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -23,35 +23,37 @@
* questions.
*/
-package com.sun.corba.se.impl.orb ;
+package com.sun.corba.se.impl.orb;
import java.applet.Applet;
-import java.io.IOException ;
+import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Field ;
-import java.lang.reflect.Modifier ;
-import java.lang.reflect.InvocationTargetException ;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList ;
-import java.util.Iterator ;
-import java.util.Properties ;
-import java.util.Vector ;
-import java.util.Hashtable ;
-import java.util.Map ;
-import java.util.HashMap ;
-import java.util.LinkedList ;
-import java.util.Collection ;
-import java.util.Collections ;
-import java.util.StringTokenizer ;
-import java.util.Enumeration ;
-import java.util.WeakHashMap ;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.StringTokenizer;
+import java.util.Enumeration;
+import java.util.WeakHashMap;
-import java.net.InetAddress ;
+import java.net.InetAddress;
import java.security.PrivilegedAction;
-import java.security.AccessController ;
+import java.security.AccessController;
import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;
@@ -82,18 +84,18 @@
import com.sun.org.omg.SendingContext.CodeBase;
import com.sun.corba.se.pept.broker.Broker;
-import com.sun.corba.se.pept.protocol.ClientInvocationInfo ;
+import com.sun.corba.se.pept.protocol.ClientInvocationInfo;
import com.sun.corba.se.pept.transport.ContactInfo;
import com.sun.corba.se.pept.transport.ConnectionCache;
import com.sun.corba.se.pept.transport.TransportManager;
import com.sun.corba.se.spi.ior.IOR;
-import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder ;
+import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder;
import com.sun.corba.se.spi.ior.TaggedComponentFactoryFinder;
-import com.sun.corba.se.spi.ior.IORFactories ;
-import com.sun.corba.se.spi.ior.ObjectKey ;
-import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
-import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
+import com.sun.corba.se.spi.ior.IORFactories;
+import com.sun.corba.se.spi.ior.ObjectKey;
+import com.sun.corba.se.spi.ior.ObjectKeyFactory;
+import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.oa.OAInvocationInfo;
import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
@@ -122,10 +124,10 @@
import com.sun.corba.se.spi.transport.CorbaContactInfoListFactory;
import com.sun.corba.se.spi.transport.CorbaTransportManager;
import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketManager;
-import com.sun.corba.se.spi.copyobject.CopierManager ;
-import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults ;
-import com.sun.corba.se.spi.presentation.rmi.PresentationManager ;
-import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
+import com.sun.corba.se.spi.copyobject.CopierManager;
+import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
+import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
+import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry;
import com.sun.corba.se.impl.corba.TypeCodeFactory;
@@ -140,6 +142,7 @@
import com.sun.corba.se.impl.corba.RequestImpl;
import com.sun.corba.se.impl.dynamicany.DynAnyFactoryImpl;
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
+import com.sun.corba.se.impl.encoding.CachedCodeBase;
import com.sun.corba.se.impl.interceptors.PIHandlerImpl;
import com.sun.corba.se.impl.interceptors.PINoOpHandlerImpl;
import com.sun.corba.se.impl.ior.TaggedComponentFactoryFinderImpl;
@@ -185,6 +188,7 @@
private java.lang.Object runObj = new java.lang.Object();
private java.lang.Object shutdownObj = new java.lang.Object();
+ private java.lang.Object waitForCompletionObj = new java.lang.Object();
private static final byte STATUS_OPERATING = 1;
private static final byte STATUS_SHUTTING_DOWN = 2;
private static final byte STATUS_SHUTDOWN = 3;
@@ -193,6 +197,7 @@
// XXX Should we move invocation tracking to the first level server dispatcher?
private java.lang.Object invocationObj = new java.lang.Object();
+ private int numInvocations = 0;
// thread local variable to store a boolean to detect deadlock in
// ORB.shutdown(true).
@@ -220,8 +225,6 @@
private int transientServerId ;
- private ThreadGroup threadGroup ;
-
private ServiceContextRegistry serviceContextRegistry ;
// Needed here to implement connect/disconnect
@@ -265,6 +268,7 @@
private final Object urlOperationLock = new java.lang.Object() ;
private CorbaServerRequestDispatcher insNamingDelegate ;
+
// resolverLock must be used for all access to either resolver or
// localResolver, since it is possible for the resolver to indirectly
// refer to the localResolver. Also used to protect access to
@@ -279,6 +283,8 @@
private ObjectKeyFactory objectKeyFactory ;
+ private boolean orbOwnsThreadPoolManager = false ;
+
private ThreadPoolManager threadpoolMgr;
private void dprint( String msg )
@@ -322,11 +328,17 @@
public ORBVersion getORBVersion()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return (ORBVersion)(orbVersionThreadLocal.get()) ;
}
public void setORBVersion(ORBVersion verObj)
{
+ synchronized (this) {
+ checkShutdownState();
+ }
orbVersionThreadLocal.set(verObj);
}
@@ -347,46 +359,6 @@
// end of this method.
pihandler = new PINoOpHandlerImpl( );
- // 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.
- threadGroup = (ThreadGroup) AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object 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");
- }
- }
- );
- } catch (SecurityException e) {
- // something wrong, we go back to the original code
- threadGroup = Thread.currentThread().getThreadGroup();
- }
-
// This is the unique id of this server (JVM). Multiple incarnations
// of this server will get different ids.
// Compute transientServerId = milliseconds since Jan 1, 1970
@@ -547,6 +519,9 @@
public void set_parameters( Properties props )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
preInit( null, props ) ;
DataCollector dataCollector =
DataCollectorFactory.create( props, getLocalHostName() ) ;
@@ -788,6 +763,9 @@
*/
public void notifyORB()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (this.svResponseReceived) {
this.svResponseReceived.set();
this.svResponseReceived.notify();
@@ -854,6 +832,8 @@
// Note that we connect this if we have not already done so.
public synchronized IOR getFVDCodeBaseIOR()
{
+ checkShutdownState();
+
if (codeBaseIOR != null) // i.e. We are already connected to it
return codeBaseIOR;
@@ -1118,6 +1098,8 @@
public synchronized void setTypeCodeForClass(Class c, TypeCodeImpl tci)
{
+ checkShutdownState();
+
if (typeCodeForClassMap == null)
typeCodeForClassMap = Collections.synchronizedMap(
new WeakHashMap(64));
@@ -1128,6 +1110,8 @@
public synchronized TypeCodeImpl getTypeCodeForClass(Class c)
{
+ checkShutdownState();
+
if (typeCodeForClassMap == null)
return null;
return (TypeCodeImpl)typeCodeForClassMap.get(c);
@@ -1210,6 +1194,10 @@
{
CorbaServerRequestDispatcher insnd ;
+ synchronized (this) {
+ checkShutdownState();
+ }
+
if ((id == null) || (id.length() == 0))
throw new InvalidName() ;
@@ -1253,66 +1241,88 @@
}
}
- public void shutdown(boolean wait_for_completion)
- {
- // to wait for completion, we would deadlock, so throw a standard
- // OMG exception.
- if (wait_for_completion && ((Boolean)isProcessingInvocation.get()).booleanValue()) {
- throw omgWrapper.shutdownWaitForCompletionDeadlock() ;
- }
-
- boolean doShutdown = false ;
+ public void shutdown(boolean wait_for_completion) {
+ boolean wait = false;
synchronized (this) {
- checkShutdownState() ;
+ checkShutdownState();
+
+ // This is to avoid deadlock: don't allow a thread that is
+ // processing a request to call shutdown( true ), because
+ // the shutdown would block waiting for the request to complete,
+ // while the request would block waiting for shutdown to complete.
+ if (wait_for_completion &&
+ isProcessingInvocation.get() == Boolean.TRUE) {
+ throw omgWrapper.shutdownWaitForCompletionDeadlock();
+ }
if (status == STATUS_SHUTTING_DOWN) {
- if (!wait_for_completion)
- // If we are already shutting down and don't want
- // to wait, nothing to do: return.
- return ;
- } else {
- // The ORB status was STATUS_OPERATING, so start the shutdown.
- status = STATUS_SHUTTING_DOWN ;
- doShutdown = true ;
+ if (wait_for_completion) {
+ wait = true;
+ } else {
+ return;
+ }
}
+
+ status = STATUS_SHUTTING_DOWN;
}
- // At this point, status is SHUTTING_DOWN.
- // All shutdown calls with wait_for_completion == true must synchronize
- // here. Only the first call will be made with doShutdown == true.
+ // Avoid more than one thread performing shutdown at a time.
synchronized (shutdownObj) {
- if (doShutdown) {
- // shutdownServants will set all POAManagers into the
- // INACTIVE state, causing request to be rejected.
- // If wait_for_completion is true, this will not return until
- // all invocations have completed.
+ // At this point, the ORB status is certainly STATUS_SHUTTING_DOWN.
+ // If wait is true, another thread already called shutdown( true ),
+ // and so we wait for completion
+ if (wait) {
+ while (true) {
+ synchronized (this) {
+ if (status == STATUS_SHUTDOWN)
+ break;
+ }
+
+ try {
+ shutdownObj.wait();
+ } catch (InterruptedException exc) {
+ // NOP: just loop and wait until state is changed
+ }
+ }
+ } else {
+ // perform the actual shutdown
shutdownServants(wait_for_completion);
+ if (wait_for_completion) {
+ synchronized ( waitForCompletionObj ) {
+ while (numInvocations > 0) {
+ try {
+ waitForCompletionObj.wait();
+ } catch (InterruptedException ex) {}
+ }
+ }
+ }
+
synchronized (runObj) {
runObj.notifyAll();
}
- synchronized (this) {
- status = STATUS_SHUTDOWN;
- }
+ status = STATUS_SHUTDOWN;
+
+ shutdownObj.notifyAll();
}
}
}
- /** This method shuts down the ORB and causes orb.run() to return.
- * It will cause all POAManagers to be deactivated, which in turn
- * will cause all POAs to be deactivated.
- */
+ // Cause all ObjectAdapaterFactories to clean up all of their internal state, which
+ // may include activated objects that have associated state and callbacks that must
+ // complete in order to shutdown. This will cause new request to be rejected.
protected void shutdownServants(boolean wait_for_completion) {
- Iterator iter = requestDispatcherRegistry.getObjectAdapterFactories().iterator() ;
- while (iter.hasNext()) {
- ObjectAdapterFactory oaf = (ObjectAdapterFactory)iter.next() ;
- oaf.shutdown( wait_for_completion ) ;
+ Set<ObjectAdapterFactory> oaset;
+ synchronized (this) {
+ oaset = new HashSet<>(requestDispatcherRegistry.getObjectAdapterFactories());
}
+
+ for (ObjectAdapterFactory oaf : oaset)
+ oaf.shutdown(wait_for_completion);
}
- // REVISIT: was protected - made public for framework
// Note that the caller must hold the ORBImpl lock.
public void checkShutdownState()
{
@@ -1327,21 +1337,40 @@
public boolean isDuringDispatch()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
Boolean value = (Boolean)(isProcessingInvocation.get()) ;
return value.booleanValue() ;
}
public void startingDispatch()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (invocationObj) {
isProcessingInvocation.set(Boolean.TRUE);
+ numInvocations++;
}
}
public void finishedDispatch()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (invocationObj) {
- isProcessingInvocation.set(Boolean.FALSE);
+ numInvocations--;
+ isProcessingInvocation.set(false);
+ if (numInvocations == 0) {
+ synchronized (waitForCompletionObj) {
+ waitForCompletionObj.notifyAll();
+ }
+ } else if (numInvocations < 0) {
+ throw wrapper.numInvocationsAlreadyZero(
+ CompletionStatus.COMPLETED_YES);
+ }
}
}
@@ -1350,12 +1379,12 @@
* not been shut down, it will start the shutdown process and block until
* the ORB has shut down before it destroys the ORB."
*/
- public synchronized void destroy()
+ public void destroy()
{
- boolean shutdownFirst = false ;
+ boolean shutdownFirst = false;
synchronized (this) {
- shutdownFirst = (status == STATUS_OPERATING) ;
+ shutdownFirst = (status == STATUS_OPERATING);
}
if (shutdownFirst) {
@@ -1365,11 +1394,76 @@
synchronized (this) {
if (status < STATUS_DESTROYED) {
getCorbaTransportManager().close();
- getPIHandler().destroyInterceptors() ;
+ getPIHandler().destroyInterceptors();
status = STATUS_DESTROYED;
}
}
+ synchronized (threadPoolManagerAccessLock) {
+ if (orbOwnsThreadPoolManager) {
+ try {
+ threadpoolMgr.close();
+ threadpoolMgr = null;
+ } catch (IOException exc) {
+ wrapper.ioExceptionOnClose(exc);
+ }
+ }
+ }
+ try {
+ monitoringManager.close();
+ monitoringManager = null;
+ } catch (IOException exc) {
+ wrapper.ioExceptionOnClose(exc);
+ }
+
+ CachedCodeBase.cleanCache(this);
+ try {
+ pihandler.close();
+ } catch (IOException exc) {
+ wrapper.ioExceptionOnClose(exc);
+ }
+
+ super.destroy();
+
+ badServerIdHandlerAccessLock = null;
+ clientDelegateFactoryAccessorLock = null;
+ corbaContactInfoListFactoryAccessLock = null;
+
+ objectKeyFactoryAccessLock = null;
+ legacyServerSocketManagerAccessLock = null;
+ threadPoolManagerAccessLock = null;
+ transportManager = null;
+ legacyServerSocketManager = null;
+ OAInvocationInfoStack = null;
+ clientInvocationInfoStack = null;
+ codeBaseIOR = null;
+ dynamicRequests = null;
+ svResponseReceived = null;
+ runObj = null;
+ shutdownObj = null;
+ waitForCompletionObj = null;
+ invocationObj = null;
+ isProcessingInvocation = null;
+ typeCodeForClassMap = null;
+ valueFactoryCache = null;
+ orbVersionThreadLocal = null;
+ requestDispatcherRegistry = null;
+ copierManager = null;
+ toaFactory = null;
+ poaFactory = null;
+ pihandler = null;
+ configData = null;
+ badServerIdHandler = null;
+ clientDelegateFactory = null;
+ corbaContactInfoListFactory = null;
+ resolver = null;
+ localResolver = null;
+ insNamingDelegate = null;
+ urlOperation = null;
+ taggedComponentFactoryFinder = null;
+ taggedProfileFactoryFinder = null;
+ taggedProfileTemplateFactoryFinder = null;
+ objectKeyFactory = null;
}
/**
@@ -1434,18 +1528,27 @@
public OAInvocationInfo peekInvocationInfo()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
return (OAInvocationInfo)(stack.peek()) ;
}
public void pushInvocationInfo( OAInvocationInfo info )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
stack.push( info ) ;
}
public OAInvocationInfo popInvocationInfo()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
return (OAInvocationInfo)(stack.pop()) ;
}
@@ -1459,6 +1562,9 @@
public void initBadServerIdHandler()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (badServerIdHandlerAccessLock) {
Class cls = configData.getBadServerIdHandler() ;
if (cls != null) {
@@ -1477,6 +1583,9 @@
public void setBadServerIdHandler( BadServerIdHandler handler )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (badServerIdHandlerAccessLock) {
badServerIdHandler = handler;
}
@@ -1484,6 +1593,9 @@
public void handleBadServerId( ObjectKey okey )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (badServerIdHandlerAccessLock) {
if (badServerIdHandler == null)
throw wrapper.badServerId() ;
@@ -1532,6 +1644,9 @@
public int getTransientServerId()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
if( configData.getORBServerIdPropertySpecified( ) ) {
// ORBServerId is specified then use that value
return configData.getPersistentServerId( );
@@ -1541,11 +1656,17 @@
public RequestDispatcherRegistry getRequestDispatcherRegistry()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return requestDispatcherRegistry;
}
public ServiceContextRegistry getServiceContextRegistry()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return serviceContextRegistry ;
}
@@ -1563,12 +1684,18 @@
// XXX What about multi-homed host?
public boolean isLocalHost( String hostName )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return hostName.equals( configData.getORBServerHost() ) ||
hostName.equals( getLocalHostName() ) ;
}
public boolean isLocalServerId( int subcontractId, int serverId )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
if ((subcontractId < ORBConstants.FIRST_POA_SCID) ||
(subcontractId > ORBConstants.MAX_POA_SCID))
return serverId == getTransientServerId( ) ;
@@ -1659,6 +1786,9 @@
public ClientInvocationInfo createOrIncrementInvocationInfo()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
StackImpl invocationInfoStack =
(StackImpl) clientInvocationInfoStack.get();
ClientInvocationInfo clientInvocationInfo = null;
@@ -1682,10 +1812,13 @@
public void releaseOrDecrementInvocationInfo()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
+ int entryCount = -1;
+ ClientInvocationInfo clientInvocationInfo = null;
StackImpl invocationInfoStack =
(StackImpl)clientInvocationInfoStack.get();
- int entryCount = -1;
- ClientInvocationInfo clientInvocationInfo = null;
if (!invocationInfoStack.empty()) {
clientInvocationInfo =
(ClientInvocationInfo)invocationInfoStack.peek();
@@ -1705,6 +1838,9 @@
public ClientInvocationInfo getInvocationInfo()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
StackImpl invocationInfoStack =
(StackImpl) clientInvocationInfoStack.get();
return (ClientInvocationInfo) invocationInfoStack.peek();
@@ -1719,6 +1855,9 @@
public void setClientDelegateFactory( ClientDelegateFactory factory )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (clientDelegateFactoryAccessorLock) {
clientDelegateFactory = factory ;
}
@@ -1726,6 +1865,9 @@
public ClientDelegateFactory getClientDelegateFactory()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (clientDelegateFactoryAccessorLock) {
return clientDelegateFactory ;
}
@@ -1735,6 +1877,9 @@
public void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (corbaContactInfoListFactoryAccessLock) {
corbaContactInfoListFactory = factory ;
}
@@ -1742,6 +1887,7 @@
public synchronized CorbaContactInfoListFactory getCorbaContactInfoListFactory()
{
+ checkShutdownState();
return corbaContactInfoListFactory ;
}
@@ -1750,6 +1896,9 @@
*/
public void setResolver( Resolver resolver )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (resolverLock) {
this.resolver = resolver ;
}
@@ -1760,6 +1909,9 @@
*/
public Resolver getResolver()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (resolverLock) {
return resolver ;
}
@@ -1770,6 +1922,9 @@
*/
public void setLocalResolver( LocalResolver resolver )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (resolverLock) {
this.localResolver = resolver ;
}
@@ -1780,6 +1935,9 @@
*/
public LocalResolver getLocalResolver()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (resolverLock) {
return localResolver ;
}
@@ -1790,6 +1948,9 @@
*/
public void setURLOperation( Operation stringToObject )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (urlOperationLock) {
urlOperation = stringToObject ;
}
@@ -1800,6 +1961,9 @@
*/
public Operation getURLOperation()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (urlOperationLock) {
return urlOperation ;
}
@@ -1807,6 +1971,9 @@
public void setINSDelegate( CorbaServerRequestDispatcher sdel )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (resolverLock) {
insNamingDelegate = sdel ;
}
@@ -1814,16 +1981,25 @@
public TaggedComponentFactoryFinder getTaggedComponentFactoryFinder()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return taggedComponentFactoryFinder ;
}
public IdentifiableFactoryFinder getTaggedProfileFactoryFinder()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return taggedProfileFactoryFinder ;
}
public IdentifiableFactoryFinder getTaggedProfileTemplateFactoryFinder()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return taggedProfileTemplateFactoryFinder ;
}
@@ -1831,6 +2007,9 @@
public ObjectKeyFactory getObjectKeyFactory()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (objectKeyFactoryAccessLock) {
return objectKeyFactory ;
}
@@ -1838,6 +2017,9 @@
public void setObjectKeyFactory( ObjectKeyFactory factory )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (objectKeyFactoryAccessLock) {
objectKeyFactory = factory ;
}
@@ -1864,6 +2046,9 @@
public LegacyServerSocketManager getLegacyServerSocketManager()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (legacyServerSocketManagerAccessLock) {
if (legacyServerSocketManager == null) {
legacyServerSocketManager = new LegacyServerSocketManagerImpl(this);
@@ -1876,6 +2061,9 @@
public void setThreadPoolManager(ThreadPoolManager mgr)
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (threadPoolManagerAccessLock) {
threadpoolMgr = mgr;
}
@@ -1883,9 +2071,13 @@
public ThreadPoolManager getThreadPoolManager()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
synchronized (threadPoolManagerAccessLock) {
if (threadpoolMgr == null) {
- threadpoolMgr = new ThreadPoolManagerImpl( threadGroup );
+ threadpoolMgr = new ThreadPoolManagerImpl();
+ orbOwnsThreadPoolManager = true;
}
return threadpoolMgr;
}
@@ -1893,6 +2085,9 @@
public CopierManager getCopierManager()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
return copierManager ;
}
} // Class ORBImpl
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.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,18 @@
package com.sun.corba.se.impl.orbutil.threadpool;
+import java.io.IOException;
+import java.io.Closeable;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
import com.sun.corba.se.spi.orbutil.threadpool.NoSuchWorkQueueException;
import com.sun.corba.se.spi.orbutil.threadpool.ThreadPool;
import com.sun.corba.se.spi.orbutil.threadpool.Work;
@@ -36,12 +48,27 @@
import com.sun.corba.se.spi.monitoring.MonitoringConstants;
import com.sun.corba.se.spi.monitoring.MonitoredObject;
import com.sun.corba.se.spi.monitoring.MonitoringFactories;
+import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.monitoring.LongMonitoredAttributeBase;
+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 ThreadPoolImpl implements ThreadPool
{
- private static int threadCounter = 0; // serial counter useful for debugging
+ // serial counter useful for debugging
+ private static AtomicInteger threadCounter = new AtomicInteger(0);
+ private static final ORBUtilSystemException wrapper =
+ ORBUtilSystemException.get(CORBALogDomains.RPC_TRANSPORT);
+
+ // Any time currentThreadCount and/or availableWorkerThreads is updated
+ // or accessed this ThreadPool's WorkQueue must be locked. And, it is
+ // expected that this ThreadPool's WorkQueue is the only object that
+ // updates and accesses these values directly and indirectly though a
+ // call to a method in this ThreadPool. If any call to update or access
+ // those values must synchronized on this ThreadPool's WorkQueue.
private WorkQueue workQueue;
// Stores the number of available worker threads
@@ -65,14 +92,11 @@
// Running count of the work items processed
// Set the value to 1 so that divide by zero is avoided in
// averageWorkCompletionTime()
- private long processedCount = 1;
+ private AtomicLong processedCount = new AtomicLong(1);
// Running aggregate of the time taken in millis to execute work items
// processed by the threads in the threadpool
- private long totalTimeTaken = 0;
-
- // Lock for protecting state when required
- private Object lock = new Object();
+ private AtomicLong totalTimeTaken = new AtomicLong(0);
// Name of the ThreadPool
private String name;
@@ -81,7 +105,10 @@
private MonitoredObject threadpoolMonitoredObject;
// ThreadGroup in which threads should be created
- private ThreadGroup threadGroup ;
+ private ThreadGroup threadGroup;
+
+ Object workersLock = new Object();
+ List<WorkerThread> workers = new ArrayList<>();
/**
* This constructor is used to create an unbounded threadpool
@@ -90,7 +117,7 @@
inactivityTimeout = ORBConstants.DEFAULT_INACTIVITY_TIMEOUT;
maxWorkerThreads = Integer.MAX_VALUE;
workQueue = new WorkQueueImpl(this);
- threadGroup = tg ;
+ threadGroup = tg;
name = threadpoolName;
initializeMonitoring();
}
@@ -121,6 +148,30 @@
initializeMonitoring();
}
+ // Note that this method should not return until AFTER all threads have died.
+ public void close() throws IOException {
+
+ // Copy to avoid concurrent modification problems.
+ List<WorkerThread> copy = null;
+ synchronized (workersLock) {
+ copy = new ArrayList<>(workers);
+ }
+
+ for (WorkerThread wt : copy) {
+ wt.close();
+ while (wt.getState() != Thread.State.TERMINATED) {
+ try {
+ wt.join();
+ } catch (InterruptedException exc) {
+ wrapper.interruptedJoinCallWhileClosingThreadPool(exc, wt, this);
+ }
+ }
+ }
+
+ threadGroup = null;
+ }
+
+
// Setup monitoring for this threadpool
private void initializeMonitoring() {
// Get root monitored object
@@ -217,8 +268,8 @@
* or notify waiting threads on the queue for available work
*/
void notifyForAvailableWork(WorkQueue aWorkQueue) {
- synchronized (lock) {
- if (availableWorkerThreads == 0) {
+ synchronized (aWorkQueue) {
+ if (availableWorkerThreads < aWorkQueue.workItemsInQueue()) {
createWorkerThread();
} else {
aWorkQueue.notify();
@@ -227,120 +278,145 @@
}
+ private Thread createWorkerThreadHelper( String name ) {
+ // Thread creation needs to be in a doPrivileged block
+ // if there is a non-null security manager for two reasons:
+ // 1. The creation of a thread in a specific ThreadGroup
+ // is a privileged operation. Lack of a doPrivileged
+ // block here causes an AccessControlException
+ // (see bug 6268145).
+ // 2. We want to make sure that the permissions associated
+ // with this thread do NOT include the permissions of
+ // the current thread that is calling this method.
+ // This leads to problems in the app server where
+ // some threads in the ThreadPool randomly get
+ // bad permissions, leading to unpredictable
+ // permission errors (see bug 6021011).
+ //
+ // A Java thread contains a stack of call frames,
+ // one for each method called that has not yet returned.
+ // Each method comes from a particular class. The class
+ // was loaded by a ClassLoader which has an associated
+ // CodeSource, and this determines the Permissions
+ // for all methods in that class. The current
+ // Permissions for the thread are the intersection of
+ // all Permissions for the methods on the stack.
+ // This is part of the Security Context of the thread.
+ //
+ // When a thread creates a new thread, the new thread
+ // inherits the security context of the old thread.
+ // This is bad in a ThreadPool, because different
+ // creators of threads may have different security contexts.
+ // This leads to occasional unpredictable errors when
+ // a thread is re-used in a different security context.
+ //
+ // Avoiding this problem is simple: just do the thread
+ // creation in a doPrivileged block. This sets the
+ // inherited security context to that of the code source
+ // for the ORB code itself, which contains all permissions
+ // in either Java SE or Java EE.
+ WorkerThread thread = new WorkerThread(threadGroup, name);
+ synchronized (workersLock) {
+ workers.add(thread);
+ }
+
+ // The thread must be set to a daemon thread so the
+ // VM can exit if the only threads left are PooledThreads
+ // or other daemons. We don't want to rely on the
+ // calling thread always being a daemon.
+ // Note that no exception is possible here since we
+ // are inside the doPrivileged block.
+ thread.setDaemon(true);
+
+ wrapper.workerThreadCreated(thread, thread.getContextClassLoader());
+
+ thread.start();
+ return null;
+ }
+
+
/**
* To be called from the workqueue to create worker threads when none
* available.
*/
void createWorkerThread() {
- WorkerThread thread;
-
- synchronized (lock) {
- if (boundedThreadPool) {
- if (currentThreadCount < maxWorkerThreads) {
- thread = new WorkerThread(threadGroup, getName());
- currentThreadCount++;
+ final String name = getName();
+ synchronized (workQueue) {
+ try {
+ if (System.getSecurityManager() == null) {
+ createWorkerThreadHelper(name);
} else {
- // REVIST - Need to create a thread to monitor the
- // the state for deadlock i.e. all threads waiting for
- // something which can be got from the item in the
- // workqueue, but there is no thread available to
- // process that work item - DEADLOCK !!
- return;
+ // If we get here, we need to create a thread.
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return createWorkerThreadHelper(name);
+ }
+ }
+ );
}
- } else {
- thread = new WorkerThread(threadGroup, getName());
- currentThreadCount++;
+ } catch (Throwable t) {
+ // Decrementing the count of current worker threads.
+ // But, it will be increased in the finally block.
+ decrementCurrentNumberOfThreads();
+ wrapper.workerThreadCreationFailure(t);
+ } finally {
+ incrementCurrentNumberOfThreads();
}
}
-
- // The thread must be set to a daemon thread so the
- // VM can exit if the only threads left are PooledThreads
- // or other daemons. We don't want to rely on the
- // calling thread always being a daemon.
-
- // Catch exceptions since setDaemon can cause a
- // security exception to be thrown under netscape
- // in the Applet mode
- try {
- thread.setDaemon(true);
- } catch (Exception e) {
- // REVISIT - need to do some logging here
- }
-
- thread.start();
}
- /**
- * This method will return the minimum number of threads maintained
- * by the threadpool.
- */
public int minimumNumberOfThreads() {
return minWorkerThreads;
}
- /**
- * This method will return the maximum number of threads in the
- * threadpool at any point in time, for the life of the threadpool
- */
public int maximumNumberOfThreads() {
return maxWorkerThreads;
}
- /**
- * This method will return the time in milliseconds when idle
- * threads in the threadpool are removed.
- */
public long idleTimeoutForThreads() {
return inactivityTimeout;
}
- /**
- * This method will return the total number of threads currently in the
- * threadpool. This method returns a value which is not synchronized.
- */
public int currentNumberOfThreads() {
- synchronized (lock) {
+ synchronized (workQueue) {
return currentThreadCount;
}
}
- /**
- * This method will return the number of available threads in the
- * threadpool which are waiting for work. This method returns a
- * value which is not synchronized.
- */
+ void decrementCurrentNumberOfThreads() {
+ synchronized (workQueue) {
+ currentThreadCount--;
+ }
+ }
+
+ void incrementCurrentNumberOfThreads() {
+ synchronized (workQueue) {
+ currentThreadCount++;
+ }
+ }
+
public int numberOfAvailableThreads() {
- synchronized (lock) {
+ synchronized (workQueue) {
return availableWorkerThreads;
}
}
- /**
- * This method will return the number of busy threads in the threadpool
- * This method returns a value which is not synchronized.
- */
public int numberOfBusyThreads() {
- synchronized (lock) {
+ synchronized (workQueue) {
return (currentThreadCount - availableWorkerThreads);
}
}
- /**
- * This method returns the average elapsed time taken to complete a Work
- * item in milliseconds.
- */
public long averageWorkCompletionTime() {
- synchronized (lock) {
- return (totalTimeTaken / processedCount);
+ synchronized (workQueue) {
+ return (totalTimeTaken.get() / processedCount.get());
}
}
- /**
- * This method returns the number of Work items processed by the threadpool
- */
public long currentProcessedCount() {
- synchronized (lock) {
- return processedCount;
+ synchronized (workQueue) {
+ return processedCount.get();
}
}
@@ -357,15 +433,37 @@
private static synchronized int getUniqueThreadId() {
- return ThreadPoolImpl.threadCounter++;
+ return ThreadPoolImpl.threadCounter.incrementAndGet();
+ }
+
+ /**
+ * This method will decrement the number of available threads
+ * in the threadpool which are waiting for work. Called from
+ * WorkQueueImpl.requestWork()
+ */
+ void decrementNumberOfAvailableThreads() {
+ synchronized (workQueue) {
+ availableWorkerThreads--;
+ }
+ }
+
+ /**
+ * This method will increment the number of available threads
+ * in the threadpool which are waiting for work. Called from
+ * WorkQueueImpl.requestWork()
+ */
+ void incrementNumberOfAvailableThreads() {
+ synchronized (workQueue) {
+ availableWorkerThreads++;
+ }
}
- private class WorkerThread extends Thread
+ private class WorkerThread extends Thread implements Closeable
{
private Work currentWork;
private int threadId = 0; // unique id for the thread
- // thread pool this WorkerThread belongs too
+ private volatile boolean closeCalled = false;
private String threadPoolName;
// name seen by Thread.getName()
private StringBuffer workerThreadName = new StringBuffer();
@@ -377,100 +475,61 @@
setName(composeWorkerThreadName(threadPoolName, "Idle"));
}
- public void run() {
- while (true) {
- try {
+ public synchronized void close() {
+ closeCalled = true;
+ interrupt();
+ }
- synchronized (lock) {
- availableWorkerThreads++;
- }
+ private void resetClassLoader() {
- // Get some work to do
- currentWork = ((WorkQueueImpl)workQueue).requestWork(inactivityTimeout);
+ }
- synchronized (lock) {
- availableWorkerThreads--;
- // It is possible in notifyForAvailableWork that the
- // check for availableWorkerThreads = 0 may return
- // false, because the availableWorkerThreads has not been
- // decremented to zero before the producer thread added
- // work to the queue. This may create a deadlock, if the
- // executing thread needs information which is in the work
- // item queued in the workqueue, but has no thread to work
- // on it since none was created because availableWorkerThreads = 0
- // returned false.
- // The following code will ensure that a thread is always available
- // in those situations
- if ((availableWorkerThreads == 0) &&
- (workQueue.workItemsInQueue() > 0)) {
- createWorkerThread();
- }
- }
+ private void performWork() {
+ long start = System.currentTimeMillis();
+ try {
+ currentWork.doWork();
+ } catch (Throwable t) {
+ wrapper.workerThreadDoWorkThrowable(this, t);
+ }
+ long elapsedTime = System.currentTimeMillis() - start;
+ totalTimeTaken.addAndGet(elapsedTime);
+ processedCount.incrementAndGet();
+ }
- // Set the thread name for debugging.
- setName(composeWorkerThreadName(threadPoolName,
- Integer.toString(this.threadId)));
-
- long start = System.currentTimeMillis();
+ public void run() {
+ try {
+ while (!closeCalled) {
+ try {
+ currentWork = ((WorkQueueImpl)workQueue).requestWork(
+ inactivityTimeout);
+ if (currentWork == null)
+ continue;
+ } catch (InterruptedException exc) {
+ wrapper.workQueueThreadInterrupted( exc, getName(),
+ Boolean.valueOf(closeCalled));
- try {
- // Do the work
- currentWork.doWork();
+ continue ;
} catch (Throwable t) {
- // Ignore all errors.
- ;
+ wrapper.workerThreadThrowableFromRequestWork(this, t,
+ workQueue.getName());
+
+ continue;
}
- long end = System.currentTimeMillis();
-
-
- synchronized (lock) {
- totalTimeTaken += (end - start);
- processedCount++;
- }
+ performWork();
// set currentWork to null so that the work item can be
- // garbage collected
+ // garbage collected without waiting for the next work item.
currentWork = null;
- setName(composeWorkerThreadName(threadPoolName, "Idle"));
-
- } catch (TimeoutException e) {
- // This thread timed out waiting for something to do.
-
- synchronized (lock) {
- availableWorkerThreads--;
-
- // This should for both bounded and unbounded case
- if (currentThreadCount > minWorkerThreads) {
- currentThreadCount--;
- // This thread can exit.
- return;
- } else {
- // Go back to waiting on workQueue
- continue;
- }
- }
- } catch (InterruptedException ie) {
- // InterruptedExceptions are
- // caught here. Thus, threads can be forced out of
- // requestWork and so they have to reacquire the lock.
- // Other options include ignoring or
- // letting this thread die.
- // Ignoring for now. REVISIT
- synchronized (lock) {
- availableWorkerThreads--;
- }
-
- } catch (Throwable e) {
-
- // Ignore any exceptions that currentWork.process
- // accidently lets through, but let Errors pass.
- // Add debugging output? REVISIT
- synchronized (lock) {
- availableWorkerThreads--;
- }
-
+ resetClassLoader();
+ }
+ } catch (Throwable e) {
+ // This should not be possible
+ wrapper.workerThreadCaughtUnexpectedThrowable(this,e);
+ } finally {
+ synchronized (workersLock) {
+ workers.remove(this);
}
}
}
--- 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;
}
/**
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -111,24 +111,23 @@
return workqueueMonitoredObject;
}
- public void addWork(Work work) {
- synchronized (this) {
+ public synchronized void addWork(Work work) {
workItemsAdded++;
work.setEnqueueTime(System.currentTimeMillis());
theWorkQueue.addLast(work);
((ThreadPoolImpl)workerThreadPool).notifyForAvailableWork(this);
- }
}
- Work requestWork(long waitTime)
- throws TimeoutException, InterruptedException
+ synchronized Work requestWork(long waitTime) throws TimeoutException, InterruptedException
{
Work workItem;
- synchronized (this) {
+ ((ThreadPoolImpl)workerThreadPool).incrementNumberOfAvailableThreads();
+
if (theWorkQueue.size() != 0) {
workItem = (Work)theWorkQueue.removeFirst();
totalTimeInQueue += System.currentTimeMillis() - workItem.getEnqueueTime();
workItemsDequeued++;
+ ((ThreadPoolImpl)workerThreadPool).decrementNumberOfAvailableThreads();
return workItem;
}
@@ -145,6 +144,7 @@
workItem = (Work)theWorkQueue.removeFirst();
totalTimeInQueue += System.currentTimeMillis() - workItem.getEnqueueTime();
workItemsDequeued++;
+ ((ThreadPoolImpl)workerThreadPool).decrementNumberOfAvailableThreads();
return workItem;
}
@@ -152,12 +152,13 @@
} while (remainingWaitTime > 0);
+ ((ThreadPoolImpl)workerThreadPool).decrementNumberOfAvailableThreads();
throw new TimeoutException();
} catch (InterruptedException ie) {
+ ((ThreadPoolImpl)workerThreadPool).decrementNumberOfAvailableThreads();
throw ie;
}
- }
}
public void setThreadPool(ThreadPool workerThreadPool) {
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1666,7 +1666,9 @@
((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
ORB orb = (ORB)messageMediator.getBroker();
- orb.checkShutdownState();
+ synchronized (orb) {
+ orb.checkShutdownState();
+ }
ObjectKey okey = messageMediator.getObjectKey();
if (orb.subcontractDebugFlag) {
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, 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
@@ -69,8 +69,8 @@
private HashMap listenerThreads;
private Map readerThreads;
private boolean selectorStarted;
- private boolean closed;
- private ORBUtilSystemException wrapper ;
+ private volatile boolean closed;
+ private ORBUtilSystemException wrapper;
public SelectorImpl(ORB orb)
--- a/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc Wed Jun 27 21:09:29 2012 +0100
@@ -1,6 +1,6 @@
;
-; Copyright (c) 2003, 2011, 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
@@ -62,6 +62,7 @@
(IS_LOCAL_REQUIRES_STUB 43 WARNING "Call to StubAdapter.isLocal did not pass a stub")
(REQUEST_REQUIRES_STUB 44 WARNING "Call to StubAdapter.request did not pass a stub")
(BAD_ACTIVATE_TIE_CALL 45 WARNING "Call to StubAdapter.activateTie did not pass a valid Tie")
+ (IO_EXCEPTION_ON_CLOSE 46 FINE "Useless exception on call to Closeable.close()")
)
(BAD_PARAM
(NULL_PARAM 1 WARNING "Null parameter")
@@ -291,7 +292,31 @@
(JAVA_STREAM_INIT_FAILED 95 WARNING "Java stream initialization failed")
(DUPLICATE_ORB_VERSION_SERVICE_CONTEXT 96 WARNING "An ORBVersionServiceContext was already in the service context list")
(DUPLICATE_SENDING_CONTEXT_SERVICE_CONTEXT 97 WARNING "A SendingContextServiceContext was already in the service context list")
+ (WORK_QUEUE_THREAD_INTERRUPTED 98 FINE "Worker Thread from thread pool {0} was interrupted: closeCalled is {1}.")
+ (WORKER_THREAD_CREATED
+ 104 FINE "Worker thread {0} has been created with ClassLoader {1}")
+ (WORKER_THREAD_THROWABLE_FROM_REQUEST_WORK
+ 109 FINE "Worker thread {0} caught throwable {1} when requesting work from work queue {2}.")
+ (WORKER_THREAD_NOT_NEEDED
+ 110 FINE "Worker thread {0} will exit; current thread count, {1}, greater than minunum worker threads needed, {2}.")
+ (WORKER_THREAD_DO_WORK_THROWABLE
+ 111 FINE "Worker thread {0} caught throwable {1} while executing work.")
+ (WORKER_THREAD_CAUGHT_UNEXPECTED_THROWABLE
+ 112 WARNING "Worker thread {0} caught unexpected throwable {1}.")
+ (WORKER_THREAD_CREATION_FAILURE
+ 113 SEVERE "Worker thread creation failure; cause {0}.")
+ (WORKER_THREAD_SET_NAME_FAILURE
+ 114 WARNING "Unable to set worker thread {0} name to {1}; cause {2}.")
+ (WORK_QUEUE_REQUEST_WORK_NO_WORK_FOUND
+ 116 WARNING "Ignoring unexpected {0} when retrieving of work from work queue, {1}.")
+ (THREAD_POOL_CLOSE_ERROR 126 WARNING "Error in closing ThreadPool")
+ (THREAD_GROUP_IS_DESTROYED 127 WARNING "ThreadGroup {0} is already destroyed: can't destroy it")
+ (THREAD_GROUP_HAS_ACTIVE_THREADS_IN_CLOSE 128 WARNING "ThreadGroup {0} has {1} active threads: destroy may cause exception")
+ (THREAD_GROUP_HAS_SUB_GROUPS_IN_CLOSE 129 WARNING "ThreadGroup {0} has {1} sub-thread groups: destroy may cause exception")
+ (THREAD_GROUP_DESTROY_FAILED 130 WARNING "ThreadGroup {0} could not be destroyed")
+ (INTERRUPTED_JOIN_CALL_WHILE_CLOSING_THREAD_POOL 131 WARNING "Join was interrupted on thread {0} while closing ThreadPool {1}")
)
+
(MARSHAL
(CHUNK_OVERFLOW 1 WARNING "Data read past end of chunk without closing the chunk")
(UNEXPECTED_EOF 2 WARNING "Grow buffer strategy called underflow handler")
--- a/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -24,6 +24,7 @@
*/
package com.sun.corba.se.spi.monitoring;
+import java.io.Closeable;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.monitoring.MonitoredObject;
import java.util.*;
@@ -39,7 +40,7 @@
* @author Hemanth Puttaswamy
* </p>
*/
-public interface MonitoringManager {
+public interface MonitoringManager extends Closeable {
///////////////////////////////////////
// operations
--- a/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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
@@ -40,4 +40,6 @@
*/
MonitoringManager createMonitoringManager( String nameOfTheRoot,
String description );
+
+ void remove(String nameOfTheRoot);
}
--- a/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -171,7 +171,7 @@
private static Map staticWrapperMap = new ConcurrentHashMap();
- private MonitoringManager monitoringManager;
+ protected MonitoringManager monitoringManager;
// There is only one instance of the PresentationManager
// that is shared between all ORBs. This is necessary
@@ -226,6 +226,14 @@
globalPM.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ;
}
+ public void destroy() {
+ wrapper = null;
+ omgWrapper = null;
+ typeCodeMap = null;
+ primitiveTypeCodeConstants = null;
+ byteBufferPool = null;
+ }
+
/** Get the single instance of the PresentationManager
*/
public static PresentationManager getPresentationManager()
@@ -302,6 +310,9 @@
// Typecode support: needed in both ORBImpl and ORBSingleton
public TypeCodeImpl get_primitive_tc(int kind)
{
+ synchronized (this) {
+ checkShutdownState();
+ }
try {
return primitiveTypeCodeConstants[kind] ;
} catch (Throwable t) {
@@ -311,15 +322,20 @@
public synchronized void setTypeCode(String id, TypeCodeImpl code)
{
+ checkShutdownState();
typeCodeMap.put(id, code);
}
public synchronized TypeCodeImpl getTypeCode(String id)
{
+ checkShutdownState();
return (TypeCodeImpl)typeCodeMap.get(id);
}
public MonitoringManager getMonitoringManager( ) {
+ synchronized (this) {
+ checkShutdownState();
+ }
return monitoringManager;
}
@@ -434,6 +450,9 @@
*/
public Logger getLogger( String domain )
{
+ synchronized (this) {
+ checkShutdownState();
+ }
ORBData odata = getORBData() ;
// Determine the correct ORBId. There are 3 cases:
@@ -510,6 +529,9 @@
// This method must also be inherited by both ORB and ORBSingleton.
public ByteBufferPool getByteBufferPool()
{
+ synchronized (this) {
+ checkShutdownState();
+ }
if (byteBufferPool == null)
byteBufferPool = new ByteBufferPoolImpl(this);
--- a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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,9 +25,15 @@
package com.sun.corba.se.spi.orbutil.threadpool;
+import java.io.Closeable;
-public interface ThreadPool
+/** This interface defines a thread pool execution service. The ORB uses this
+ * interface, which preceeds the JDK 5 ExecutorService. Note that the close
+ * method must be called in order to reclaim thread resources.
+ */
+public interface ThreadPool extends Closeable
{
+
/**
* This method will return any instance of the WorkQueue. If the ThreadPool
* instance only services one WorkQueue then that WorkQueue instance will
--- a/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 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,7 +25,9 @@
package com.sun.corba.se.spi.orbutil.threadpool;
-public interface ThreadPoolManager
+import java.io.Closeable;
+
+public interface ThreadPoolManager extends Closeable
{
/**
* This method will return an instance of the threadpool given a threadpoolId,
--- a/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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,8 @@
package com.sun.corba.se.spi.protocol;
+import java.io.Closeable;
+
import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
import org.omg.PortableInterceptor.Interceptor ;
import org.omg.PortableInterceptor.Current ;
@@ -51,7 +53,7 @@
/** This interface defines the PI interface that is used to interface the rest of the
* ORB to the PI implementation.
*/
-public interface PIHandler {
+public interface PIHandler extends Closeable {
/** Complete the initialization of the PIHandler. This will execute the methods
* on the ORBInitializers, if any are defined. This must be done here so that
* the ORB can obtain the PIHandler BEFORE the ORBInitializers run, since they
--- a/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java Wed Jul 05 18:14:56 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java Wed Jun 27 21:09:29 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -37,33 +37,59 @@
* This is a registry of all subcontract ID dependent objects. This includes:
* LocalClientRequestDispatcherFactory, ClientRequestDispatcher, ServerRequestDispatcher, and
* ObjectAdapterFactory.
- * XXX Should the registerXXX methods take an scid or not? I think we
- * want to do this so that the same instance can be shared across multiple
- * scids (and this is already true for ObjectAdapterFactory and LocalClientRequestDispatcherFactory),
- * but this will require some changes for ClientRequestDispatcher and ServerRequestDispatcher.
*/
public interface RequestDispatcherRegistry {
- // XXX needs javadocs!
+ /** Register a ClientRequestDispatcher for a particular subcontract ID.
+ * The subcontract ID appears in the ObjectKey of an object reference, and is used
+ * to control how a remote method invocation is processed by the ORB for a
+ * particular kind of object reference.
+ */
void registerClientRequestDispatcher( ClientRequestDispatcher csc, int scid) ;
+ /** Get the ClientRequestDispatcher for subcontract ID scid.
+ */
ClientRequestDispatcher getClientRequestDispatcher( int scid ) ;
+ /** Register a LocalClientRequestDispatcher for a particular subcontract ID.
+ * The subcontract ID appears in the ObjectKey of an object reference, and is used
+ * to control how a particular kind of colocated request is processed.
+ */
void registerLocalClientRequestDispatcherFactory( LocalClientRequestDispatcherFactory csc, int scid) ;
+ /** Get the LocalClientRequestDispatcher for subcontract ID scid.
+ */
LocalClientRequestDispatcherFactory getLocalClientRequestDispatcherFactory( int scid ) ;
+ /** Register a CorbaServerRequestDispatcher for a particular subcontract ID.
+ * The subcontract ID appears in the ObjectKey of an object reference, and is used
+ * to control how a particular kind of request is processed when received by the ORB.
+ */
void registerServerRequestDispatcher( CorbaServerRequestDispatcher ssc, int scid) ;
+ /** Get the CorbaServerRequestDispatcher for subcontract ID scid.
+ */
CorbaServerRequestDispatcher getServerRequestDispatcher(int scid) ;
+ /** Register a CorbaServerRequestDispatcher for handling an explicit object key name.
+ * This is used for non-standard invocations such as INS and the bootstrap name service.
+ */
void registerServerRequestDispatcher( CorbaServerRequestDispatcher ssc, String name ) ;
+ /** Get the CorbaServerRequestDispatcher for a particular object key.
+ */
CorbaServerRequestDispatcher getServerRequestDispatcher( String name ) ;
+ /** Register an ObjectAdapterFactory for a particular subcontract ID.
+ * This controls how Object references are created and managed.
+ */
void registerObjectAdapterFactory( ObjectAdapterFactory oaf, int scid) ;
+ /** Get the ObjectAdapterFactory for a particular subcontract ID scid.
+ */
ObjectAdapterFactory getObjectAdapterFactory( int scid ) ;
- Set getObjectAdapterFactories() ;
+ /** Return the set of all ObjectAdapterFactory instances that are registered.
+ */
+ Set<ObjectAdapterFactory> getObjectAdapterFactories();
}