6372405: Server thread hangs when fragments don't complete because of connection abort
authortbell
Mon, 20 Apr 2009 00:12:19 -0700
changeset 2664 a0a22a8f16bd
parent 2553 a8134c4ee2cf
child 2665 dcd08203a4cf
child 2711 56edbef7d472
6372405: Server thread hangs when fragments don't complete because of connection abort 5104239: Java: thread deadlock 6191561: JCK15: api/org_omg/PortableInterceptor/ClientRequestInfo/index.html#RIMethods sometime hang 6486322: org.omg.CORBA.ORB.init() thread safety issue 6420980: Security issue with the com.sun.corba.se.impl.orbutil.ORBUtility class 6465377: NullPointerException for RMI ORB in 1.5.0_08 6553303: Corba application fails w/ org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 203 completed: No 6438259: Wrong repository ID generated by IDLJ Reviewed-by: darcy
corba/src/share/classes/com/sun/corba/se/impl/encoding/BufferManagerReadStream.java
corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
corba/src/share/classes/com/sun/corba/se/impl/oa/poa/POAFactory.java
corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java
corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
corba/src/share/classes/com/sun/corba/se/impl/resolver/INSURLOperationImpl.java
corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc
corba/src/share/classes/com/sun/tools/corba/se/idl/Parser.java
corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java
corba/src/share/classes/org/omg/CORBA/ORB.java
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/BufferManagerReadStream.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/BufferManagerReadStream.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  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
@@ -44,6 +44,7 @@
     // We should convert endOfStream to a final static dummy end node
     private boolean endOfStream = true;
     private BufferQueue fragmentQueue = new BufferQueue();
+    private long FRAGMENT_TIMEOUT = 60000;
 
     // REVISIT - This should go in BufferManagerRead. But, since
     //           BufferManagerRead is an interface. BufferManagerRead
@@ -111,9 +112,16 @@
                     throw wrapper.endOfStream() ;
                 }
 
+                boolean interrupted = false;
                 try {
-                    fragmentQueue.wait();
-                } catch (InterruptedException e) {}
+                    fragmentQueue.wait(FRAGMENT_TIMEOUT);
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                }
+
+                if (!interrupted && fragmentQueue.size() == 0) {
+                    throw wrapper.bufferReadManagerTimeout();
+                }
 
                 if (receivedCancel) {
                     throw new RequestCanceledException(cancelReqId);
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  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
@@ -153,22 +153,22 @@
                 desc = new ObjectStreamClass(cl, superdesc,
                                              serializable, externalizable);
             }
+            // Must always call init.  See bug 4488137.  This code was
+            // incorrectly changed to return immediately on a non-null
+            // cache result.  That allowed threads to gain access to
+            // unintialized instances.
+            //
+            // History: Note, the following init() call was originally within
+            // the synchronization block, as it currently is now. Later, the
+            // init() call was moved outside the synchronization block, and
+            // the init() method used a private member variable lock, to
+            // avoid performance problems. See bug 4165204. But that lead to
+            // a deadlock situation, see bug 5104239. Hence, the init() method
+            // has now been moved back into the synchronization block. The
+            // right approach to solving these problems would be to rewrite
+            // this class, based on the latest java.io.ObjectStreamClass.
+            desc.init();
         }
-
-        // Must always call init.  See bug 4488137.  This code was
-        // incorrectly changed to return immediately on a non-null
-        // cache result.  That allowed threads to gain access to
-        // unintialized instances.
-        //
-        // All threads must sync on the member variable lock
-        // and check the initialization state.
-        //
-        // Another possibility is to continue to synchronize on the
-        // descriptorFor array, but that leads to poor performance
-        // (see bug 4165204 "ObjectStreamClass can hold global lock
-        // for a very long time").
-        desc.init();
-
         return desc;
     }
 
--- a/corba/src/share/classes/com/sun/corba/se/impl/oa/poa/POAFactory.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/oa/poa/POAFactory.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2007 Sun Microsystems, Inc.  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
@@ -76,6 +76,7 @@
     private ORB orb ;
     private POASystemException wrapper ;
     private OMGSystemException omgWrapper ;
+    private boolean isShuttingDown = false;
 
     public POASystemException getWrapper()
     {
@@ -166,6 +167,7 @@
         // pm.deactivate removes itself from poaManagers!
         Iterator managers = null ;
         synchronized (this) {
+            isShuttingDown = true ;
             managers = (new HashSet(poaManagers)).iterator();
         }
 
@@ -208,9 +210,15 @@
             ClosureFactory.makeFuture( rpClosure ) ) ;
     }
 
