corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
changeset 2664 a0a22a8f16bd
parent 4 02bb8761fcce
child 3291 805a72a26925
equal deleted inserted replaced
2553:a8134c4ee2cf 2664:a0a22a8f16bd
     1 /*
     1 /*
     2  * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
   183     private Vector            dynamicRequests ;
   183     private Vector            dynamicRequests ;
   184     private SynchVariable     svResponseReceived ;
   184     private SynchVariable     svResponseReceived ;
   185 
   185 
   186     private java.lang.Object runObj = new java.lang.Object();
   186     private java.lang.Object runObj = new java.lang.Object();
   187     private java.lang.Object shutdownObj = new java.lang.Object();
   187     private java.lang.Object shutdownObj = new java.lang.Object();
   188     private java.lang.Object waitForCompletionObj = new java.lang.Object();
       
   189     private static final byte STATUS_OPERATING = 1;
   188     private static final byte STATUS_OPERATING = 1;
   190     private static final byte STATUS_SHUTTING_DOWN = 2;
   189     private static final byte STATUS_SHUTTING_DOWN = 2;
   191     private static final byte STATUS_SHUTDOWN = 3;
   190     private static final byte STATUS_SHUTDOWN = 3;
   192     private static final byte STATUS_DESTROYED = 4;
   191     private static final byte STATUS_DESTROYED = 4;
   193     private byte status = STATUS_OPERATING;
   192     private byte status = STATUS_OPERATING;
   194 
   193 
   195     // XXX Should we move invocation tracking to the first level server dispatcher?
   194     // XXX Should we move invocation tracking to the first level server dispatcher?
   196     private java.lang.Object invocationObj = new java.lang.Object();
   195     private java.lang.Object invocationObj = new java.lang.Object();
   197     private int numInvocations = 0;
       
   198 
   196 
   199     // thread local variable to store a boolean to detect deadlock in
   197     // thread local variable to store a boolean to detect deadlock in
   200     // ORB.shutdown(true).
   198     // ORB.shutdown(true).
   201     private ThreadLocal isProcessingInvocation = new ThreadLocal () {
   199     private ThreadLocal isProcessingInvocation = new ThreadLocal () {
   202         protected java.lang.Object initialValue() {
   200         protected java.lang.Object initialValue() {
  1243         }
  1241         }
  1244     }
  1242     }
  1245 
  1243 
  1246     public void shutdown(boolean wait_for_completion)
  1244     public void shutdown(boolean wait_for_completion)
  1247     {
  1245     {
       
  1246         // to wait for completion, we would deadlock, so throw a standard
       
  1247         // OMG exception.
       
  1248         if (wait_for_completion && ((Boolean)isProcessingInvocation.get()).booleanValue()) {
       
  1249             throw omgWrapper.shutdownWaitForCompletionDeadlock() ;
       
  1250         }
       
  1251 
       
  1252         boolean doShutdown = false ;
       
  1253 
  1248         synchronized (this) {
  1254         synchronized (this) {
  1249             checkShutdownState();
  1255             checkShutdownState() ;
  1250         }
  1256 
  1251 
  1257             if (status == STATUS_SHUTTING_DOWN) {
  1252         // Avoid more than one thread performing shutdown at a time.
  1258                 if (!wait_for_completion)
       
  1259                 // If we are already shutting down and don't want
       
  1260                 // to wait, nothing to do: return.
       
  1261                 return ;
       
  1262             } else {
       
  1263                 // The ORB status was STATUS_OPERATING, so start the shutdown.
       
  1264                 status = STATUS_SHUTTING_DOWN ;
       
  1265                 doShutdown = true ;
       
  1266             }
       
  1267         }
       
  1268 
       
  1269         // At this point, status is SHUTTING_DOWN.
       
  1270         // All shutdown calls with wait_for_completion == true must synchronize
       
  1271         // here.  Only the first call will be made with doShutdown == true.
  1253         synchronized (shutdownObj) {
  1272         synchronized (shutdownObj) {
  1254             checkShutdownState();
  1273             if (doShutdown) {
  1255             // This is to avoid deadlock
  1274                 // shutdownServants will set all POAManagers into the
  1256             if (wait_for_completion &&
  1275                 // INACTIVE state, causing request to be rejected.
  1257                 isProcessingInvocation.get() == Boolean.TRUE) {
  1276                 // If wait_for_completion is true, this will not return until
  1258                 throw omgWrapper.shutdownWaitForCompletionDeadlock() ;
  1277                 // all invocations have completed.
  1259             }
  1278                 shutdownServants(wait_for_completion);
  1260 
  1279 
  1261             status = STATUS_SHUTTING_DOWN;
  1280                 synchronized (runObj) {
  1262             // XXX access to requestDispatcherRegistry should be protected
  1281                     runObj.notifyAll();
  1263             // by the ORBImpl instance monitor, but is not here in the
  1282                 }
  1264             // shutdownServants call.
  1283 
  1265             shutdownServants(wait_for_completion);
  1284                 synchronized (this) {
  1266             if (wait_for_completion) {
  1285                     status = STATUS_SHUTDOWN;
  1267                 synchronized ( waitForCompletionObj ) {
       
  1268                     while (numInvocations > 0) {
       
  1269                         try {
       
  1270                             waitForCompletionObj.wait();
       
  1271                         } catch (InterruptedException ex) {}
       
  1272                     }
       
  1273                 }
  1286                 }
  1274             }
  1287             }
  1275             synchronized ( runObj ) {
       
  1276                 runObj.notifyAll();
       
  1277             }
       
  1278             status = STATUS_SHUTDOWN;
       
  1279         }
  1288         }
  1280     }
  1289     }
  1281 
  1290 
  1282     /** This method shuts down the ORB and causes orb.run() to return.
  1291     /** This method shuts down the ORB and causes orb.run() to return.
  1283      *  It will cause all POAManagers to be deactivated, which in turn
  1292      *  It will cause all POAManagers to be deactivated, which in turn
  1312 
  1321 
  1313     public void startingDispatch()
  1322     public void startingDispatch()
  1314     {
  1323     {
  1315         synchronized (invocationObj) {
  1324         synchronized (invocationObj) {
  1316             isProcessingInvocation.set(Boolean.TRUE);
  1325             isProcessingInvocation.set(Boolean.TRUE);
  1317             numInvocations++;
       
  1318         }
  1326         }
  1319     }
  1327     }
  1320 
  1328 
  1321     public void finishedDispatch()
  1329     public void finishedDispatch()
  1322     {
  1330     {
  1323         synchronized (invocationObj) {
  1331         synchronized (invocationObj) {
  1324             numInvocations--;
       
  1325             isProcessingInvocation.set(Boolean.FALSE);
  1332             isProcessingInvocation.set(Boolean.FALSE);
  1326             if (numInvocations == 0) {
       
  1327                 synchronized (waitForCompletionObj) {
       
  1328                     waitForCompletionObj.notifyAll();
       
  1329                 }
       
  1330             } else if (numInvocations < 0) {
       
  1331                 throw wrapper.numInvocationsAlreadyZero(
       
  1332                     CompletionStatus.COMPLETED_YES ) ;
       
  1333             }
       
  1334         }
  1333         }
  1335     }
  1334     }
  1336 
  1335 
  1337     /**
  1336     /**
  1338      *  formal/99-10-07 p 159: "If destroy is called on an ORB that has
  1337      *  formal/99-10-07 p 159: "If destroy is called on an ORB that has
  1339      *  not been shut down, it will start the shutdown process and block until
  1338      *  not been shut down, it will start the shutdown process and block until
  1340      *  the ORB has shut down before it destroys the ORB."
  1339      *  the ORB has shut down before it destroys the ORB."
  1341      */
  1340      */
  1342     public synchronized void destroy()
  1341     public synchronized void destroy()
  1343     {
  1342     {
  1344         if (status == STATUS_OPERATING) {
  1343         boolean shutdownFirst = false ;
       
  1344 
       
  1345         synchronized (this) {
       
  1346             shutdownFirst = (status == STATUS_OPERATING) ;
       
  1347         }
       
  1348 
       
  1349         if (shutdownFirst) {
  1345             shutdown(true);
  1350             shutdown(true);
  1346         }
  1351         }
  1347         getCorbaTransportManager().close();
  1352 
  1348         getPIHandler().destroyInterceptors() ;
  1353         synchronized (this) {
  1349         status = STATUS_DESTROYED;
  1354             if (status < STATUS_DESTROYED) {
       
  1355                 getCorbaTransportManager().close();
       
  1356                 getPIHandler().destroyInterceptors() ;
       
  1357                 status = STATUS_DESTROYED;
       
  1358             }
       
  1359         }
       
  1360 
  1350     }
  1361     }
  1351 
  1362 
  1352     /**
  1363     /**
  1353      * Registers a value factory for a particular repository ID.
  1364      * Registers a value factory for a particular repository ID.
  1354      *
  1365      *