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 + -
显示快捷键?