+
     public synchronized POA getRootPOA()
     {
         if (rootPOA == null) {
+            // See if we are trying to getRootPOA while shutting down the ORB.
+            if (isShuttingDown) {
+                throw omgWrapper.noObjectAdaptor( ) ;
+            }
+
             try {
                 Object obj = orb.resolve_initial_references(
                     ORBConstants.ROOT_POA_NAME ) ;
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2007 Sun Microsystems, Inc.  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
@@ -185,7 +185,6 @@
 
     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;
@@ -194,7 +193,6 @@
 
     // 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).
@@ -1245,37 +1243,48 @@
 
     public void shutdown(boolean wait_for_completion)
     {
-        synchronized (this) {
-            checkShutdownState();
+        // to wait for completion, we would deadlock, so throw a standard
+        // OMG exception.
+        if (wait_for_completion && ((Boolean)isProcessingInvocation.get()).booleanValue()) {
+            throw omgWrapper.shutdownWaitForCompletionDeadlock() ;
         }
 
-        // Avoid more than one thread performing shutdown at a time.
-        synchronized (shutdownObj) {
-            checkShutdownState();
-            // This is to avoid deadlock
-            if (wait_for_completion &&
-                isProcessingInvocation.get() == Boolean.TRUE) {
-                throw omgWrapper.shutdownWaitForCompletionDeadlock() ;
+        boolean doShutdown = false ;
+
+        synchronized (this) {
+            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 ;
             }
+        }
 
-            status = STATUS_SHUTTING_DOWN;
-            // XXX access to requestDispatcherRegistry should be protected
-            // by the ORBImpl instance monitor, but is not here in the
-            // shutdownServants call.
-            shutdownServants(wait_for_completion);
-            if (wait_for_completion) {
-                synchronized ( waitForCompletionObj ) {
-                    while (numInvocations > 0) {
-                        try {
-                            waitForCompletionObj.wait();
-                        } catch (InterruptedException ex) {}
-                    }
+        // 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.
+        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);
+
+                synchronized (runObj) {
+                    runObj.notifyAll();
+                }
+
+                synchronized (this) {
+                    status = STATUS_SHUTDOWN;
                 }
             }
-            synchronized ( runObj ) {
-                runObj.notifyAll();
-            }
-            status = STATUS_SHUTDOWN;
         }
     }
 
@@ -1314,23 +1323,13 @@
     {
         synchronized (invocationObj) {
             isProcessingInvocation.set(Boolean.TRUE);
-            numInvocations++;
         }
     }
 
     public void finishedDispatch()
     {
         synchronized (invocationObj) {
-            numInvocations--;
             isProcessingInvocation.set(Boolean.FALSE);
-            if (numInvocations == 0) {
-                synchronized (waitForCompletionObj) {
-                    waitForCompletionObj.notifyAll();
-                }
-            } else if (numInvocations < 0) {
-                throw wrapper.numInvocationsAlreadyZero(
-                    CompletionStatus.COMPLETED_YES ) ;
-            }
         }
     }
 
@@ -1341,12 +1340,24 @@
      */
     public synchronized void destroy()
     {
-        if (status == STATUS_OPERATING) {
+        boolean shutdownFirst = false ;
+
+        synchronized (this) {
+            shutdownFirst = (status == STATUS_OPERATING) ;
+        }
+
+        if (shutdownFirst) {
             shutdown(true);
         }
-        getCorbaTransportManager().close();
-        getPIHandler().destroyInterceptors() ;
-        status = STATUS_DESTROYED;
+
+        synchronized (this) {
+            if (status < STATUS_DESTROYED) {
+                getCorbaTransportManager().close();
+                getPIHandler().destroyInterceptors() ;
+                status = STATUS_DESTROYED;
+            }
+        }
+
     }
 
     /**
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2006 Sun Microsystems, Inc.  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
@@ -135,7 +135,7 @@
 public class ORBSingleton extends ORB
 {
     // This is used to support read_Object.
-    private static ORB fullORB;
+    private ORB fullORB;
     private static PresentationManager.StubFactoryFactory staticStubFactoryFactory =
         PresentationDefaults.getStaticStubFactoryFactory() ;
 
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2006 Sun Microsystems, Inc.  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
@@ -806,25 +806,6 @@
         return result ;
     }
 
-    public static void setDaemon(Thread thread)
-    {
-        // Catch exceptions since setDaemon can cause a
-        // security exception to be thrown under netscape
-        // in the Applet mode
-        final Thread finalThread = thread;
-        try {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public java.lang.Object run() {
-                        finalThread.setDaemon(true);
-                        return null;
-                    }
-                });
-        } catch (Exception e) {
-            // REVISIT: Object to get static method. Ignore it.
-            dprint(new Object(), "setDaemon: Exception: " + e);
-        }
-    }
-
     public static String operationNameAndRequestId(CorbaMessageMediator m)
     {
         return "op/" + m.getOperationName() + " id/" + m.getRequestId();
--- a/corba/src/share/classes/com/sun/corba/se/impl/resolver/INSURLOperationImpl.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/resolver/INSURLOperationImpl.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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
@@ -53,7 +53,8 @@
 import com.sun.corba.se.spi.resolver.Resolver;
 
 import com.sun.corba.se.impl.encoding.EncapsInputStream;
-import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
+import com.sun.corba.se.impl.logging.ORBUtilSystemException;
+import com.sun.corba.se.impl.logging.OMGSystemException;
 import com.sun.corba.se.impl.naming.namingutil.INSURLHandler;
 import com.sun.corba.se.impl.naming.namingutil.IIOPEndpointInfo;
 import com.sun.corba.se.impl.naming.namingutil.INSURL;
@@ -76,6 +77,7 @@
 {
     ORB orb;
     ORBUtilSystemException wrapper ;
+    OMGSystemException omgWrapper ;
     Resolver bootstrapResolver ;
 
     // Root Naming Context for default resolution of names.
@@ -90,6 +92,8 @@
         this.orb = orb ;
         wrapper = ORBUtilSystemException.get( orb,
             CORBALogDomains.ORB_RESOLVER ) ;
+        omgWrapper = OMGSystemException.get( orb,
+            CORBALogDomains.ORB_RESOLVER ) ;
         this.bootstrapResolver = bootstrapResolver ;
     }
 
@@ -126,6 +130,8 @@
                 return getIORFromString( str ) ;
             else {
                 INSURL insURL = insURLHandler.parseURL( str ) ;
+                if (insURL == null)
+                    throw omgWrapper.soBadSchemeName() ;
                 return resolveINSURL( insURL ) ;
             }
         }
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2001-2007 Sun Microsystems, Inc.  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
@@ -1057,7 +1057,9 @@
 
             // IIOPOutputStream will cleanup the connection info when it
             // sees this exception.
-            throw wrapper.writeErrorSend(e1) ;
+            SystemException exc = wrapper.writeErrorSend(e1);
+            purgeCalls(exc, false, true);
+            throw exc;
         }
     }
 
--- a/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/corba/se/spi/logging/data/ORBUtil.mc	Mon Apr 20 00:12:19 2009 -0700
@@ -1,6 +1,6 @@
 ;
 
-; Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+; Copyright 2003-2008 Sun Microsystems, Inc.  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
@@ -144,6 +144,8 @@
 	     15 WARNING "Read of full message failed : bytes requested = {0} bytes read = {1} max wait time = {2} total time spent waiting = {3}")
 	    (CREATE_LISTENER_FAILED 
 	     16 SEVERE "Unable to create listener thread on the specified port: {0}")
+	    (BUFFER_READ_MANAGER_TIMEOUT
+	     17 WARNING "Timeout while reading data in buffer manager")
 	    )
 	(DATA_CONVERSION
 	    (BAD_STRINGIFIED_IOR_LEN 1  WARNING "A character did not map to the transmission code set")
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/Parser.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/Parser.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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
@@ -2086,8 +2086,8 @@
 
     if (token.type == Token.LeftBrace) {
       repIDStack.push(((IDLID)repIDStack.peek ()).clone ()) ;
+      structEntry = makeStructEntry( name, entry, false ) ;
       ((IDLID)repIDStack.peek ()).appendToName (name);
-      structEntry = makeStructEntry( name, entry, false ) ;
       prep.openScope (structEntry);
       match (Token.LeftBrace) ;
       member (structEntry) ;
@@ -2174,8 +2174,8 @@
 
     if (token.type == Token.Switch) {
       repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
+      unionEntry = makeUnionEntry( name, entry, false ) ;
       ((IDLID)repIDStack.peek ()).appendToName (name);
-      unionEntry = makeUnionEntry( name, entry, false ) ;
       match (Token.Switch);
       match (Token.LeftParen);
       unionEntry.type (switchTypeSpec (unionEntry));
@@ -2641,8 +2641,8 @@
   private void exceptDcl (SymtabEntry entry) throws IOException, ParseException
   {
     match (Token.Exception);
+    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
     ExceptionEntry exceptEntry = stFactory.exceptionEntry (entry, (IDLID)repIDStack.peek ());
-    repIDStack.push (((IDLID)repIDStack.peek ()).clone ());
     ((IDLID)repIDStack.peek ()).appendToName (token.name);
     exceptEntry.sourceFile (scanner.fileEntry ());
     // Comment must immediately precede "exception" keyword
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java	Mon Apr 20 00:12:19 2009 -0700
@@ -91,4 +91,3 @@
   }
 
 }
-
--- a/corba/src/share/classes/org/omg/CORBA/ORB.java	Wed Jul 05 16:51:35 2017 +0200
+++ b/corba/src/share/classes/org/omg/CORBA/ORB.java	Mon Apr 20 00:12:19 2009 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2006 Sun Microsystems, Inc.  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
@@ -289,7 +289,7 @@
      *
      * @return the singleton ORB
      */
-    public static ORB init() {
+    public static synchronized ORB init() {
         if (singleton == null) {
             String className = getSystemProperty(ORBSingletonClassKey);
             if (className == null)