poamanagerimpl.java
来自「java jdk 1.4的源码」· Java 代码 · 共 285 行
JAVA
285 行
/* * @(#)POAManagerImpl.java 1.18 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.corba.se.internal.POA;import java.util.*;import org.omg.CORBA.TRANSIENT;import org.omg.CORBA.OBJ_ADAPTER;import org.omg.CORBA.CompletionStatus;import org.omg.CORBA.LocalObject;import org.omg.PortableServer.POAManager;import org.omg.PortableServer.POAManagerPackage.State;import org.omg.PortableServer.POA;/** POAManagerImpl is the implementation of the POAManager interface. * Its public methods are activate(), hold_requests(), discard_requests() * and deactivate(). * * A note on deadlocks: Since Java allows threads to acquire the same * monitor multiple times, there will not be a deadlock on circular calls * to synchronized methods (i.e. if a POAManager instance method calls an * object which calls another method on this same POAManager instance). * However, there is one "legal" deadlock which can occur: see the note * in the enter() method. */public class POAManagerImpl extends org.omg.CORBA.LocalObject implements POAManager{ // POAManager states private static final State HOLDING = State.HOLDING; private static final State ACTIVE = State.ACTIVE; private static final State DISCARDING = State.DISCARDING; private static final State INACTIVE = State.INACTIVE; POAORB orb; private State state; // current state of this private Set poas = Collections.synchronizedSet(new HashSet(4)); // all poas controlled by this // Number of invocations in progress int nInvocations=0; // Number of threads waiting for invocations to complete int nWaiters=0; private void countedWait() { try { nWaiters++ ; wait(); } catch ( java.lang.InterruptedException ex ) { // NOP } finally { nWaiters-- ; } } private void notifyWaiters() { if (nWaiters >0) notifyAll() ; } public POAManagerImpl(POAORB orb) { this.orb = orb; state = HOLDING; } synchronized void addPOA(POA poa) { poas.add(poa); orb.addPoaManager(this); } synchronized void removePOA(POA poa) { poas.remove(poa); if ( poas.isEmpty() ) { orb.removePoaManager(this); } }/**************************************************************************** * The following four public methods are used to change the POAManager's state. * * A note on the design of synchronization code: * There are 4 places where a thread would need to wait for a condition: * - in hold_requests, discard_requests, deactivate, enter * There are 5 places where a thread notifies a condition: * - in activate, hold_requests, discard_requests, deactivate, exit * Since each notify needs to awaken waiters in several of the 4 places, * and since wait() in Java has the nice property of releasing the lock * on its monitor before sleeping, it seemed simplest to have just one * monitor object: "this". Thus all notifies will awaken all waiters. * On waking up, each waiter verifies that the condition it was waiting * for is satisfied, otherwise it goes back into a wait(). * ****************************************************************************/ /** * <code>activate</code> * <b>Spec: pages 3-14 thru 3-18</b> */ public synchronized void activate() throws org.omg.PortableServer.POAManagerPackage.AdapterInactive { if ( state.value() == State._INACTIVE ) throw new org.omg.PortableServer.POAManagerPackage.AdapterInactive(); // set the state to ACTIVE state = ACTIVE; // Notify any invocations that were waiting because the previous // state was HOLDING, as well as notify any threads that were waiting // inside hold_requests() or discard_requests(). notifyWaiters(); } /** * <code>hold_requests</code> * <b>Spec: pages 3-14 thru 3-18</b> */ public synchronized void hold_requests(boolean wait_for_completion) throws org.omg.PortableServer.POAManagerPackage.AdapterInactive { if ( state.value() == State._INACTIVE ) throw new org.omg.PortableServer.POAManagerPackage.AdapterInactive(); // set the state to HOLDING state = HOLDING; // Notify any threads that were waiting in the wait() inside // discard_requests. This will cause discard_requests to return // (which is in conformance with the spec). notifyWaiters(); if ( wait_for_completion ) { while ( state.value() == State._HOLDING && nInvocations > 0 ) { countedWait() ; } } } /** * <code>discard_requests</code> * <b>Spec: pages 3-14 thru 3-18</b> */ public synchronized void discard_requests(boolean wait_for_completion) throws org.omg.PortableServer.POAManagerPackage.AdapterInactive { if ( state.value() == State._INACTIVE ) throw new org.omg.PortableServer.POAManagerPackage.AdapterInactive(); // set the state to DISCARDING state = DISCARDING; // Notify any invocations that were waiting because the previous // state was HOLDING. Those invocations will henceforth be rejected with // a TRANSIENT exception. Also notify any threads that were waiting // inside hold_requests(). notifyWaiters(); if ( wait_for_completion ) { while ( state.value() == State._DISCARDING && nInvocations > 0 ) { countedWait() ; } } } /** * <code>deactivate</code> * <b>Spec: pages 3-14 thru 3-18</b> * Note: INACTIVE is a permanent state. */ public synchronized void deactivate(boolean etherealize_objects, boolean wait_for_completion) throws org.omg.PortableServer.POAManagerPackage.AdapterInactive { if ( state.value() == State._INACTIVE ) throw new org.omg.PortableServer.POAManagerPackage.AdapterInactive(); state = INACTIVE; // Notify any invocations that were waiting because the previous // state was HOLDING. Those invocations will then be rejected with // an OBJ_ADAPTER exception. Also notify any threads that were waiting // inside hold_requests() or discard_requests(). notifyWaiters(); if ( wait_for_completion ) { while ( nInvocations > 0 ) { countedWait() ; } } if ( etherealize_objects ) { if ( wait_for_completion ) { // stefanb 12/00: Why was this condition reversed? Spawning new threads means NOT to wait! etherealizePOAs(); } else { new Thread() { public void run() { POAManagerImpl.this.etherealizePOAs(); } }.start(); } } else { orb.removePoaManager(this); // remove all POAs from poas, so that they can be GC'ed. poas.clear(); } } /** * Added according to the spec CORBA V2.3; this returns the * state of the POAManager */ public org.omg.PortableServer.POAManagerPackage.State get_state () { return state; } void etherealizePOAs() { Iterator iterator = (new HashSet(poas)).iterator(); while (iterator.hasNext()) { // if this is a RETAIN+USE_SERVANT_MGR poa // then it must call etherealize for all its objects ((POAImpl)iterator.next()).etherealizeAll(); } orb.removePoaManager(this); poas.clear(); }/**************************************************************************** * The following methods are used on the invocation path. ****************************************************************************/ // called from POA.find_POA before calling // AdapterActivator.unknown_adapter. synchronized void checkIfActive() { checkState(); } private void checkState() { while ( state.value() != State._ACTIVE ) { switch ( state.value() ) { case State._HOLDING: while ( state.value() == State._HOLDING ) { countedWait() ; } break; case State._DISCARDING: throw new TRANSIENT(MinorCodes.POA_DISCARDING, CompletionStatus.COMPLETED_NO); case State._INACTIVE: throw new OBJ_ADAPTER(MinorCodes.POA_INACTIVE, CompletionStatus.COMPLETED_NO); } } } synchronized void enter() { checkState(); nInvocations++; } synchronized void exit() { nInvocations--; if ( nInvocations == 0 ) { // This notifies any threads that were in the // wait_for_completion loop in hold/discard/deactivate(). notifyWaiters(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?