corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
changeset 2664 a0a22a8f16bd
parent 4 02bb8761fcce
child 3291 805a72a26925
--- 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;
+            }
+        }
+
     }
 
     /**