Mercurial > hg > release > icedtea6-1.11
changeset 2946:407a06b6d350
S7162902: Umbrella port of a number of corba bug fixes from JDK 6 to jdk7u/8
S6763340: memory leak in com.sun.corba.se.* classes
S6873605: Missing finishedDispatch() call in ORBImpl causes test failures after 5u20 b04
S6980681: CORBA deadlock in Java SE believed to be related to CR 6238477
2012-10-30 Andrew John Hughes <gnu.andrew@redhat.com>
* Makefile.am: Add new patches.
* NEWS: List new backports.
* patches/openjdk/6763340-corba_memory_leak.patch,
* patches/openjdk/6980681-corba_deadlock.patch,
* patches/openjdk/7162902-corba_fixes.patch:
Add a series of CORBA backports, already applied
to the proprietary JDK6 release.
* patches/traceable.patch: Fix
GenerateBreakIteratorData tool so that crashes
have stack traces.
author | Andrew John Hughes <gnu.andrew@redhat.com> |
---|---|
date | Mon, 20 Jan 2014 07:16:23 +0000 |
parents | a3249839270a |
children | 42ad2c13804d |
files | ChangeLog Makefile.am NEWS patches/openjdk/6763340-corba_memory_leak.patch patches/openjdk/6980681-corba_deadlock.patch patches/openjdk/7162902-corba_fixes.patch patches/traceable.patch |
diffstat | 7 files changed, 2771 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Jan 15 12:52:12 2014 -0500 +++ b/ChangeLog Mon Jan 20 07:16:23 2014 +0000 @@ -1,3 +1,16 @@ +2012-10-30 Andrew John Hughes <gnu.andrew@redhat.com> + + * Makefile.am: Add new patches. + * NEWS: List new backports. + * patches/openjdk/6763340-corba_memory_leak.patch, + * patches/openjdk/6980681-corba_deadlock.patch, + * patches/openjdk/7162902-corba_fixes.patch: + Add a series of CORBA backports, already applied + to the proprietary JDK6 release. + * patches/traceable.patch: Fix + GenerateBreakIteratorData tool so that crashes + have stack traces. + 2014-01-15 Omair Majid <omajid@redhat.com> * Makefile (SECURITY_PATCHES): Add patches. @@ -37,7 +50,7 @@ 2014-01-10 Omair Majid <omajid@redhat.com> - * patches/nss-not-enabled-config.patch: Fix path + * patches/nss-not-enabled-config.patch: Fix path to java.security. 2013-11-13 Andrew John Hughes <gnu.andrew@redhat.com>
--- a/Makefile.am Wed Jan 15 12:52:12 2014 -0500 +++ b/Makefile.am Mon Jan 20 07:16:23 2014 +0000 @@ -808,7 +808,11 @@ patches/openjdk/7038711-fix_no-clobber_usage.patch \ patches/disable-cc-incompatible-sanity-checks.patch \ patches/rh995488-rhel_tz_fix.patch \ - patches/openjdk/8025255-tzdata2013g.patch + patches/openjdk/8025255-tzdata2013g.patch \ + patches/openjdk/6763340-corba_memory_leak.patch \ + patches/openjdk/6980681-corba_deadlock.patch \ + patches/openjdk/7162902-corba_fixes.patch \ + patches/traceable.patch if WITH_RHINO ICEDTEA_PATCHES += \
--- a/NEWS Wed Jan 15 12:52:12 2014 -0500 +++ b/NEWS Mon Jan 20 07:16:23 2014 +0000 @@ -47,7 +47,11 @@ * Bug fixes - S8026826: JDK 7 fix for 8010935 broke the build * Backports + - S6763340: memory leak in com.sun.corba.se.* classes + - S6873605: Missing finishedDispatch() call in ORBImpl causes test failures after 5u20 b04 + - S6980681: CORBA deadlock in Java SE believed to be related to CR 6238477 - S6995424: Eliminate dependency to a deprecated API com.sun.security.auth.PolicyFile + - S7162902: Umbrella port of a number of corba bug fixes from JDK 6 to jdk7u/8 New in release 1.11.14 (2013-11-13):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6763340-corba_memory_leak.patch Mon Jan 20 07:16:23 2014 +0000 @@ -0,0 +1,409 @@ +# HG changeset patch +# User robm +# Date 1289846868 28800 +# Node ID cff5a173ec1e89013359e804a3e31736ef6fb462 +# Parent f642c9ec81a07b88a5566ea1dc4f1a9068c7d251 +6763340: memory leak in com.sun.corba.se.* classes +6873605: Missing finishedDispatch() call in ORBImpl causes test failures after 5u20 b04 +Summary: Reviewed by Ken Cavanaugh +Reviewed-by: coffeys + +diff --git a/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java b/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java +@@ -74,6 +74,7 @@ + import com.sun.corba.se.spi.ior.iiop.GIOPVersion; + import com.sun.corba.se.spi.orb.ORB; + import com.sun.corba.se.spi.protocol.CorbaMessageMediator; ++import com.sun.corba.se.spi.protocol.RetryType; + import com.sun.corba.se.spi.transport.CorbaContactInfo; + import com.sun.corba.se.spi.transport.CorbaContactInfoList; + import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator; +@@ -110,7 +111,7 @@ + + // The current retry request status. True if this request is being + // retried and this info object is to be reused, or false otherwise. +- private boolean retryRequest; ++ private RetryType retryRequest; + + // The number of times this info object has been (re)used. This is + // incremented every time a request is retried, and decremented every +@@ -163,7 +164,8 @@ + + // Please keep these in the same order that they're declared above. + +- retryRequest = false; ++ // 6763340 ++ retryRequest = RetryType.NONE; + + // Do not reset entryCount because we need to know when to pop this + // from the stack. +@@ -824,14 +826,15 @@ + /** + * Set or reset the retry request flag. + */ +- void setRetryRequest( boolean retryRequest ) { ++ void setRetryRequest( RetryType retryRequest ) { + this.retryRequest = retryRequest; + } + + /** + * Retrieve the current retry request status. + */ +- boolean getRetryRequest() { ++ RetryType getRetryRequest() { ++ // 6763340 + return this.retryRequest; + } + +diff --git a/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java b/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java +@@ -70,6 +70,7 @@ + import com.sun.corba.se.spi.protocol.CorbaMessageMediator; + import com.sun.corba.se.spi.protocol.ForwardException; + import com.sun.corba.se.spi.protocol.PIHandler; ++import com.sun.corba.se.spi.protocol.RetryType; + import com.sun.corba.se.spi.logging.CORBALogDomains; + + import com.sun.corba.se.impl.logging.InterceptorsSystemException; +@@ -372,9 +373,24 @@ + } + } + +- public Exception invokeClientPIEndingPoint( +- int replyStatus, Exception exception ) +- { ++ // Needed when an error forces a retry AFTER initiateClientPIRequest ++ // but BEFORE invokeClientPIStartingPoint. ++ public Exception makeCompletedClientRequest( int replyStatus, ++ Exception exception ) { ++ ++ // 6763340 ++ return handleClientPIEndingPoint( replyStatus, exception, false ) ; ++ } ++ ++ public Exception invokeClientPIEndingPoint( int replyStatus, ++ Exception exception ) { ++ ++ // 6763340 ++ return handleClientPIEndingPoint( replyStatus, exception, true ) ; ++ } ++ ++ public Exception handleClientPIEndingPoint( ++ int replyStatus, Exception exception, boolean invokeEndingPoint ) { + if( !hasClientInterceptors ) return exception; + if( !isClientPIEnabledForThisThread() ) return exception; + +@@ -388,24 +404,31 @@ + ClientRequestInfoImpl info = peekClientRequestInfoImplStack(); + info.setReplyStatus( piReplyStatus ); + info.setException( exception ); +- interceptorInvoker.invokeClientInterceptorEndingPoint( info ); +- piReplyStatus = info.getReplyStatus(); ++ ++ if (invokeEndingPoint) { ++ // 6763340 ++ interceptorInvoker.invokeClientInterceptorEndingPoint( info ); ++ piReplyStatus = info.getReplyStatus(); ++ } + + // Check reply status: + if( (piReplyStatus == LOCATION_FORWARD.value) || +- (piReplyStatus == TRANSPORT_RETRY.value) ) +- { ++ (piReplyStatus == TRANSPORT_RETRY.value) ) { + // If this is a forward or a retry, reset and reuse + // info object: + info.reset(); +- info.setRetryRequest( true ); ++ ++ // fix for 6763340: ++ if (invokeEndingPoint) { ++ info.setRetryRequest( RetryType.AFTER_RESPONSE ) ; ++ } else { ++ info.setRetryRequest( RetryType.BEFORE_RESPONSE ) ; ++ } + + // ... and return a RemarshalException so the orb internals know + exception = new RemarshalException(); +- } +- else if( (piReplyStatus == SYSTEM_EXCEPTION.value) || +- (piReplyStatus == USER_EXCEPTION.value) ) +- { ++ } else if( (piReplyStatus == SYSTEM_EXCEPTION.value) || ++ (piReplyStatus == USER_EXCEPTION.value) ) { + exception = info.getException(); + } + +@@ -421,18 +444,21 @@ + RequestInfoStack infoStack = + (RequestInfoStack)threadLocalClientRequestInfoStack.get(); + ClientRequestInfoImpl info = null; +- if( !infoStack.empty() ) info = +- (ClientRequestInfoImpl)infoStack.peek(); + +- if( !diiRequest && (info != null) && info.isDIIInitiate() ) { ++ if (!infoStack.empty() ) { ++ info = (ClientRequestInfoImpl)infoStack.peek(); ++ } ++ ++ if (!diiRequest && (info != null) && info.isDIIInitiate() ) { + // In RequestImpl.doInvocation we already called + // initiateClientPIRequest( true ), so ignore this initiate. + info.setDIIInitiate( false ); +- } +- else { ++ } else { + // If there is no info object or if we are not retrying a request, + // push a new ClientRequestInfoImpl on the stack: +- if( (info == null) || !info.getRetryRequest() ) { ++ ++ // 6763340: don't push unless this is not a retry ++ if( (info == null) || !info.getRetryRequest().isRetry() ) { + info = new ClientRequestInfoImpl( orb ); + infoStack.push( info ); + printPush(); +@@ -442,9 +468,15 @@ + // Reset the retry request flag so that recursive calls will + // push a new info object, and bump up entry count so we know + // when to pop this info object: +- info.setRetryRequest( false ); ++ info.setRetryRequest( RetryType.NONE ); + info.incrementEntryCount(); + ++ // KMC 6763340: I don't know why this wasn't set earlier, ++ // but we do not want a retry to pick up the previous ++ // reply status, so clear it here. Most likely a new ++ // info was pushed before, so that this was not a problem. ++ info.setReplyStatus( RequestInfoImpl.UNINITIALIZED ) ; ++ + // If this is a DII request, make sure we ignore the next initiate. + if( diiRequest ) { + info.setDIIInitiate( true ); +@@ -457,25 +489,34 @@ + if( !isClientPIEnabledForThisThread() ) return; + + ClientRequestInfoImpl info = peekClientRequestInfoImplStack(); ++ RetryType rt = info.getRetryRequest() ; + +- // If the replyStatus has not yet been set, this is an indication +- // that the ORB threw an exception before we had a chance to +- // invoke the client interceptor ending points. +- // +- // _REVISIT_ We cannot handle any exceptions or ForwardRequests +- // flagged by the ending points here because there is no way +- // to gracefully handle this in any of the calling code. +- // This is a rare corner case, so we will ignore this for now. +- short replyStatus = info.getReplyStatus(); +- if( replyStatus == info.UNINITIALIZED ) { +- invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION, +- wrapper.unknownRequestInvoke( +- CompletionStatus.COMPLETED_MAYBE ) ) ; ++ // fix for 6763340 ++ if (!rt.equals( RetryType.BEFORE_RESPONSE )) { ++ ++ // If the replyStatus has not yet been set, this is an indication ++ // that the ORB threw an exception before we had a chance to ++ // invoke the client interceptor ending points. ++ // ++ // _REVISIT_ We cannot handle any exceptions or ForwardRequests ++ // flagged by the ending points here because there is no way ++ // to gracefully handle this in any of the calling code. ++ // This is a rare corner case, so we will ignore this for now. ++ short replyStatus = info.getReplyStatus(); ++ if (replyStatus == info.UNINITIALIZED ) { ++ invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION, ++ wrapper.unknownRequestInvoke( ++ CompletionStatus.COMPLETED_MAYBE ) ) ; ++ } + } + + // Decrement entry count, and if it is zero, pop it from the stack. + info.decrementEntryCount(); +- if( info.getEntryCount() == 0 ) { ++ ++ // fix for 6763340, and probably other cases (non-recursive retry) ++ if (info.getEntryCount() == 0 && !info.getRetryRequest().isRetry()) { ++ // RequestInfoStack<ClientRequestInfoImpl> infoStack = ++ // threadLocalClientRequestInfoStack.get(); + RequestInfoStack infoStack = + (RequestInfoStack)threadLocalClientRequestInfoStack.get(); + infoStack.pop(); +diff --git a/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java b/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java +@@ -107,6 +107,11 @@ + return null; + } + ++ public Exception makeCompletedClientRequest( ++ int replyStatus, Exception exception ) { ++ return null; ++ } ++ + public void initiateClientPIRequest( boolean diiRequest ) { + } + +diff --git a/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java b/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java +@@ -187,7 +187,8 @@ + startingPointCall = 0; + intermediatePointCall = 0; + endingPointCall = 0; +- replyStatus = UNINITIALIZED; ++ // 6763340 ++ setReplyStatus( UNINITIALIZED ) ; + currentExecutionPoint = EXECUTION_POINT_STARTING; + alreadyExecuted = false; + connection = null; +diff --git a/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java +@@ -1672,6 +1672,7 @@ + { + StackImpl invocationInfoStack = + (StackImpl)clientInvocationInfoStack.get(); ++ int entryCount = -1; + ClientInvocationInfo clientInvocationInfo = null; + if (!invocationInfoStack.empty()) { + clientInvocationInfo = +@@ -1680,8 +1681,12 @@ + throw wrapper.invocationInfoStackEmpty() ; + } + clientInvocationInfo.decrementEntryCount(); ++ entryCount = clientInvocationInfo.getEntryCount(); + if (clientInvocationInfo.getEntryCount() == 0) { +- invocationInfoStack.pop(); ++ // 6763340: don't pop if this is a retry! ++ if (!clientInvocationInfo.isRetryInvocation()) { ++ invocationInfoStack.pop(); ++ } + finishedDispatch(); + } + } +diff --git a/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java b/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java +@@ -185,6 +185,7 @@ + if(getContactInfoListIterator(orb).hasNext()) { + contactInfo = (ContactInfo) + getContactInfoListIterator(orb).next(); ++ unregisterWaiter(orb); + return beginRequest(self, opName, + isOneWay, contactInfo); + } else { +@@ -292,10 +293,22 @@ + // ContactInfoList outside of subcontract. + // Want to move that update to here. + if (getContactInfoListIterator(orb).hasNext()) { +- contactInfo = (ContactInfo) +- getContactInfoListIterator(orb).next(); ++ contactInfo = (ContactInfo)getContactInfoListIterator(orb).next(); ++ if (orb.subcontractDebugFlag) { ++ dprint( "RemarshalException: hasNext true\ncontact info " + contactInfo ); ++ } ++ ++ // Fix for 6763340: Complete the first attempt before starting another. ++ orb.getPIHandler().makeCompletedClientRequest( ++ ReplyMessage.LOCATION_FORWARD, null ) ; ++ unregisterWaiter(orb); ++ orb.getPIHandler().cleanupClientPIRequest() ; ++ + return beginRequest(self, opName, isOneWay, contactInfo); + } else { ++ if (orb.subcontractDebugFlag) { ++ dprint( "RemarshalException: hasNext false" ); ++ } + ORBUtilSystemException wrapper = + ORBUtilSystemException.get(orb, + CORBALogDomains.RPC_PROTOCOL); +diff --git a/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java b/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java +--- openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java +@@ -142,6 +142,27 @@ + int replyStatus, Exception exception ) ; + + /** ++ * Called when a retry is needed after initiateClientPIRequest but ++ * before invokeClientPIRequest. In this case, we need to properly ++ * balance initiateClientPIRequest/cleanupClientPIRequest calls, ++ * but WITHOUT extraneous calls to invokeClientPIEndingPoint ++ * (see bug 6763340). ++ * ++ * @param replyStatus One of the constants in iiop.messages.ReplyMessage ++ * indicating which reply status to set. ++ * @param exception The exception before ending interception points have ++ * been invoked, or null if no exception at the moment. ++ * @return The exception to be thrown, after having gone through ++ * all ending points, or null if there is no exception to be ++ * thrown. Note that this exception can be either the same or ++ * different from the exception set using setClientPIException. ++ * There are four possible return types: null (no exception), ++ * SystemException, UserException, or RemarshalException. ++ */ ++ Exception makeCompletedClientRequest( ++ int replyStatus, Exception exception ) ; ++ ++ /** + * Invoked when a request is about to be created. Must be called before + * any of the setClientPI* methods so that a new info object can be + * prepared for information collection. +diff --git a/src/share/classes/com/sun/corba/se/spi/protocol/RetryType.java b/src/share/classes/com/sun/corba/se/spi/protocol/RetryType.java +new file mode 100644 +--- /dev/null ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/RetryType.java +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) 2010, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package com.sun.corba.se.spi.protocol ; ++ ++// Introduce more information about WHY we are re-trying a request ++// so we can properly handle the two cases: ++// - BEFORE_RESPONSE means that the retry is caused by ++// something that happened BEFORE the message was sent: either ++// an exception from the SocketFactory, or one from the ++// Client side send_request interceptor point. ++// - AFTER_RESPONSE means that the retry is a result either of the ++// request sent to the server (from the response), or from the ++// Client side receive_xxx interceptor point. ++public enum RetryType { ++ NONE( false ), ++ BEFORE_RESPONSE( true ), ++ AFTER_RESPONSE( true ) ; ++ ++ private final boolean isRetry ; ++ ++ RetryType( boolean isRetry ) { ++ this.isRetry = isRetry ; ++ } ++ ++ public boolean isRetry() { ++ return this.isRetry ; ++ } ++} ; ++
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6980681-corba_deadlock.patch Mon Jan 20 07:16:23 2014 +0000 @@ -0,0 +1,69 @@ +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java 2012-10-30 14:11:07.206514499 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java 2012-10-30 14:12:01.291393721 +0000 +@@ -245,7 +245,14 @@ + // All access to resolver, localResolver, and urlOperation must be protected using + // resolverLock. Do not hold the ORBImpl lock while accessing + // resolver, or deadlocks may occur. +- private Object resolverLock ; ++ // Note that we now have separate locks for each resolver type. This is due ++ // to bug 6980681 and 6238477, which was caused by a deadlock while resolving a ++ // corbaname: URL that contained a reference to the same ORB as the ++ // ORB making the call to string_to_object. This caused a deadlock between the ++ // client thread holding the single lock for access to the urlOperation, ++ // and the server thread handling the client is_a request waiting on the ++ // same lock to access the localResolver. ++ + + // Used for resolver_initial_references and list_initial_services + private Resolver resolver ; +@@ -255,8 +262,14 @@ + + // Converts strings to object references for resolvers and string_to_object + private Operation urlOperation ; ++ 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 ++ // insNamingDelegate. ++ private final Object resolverLock = new Object() ; + + private TaggedComponentFactoryFinder taggedComponentFactoryFinder ; + +@@ -396,7 +409,6 @@ + } + }; + +- resolverLock = new java.lang.Object() ; + + requestDispatcherRegistry = new RequestDispatcherRegistryImpl( + this, ORBConstants.DEFAULT_SCID); +@@ -832,7 +844,7 @@ + if (str == null) + throw wrapper.nullParam() ; + +- synchronized (resolverLock) { ++ synchronized (urlOperationLock) { + org.omg.CORBA.Object obj = (org.omg.CORBA.Object)op.operate( str ) ; + return obj ; + } +@@ -1778,7 +1790,7 @@ + */ + public void setURLOperation( Operation stringToObject ) + { +- synchronized (resolverLock) { ++ synchronized (urlOperationLock) { + urlOperation = stringToObject ; + } + } +@@ -1788,7 +1800,7 @@ + */ + public Operation getURLOperation() + { +- synchronized (resolverLock) { ++ synchronized (urlOperationLock) { + return urlOperation ; + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7162902-corba_fixes.patch Mon Jan 20 07:16:23 2014 +0000 @@ -0,0 +1,2258 @@ +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/encoding/CachedCodeBase.java 2014-01-20 07:08:24.176039206 +0000 +@@ -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<IOR,CodeBase>(); ++ ++ 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 +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java 2014-01-20 07:06:20.430185017 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java 2014-01-20 07:08:24.176039206 +0000 +@@ -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; + +@@ -111,10 +111,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. +@@ -177,6 +177,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. + // +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java 2014-01-20 07:06:20.430185017 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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 +@@ -69,6 +69,9 @@ + public PINoOpHandlerImpl( ) { + } + ++ public void close() { ++ } ++ + public void initialize() { + } + +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerFactoryImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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); ++ } + } +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/monitoring/MonitoringManagerImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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( ) { ++ public MonitoredObject getRootMonitoredObject() { + return rootMonitoredObject; + } ++ ++ public void close() { ++ MonitoringManagerFactory f = ++ MonitoringFactories.getMonitoringManagerFactory(); ++ f.remove(rootMonitoredObject.getName()); ++ } + } +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java 2014-01-20 07:06:20.458185437 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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.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.lang.reflect.Field; ++import java.lang.reflect.Modifier; ++import java.lang.reflect.InvocationTargetException; ++ ++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; +@@ -184,6 +187,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; +@@ -192,6 +196,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). +@@ -219,8 +224,6 @@ + + private int transientServerId ; + +- private ThreadGroup threadGroup ; +- + private ServiceContextRegistry serviceContextRegistry ; + + // Needed here to implement connect/disconnect +@@ -278,6 +281,8 @@ + + private ObjectKeyFactory objectKeyFactory ; + ++ private boolean orbOwnsThreadPoolManager = false ; ++ + private ThreadPoolManager threadpoolMgr; + + private void dprint( String msg ) +@@ -321,11 +326,17 @@ + + public ORBVersion getORBVersion() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + return (ORBVersion)(orbVersionThreadLocal.get()) ; + } + + public void setORBVersion(ORBVersion verObj) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + orbVersionThreadLocal.set(verObj); + } + +@@ -346,46 +357,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 +@@ -546,6 +517,9 @@ + + public void set_parameters( Properties props ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + preInit( null, props ) ; + DataCollector dataCollector = + DataCollectorFactory.create( props, getLocalHostName() ) ; +@@ -787,6 +761,9 @@ + */ + public void notifyORB() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (this.svResponseReceived) { + this.svResponseReceived.set(); + this.svResponseReceived.notify(); +@@ -853,6 +830,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; + +@@ -1117,6 +1096,8 @@ + + public synchronized void setTypeCodeForClass(Class c, TypeCodeImpl tci) + { ++ checkShutdownState(); ++ + if (typeCodeForClassMap == null) + typeCodeForClassMap = Collections.synchronizedMap( + new WeakHashMap(64)); +@@ -1127,6 +1108,8 @@ + + public synchronized TypeCodeImpl getTypeCodeForClass(Class c) + { ++ checkShutdownState(); ++ + if (typeCodeForClassMap == null) + return null; + return (TypeCodeImpl)typeCodeForClassMap.get(c); +@@ -1209,6 +1192,10 @@ + { + CorbaServerRequestDispatcher insnd ; + ++ synchronized (this) { ++ checkShutdownState(); ++ } ++ + if ((id == null) || (id.length() == 0)) + throw new InvalidName() ; + +@@ -1252,66 +1239,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(); + +- 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 ; +- } +- } +- +- // 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. ++ // 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) { ++ wait = true; ++ } else { ++ return; ++ } ++ } ++ ++ status = STATUS_SHUTTING_DOWN; ++ } ++ ++ // 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. +- shutdownServants(wait_for_completion); ++ // 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<ObjectAdapterFactory>(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() + { +@@ -1326,21 +1335,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); ++ } + } + } + +@@ -1349,12 +1377,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) { +@@ -1364,11 +1392,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; + } + + /** +@@ -1433,18 +1526,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()) ; + } +@@ -1458,6 +1560,9 @@ + + public void initBadServerIdHandler() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (badServerIdHandlerAccessLock) { + Class cls = configData.getBadServerIdHandler() ; + if (cls != null) { +@@ -1476,6 +1581,9 @@ + + public void setBadServerIdHandler( BadServerIdHandler handler ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (badServerIdHandlerAccessLock) { + badServerIdHandler = handler; + } +@@ -1483,6 +1591,9 @@ + + public void handleBadServerId( ObjectKey okey ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (badServerIdHandlerAccessLock) { + if (badServerIdHandler == null) + throw wrapper.badServerId() ; +@@ -1531,6 +1642,9 @@ + + public int getTransientServerId() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + if( configData.getORBServerIdPropertySpecified( ) ) { + // ORBServerId is specified then use that value + return configData.getPersistentServerId( ); +@@ -1540,11 +1654,17 @@ + + public RequestDispatcherRegistry getRequestDispatcherRegistry() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + return requestDispatcherRegistry; + } + + public ServiceContextRegistry getServiceContextRegistry() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + return serviceContextRegistry ; + } + +@@ -1562,12 +1682,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( ) ; +@@ -1658,6 +1784,9 @@ + + public ClientInvocationInfo createOrIncrementInvocationInfo() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + StackImpl invocationInfoStack = + (StackImpl) clientInvocationInfoStack.get(); + ClientInvocationInfo clientInvocationInfo = null; +@@ -1681,10 +1810,13 @@ + + public void releaseOrDecrementInvocationInfo() + { +- StackImpl invocationInfoStack = +- (StackImpl)clientInvocationInfoStack.get(); ++ synchronized (this) { ++ checkShutdownState(); ++ } + int entryCount = -1; + ClientInvocationInfo clientInvocationInfo = null; ++ StackImpl invocationInfoStack = ++ (StackImpl)clientInvocationInfoStack.get(); + if (!invocationInfoStack.empty()) { + clientInvocationInfo = + (ClientInvocationInfo)invocationInfoStack.peek(); +@@ -1704,6 +1836,9 @@ + + public ClientInvocationInfo getInvocationInfo() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + StackImpl invocationInfoStack = + (StackImpl) clientInvocationInfoStack.get(); + return (ClientInvocationInfo) invocationInfoStack.peek(); +@@ -1718,6 +1853,9 @@ + + public void setClientDelegateFactory( ClientDelegateFactory factory ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (clientDelegateFactoryAccessorLock) { + clientDelegateFactory = factory ; + } +@@ -1725,6 +1863,9 @@ + + public ClientDelegateFactory getClientDelegateFactory() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (clientDelegateFactoryAccessorLock) { + return clientDelegateFactory ; + } +@@ -1734,6 +1875,9 @@ + + public void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (corbaContactInfoListFactoryAccessLock) { + corbaContactInfoListFactory = factory ; + } +@@ -1741,6 +1885,7 @@ + + public synchronized CorbaContactInfoListFactory getCorbaContactInfoListFactory() + { ++ checkShutdownState(); + return corbaContactInfoListFactory ; + } + +@@ -1749,6 +1894,9 @@ + */ + public void setResolver( Resolver resolver ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (resolverLock) { + this.resolver = resolver ; + } +@@ -1759,6 +1907,9 @@ + */ + public Resolver getResolver() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (resolverLock) { + return resolver ; + } +@@ -1769,6 +1920,9 @@ + */ + public void setLocalResolver( LocalResolver resolver ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (resolverLock) { + this.localResolver = resolver ; + } +@@ -1779,6 +1933,9 @@ + */ + public LocalResolver getLocalResolver() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (resolverLock) { + return localResolver ; + } +@@ -1789,6 +1946,9 @@ + */ + public void setURLOperation( Operation stringToObject ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (urlOperationLock) { + urlOperation = stringToObject ; + } +@@ -1799,6 +1959,9 @@ + */ + public Operation getURLOperation() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (urlOperationLock) { + return urlOperation ; + } +@@ -1806,6 +1969,9 @@ + + public void setINSDelegate( CorbaServerRequestDispatcher sdel ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (resolverLock) { + insNamingDelegate = sdel ; + } +@@ -1813,16 +1979,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 ; + } + +@@ -1830,6 +2005,9 @@ + + public ObjectKeyFactory getObjectKeyFactory() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (objectKeyFactoryAccessLock) { + return objectKeyFactory ; + } +@@ -1837,6 +2015,9 @@ + + public void setObjectKeyFactory( ObjectKeyFactory factory ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (objectKeyFactoryAccessLock) { + objectKeyFactory = factory ; + } +@@ -1863,6 +2044,9 @@ + + public LegacyServerSocketManager getLegacyServerSocketManager() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (legacyServerSocketManagerAccessLock) { + if (legacyServerSocketManager == null) { + legacyServerSocketManager = new LegacyServerSocketManagerImpl(this); +@@ -1875,6 +2059,9 @@ + + public void setThreadPoolManager(ThreadPoolManager mgr) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (threadPoolManagerAccessLock) { + threadpoolMgr = mgr; + } +@@ -1882,9 +2069,13 @@ + + public ThreadPoolManager getThreadPoolManager() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + synchronized (threadPoolManagerAccessLock) { + if (threadpoolMgr == null) { +- threadpoolMgr = new ThreadPoolManagerImpl( threadGroup ); ++ threadpoolMgr = new ThreadPoolManagerImpl(); ++ orbOwnsThreadPoolManager = true; + } + return threadpoolMgr; + } +@@ -1892,6 +2083,9 @@ + + public CopierManager getCopierManager() + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + return copierManager ; + } + } // Class ORBImpl +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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<WorkerThread>(); + + /** + * 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<WorkerThread>(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 @@ + } + + +- /** +- * 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++; +- } 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; +- } +- } else { +- thread = new WorkerThread(threadGroup, getName()); +- currentThreadCount++; +- } ++ 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); + +- // 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 +- } ++ wrapper.workerThreadCreated(thread, thread.getContextClassLoader()); + + thread.start(); ++ return null; + } + ++ + /** +- * This method will return the minimum number of threads maintained +- * by the threadpool. +- */ ++ * To be called from the workqueue to create worker threads when none ++ * available. ++ */ ++ void createWorkerThread() { ++ final String name = getName(); ++ synchronized (workQueue) { ++ try { ++ if (System.getSecurityManager() == null) { ++ createWorkerThreadHelper(name); ++ } else { ++ // If we get here, we need to create a thread. ++ AccessController.doPrivileged( ++ new PrivilegedAction() { ++ public Object run() { ++ return createWorkerThreadHelper(name); ++ } ++ } ++ ); ++ } ++ } 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(); ++ } ++ } ++ } ++ + 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 { +- +- synchronized (lock) { +- availableWorkerThreads++; +- } +- +- // Get some work to do +- currentWork = ((WorkQueueImpl)workQueue).requestWork(inactivityTimeout); ++ public synchronized void close() { ++ closeCalled = true; ++ interrupt(); ++ } + +- 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 resetClassLoader() { + +- // Set the thread name for debugging. +- setName(composeWorkerThreadName(threadPoolName, +- Integer.toString(this.threadId))); ++ } + +- long start = System.currentTimeMillis(); ++ 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(); ++ } + ++ public void run() { ++ try { ++ while (!closeCalled) { + try { +- // Do the work +- currentWork.doWork(); +- } catch (Throwable t) { +- // Ignore all errors. +- ; +- } +- +- long end = System.currentTimeMillis(); ++ currentWork = ((WorkQueueImpl)workQueue).requestWork( ++ inactivityTimeout); ++ if (currentWork == null) ++ continue; ++ } catch (InterruptedException exc) { ++ wrapper.workQueueThreadInterrupted( exc, getName(), ++ Boolean.valueOf(closeCalled)); + ++ continue ; ++ } catch (Throwable t) { ++ wrapper.workerThreadThrowableFromRequestWork(this, t, ++ workQueue.getName()); + +- synchronized (lock) { +- totalTimeTaken += (end - start); +- processedCount++; ++ continue; + } + ++ 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); + } + } + } +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolManagerImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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; ++ ++ // 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); ++ } + +- 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 ) ; ++ threadGroup = null; + } + + /** +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java 2011-11-14 22:06:00.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/orbutil/threadpool/WorkQueueImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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) { +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java 2014-01-20 07:06:14.694099057 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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) { +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java openjdk/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java 2014-01-20 07:06:15.142105771 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java 2014-01-20 07:08:24.180039265 +0000 +@@ -68,8 +68,8 @@ + private HashMap listenerThreads; + private HashMap readerThreads; + private boolean selectorStarted; +- private boolean closed; +- private ORBUtilSystemException wrapper ; ++ private volatile boolean closed; ++ private ORBUtilSystemException wrapper; + + + public SelectorImpl(ORB orb) +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc openjdk/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc 2014-01-20 07:08:24.180039265 +0000 +@@ -1,6 +1,6 @@ + ; + +-; Copyright (c) 2003, 2008, 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") +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManagerFactory.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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); + } +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/monitoring/MonitoringManager.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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 +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java 2014-01-20 07:06:14.110090305 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java 2014-01-20 07:10:22.997819167 +0000 +@@ -172,7 +172,7 @@ + + private static Map staticWrapperMap = new ConcurrentHashMap(); + +- private MonitoringManager monitoringManager; ++ protected MonitoringManager monitoringManager; + + private static PresentationManager setupPresentationManager() { + staticWrapper = ORBUtilSystemException.get( +@@ -221,6 +221,14 @@ + return pm; + } + ++ public void destroy() { ++ wrapper = null; ++ omgWrapper = null; ++ typeCodeMap = null; ++ primitiveTypeCodeConstants = null; ++ byteBufferPool = null; ++ } ++ + /** + * Returns the Presentation Manager for the current thread group, using the ThreadGroup-specific + * AppContext to hold it. Creates and records one if needed. +@@ -306,6 +314,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) { +@@ -315,15 +326,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; + } + +@@ -438,6 +454,9 @@ + */ + public Logger getLogger( String domain ) + { ++ synchronized (this) { ++ checkShutdownState(); ++ } + ORBData odata = getORBData() ; + + // Determine the correct ORBId. There are 3 cases: +@@ -514,6 +533,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); + +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPool.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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 +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/orbutil/threadpool/ThreadPoolManager.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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, +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java 2014-01-20 07:06:20.434185077 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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 +@@ -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 +diff -Nru openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java +--- openjdk.orig/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java 2011-11-14 22:06:01.000000000 +0000 ++++ openjdk/corba/src/share/classes/com/sun/corba/se/spi/protocol/RequestDispatcherRegistry.java 2014-01-20 07:08:24.180039265 +0000 +@@ -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(); + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/traceable.patch Mon Jan 20 07:16:23 2014 +0000 @@ -0,0 +1,12 @@ +diff --git a/make/tools/src/build/tools/generatebreakiteratordata/GenerateBreakIteratorData.java b/make/tools/src/build/tools/generatebreakiteratordata/GenerateBreakIteratorData.java +--- openjdk/jdk/make/tools/src/build/tools/generatebreakiteratordata/GenerateBreakIteratorData.java ++++ openjdk/jdk/make/tools/src/build/tools/generatebreakiteratordata/GenerateBreakIteratorData.java +@@ -115,7 +115,7 @@ + } + } + catch (Exception e) { +- throw new InternalError(e.toString()); ++ throw (Error) new InternalError(e.toString()).initCause(e); + } + } +