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);
+         }
+     }
+