1 /* gnuPOAManager.java -- 2 Copyright (C) 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.CORBA.Poa; 40 41 import org.omg.CORBA.BAD_INV_ORDER; 42 import org.omg.CORBA.LocalObject; 43 import org.omg.PortableInterceptor.NON_EXISTENT; 44 import org.omg.PortableServer.POAManager; 45 import org.omg.PortableServer.POAManagerPackage.AdapterInactive; 46 import org.omg.PortableServer.POAManagerPackage.State; 47 48 import java.util.HashSet; 49 import java.util.Iterator; 50 51 /** 52 * The implementation of the POA manager. The manager is a controlled 53 * switch that can change its states in response to the method calls 54 * and throw exceptions if the requested change is invalid. It is possible 55 * to check the state this switch. It does not do anything else. 56 * 57 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 58 */ 59 public class gnuPOAManager 60 extends LocalObject 61 implements POAManager 62 { 63 /** 64 * Use serialVersionUID for interoperability. 65 */ 66 private static final long serialVersionUID = 1; 67 68 /** 69 * The POAs, controlled by this manager. 70 */ 71 private HashSet POAs = new HashSet(); 72 73 /** 74 * The state of the manager. The newly created manager is always 75 * in the holding state. 76 */ 77 State state = State.HOLDING; 78 79 /** 80 * Get the state of the POA manager. 81 */ get_state()82 public State get_state() 83 { 84 return state; 85 } 86 87 /** 88 * Turns the associated POAs into active state, allowing them to receive 89 * and process requests. 90 * 91 * @throws AdapterInactive if the POAs are in the inactive state. 92 * If once inactivated, the POA cannot be activated again. This 93 * method can only be called to leave the holding or discarding state. 94 */ activate()95 public void activate() 96 throws AdapterInactive 97 { 98 if (state != State.INACTIVE) 99 state = State.ACTIVE; 100 else 101 throw new AdapterInactive(); 102 103 notifyInterceptors(state.value()); 104 } 105 106 /** 107 * Turns the associated POAs into holding state. In this state, the POAs 108 * queue incoming requests but do not process them. 109 * 110 * @param wait_for_completion if true, the method call suspends the current 111 * thread till POAs complete the requests they are currently processing. If 112 * false, the method returns immediately. 113 114 * @throws AdapterInactive if the POAs are in the inactive state. 115 */ hold_requests(boolean wait_for_completion)116 public void hold_requests(boolean wait_for_completion) 117 throws AdapterInactive 118 { 119 if (state != State.INACTIVE) 120 state = State.HOLDING; 121 else 122 throw new AdapterInactive(); 123 124 notifyInterceptors(state.value()); 125 126 if (wait_for_completion) 127 waitForIdle(); 128 } 129 130 /** 131 * 132 * Turns the asociated POAs into inactive state. The POAs in the incative 133 * state will reject new requests. If the POA is once inactivated, it 134 * cannot be activated again. The operation is used when 135 * the associated POAs are to be shut down. 136 * 137 * @param etherealize_objects if true, the servant managers of the 138 * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies, 139 * will receive a call of {@link ServantActivatorOperations#etherealize}. 140 * 141 * @param wait_for_completion if true, the method call suspends the current 142 * thread till POAs complete the requests they are currently processing. If 143 * false, the method returns immediately. 144 * 145 * @throws AdapterInactive if the POAs are already in the inactive state. 146 * 147 * @see POAOperations#destroy 148 */ deactivate(boolean etherealize_objects, boolean wait_for_completion )149 public void deactivate(boolean etherealize_objects, 150 boolean wait_for_completion 151 ) 152 throws AdapterInactive 153 { 154 if (state == State.INACTIVE) 155 throw new AdapterInactive("Repetetive inactivation"); 156 state = State.INACTIVE; 157 158 notifyInterceptors(state.value()); 159 160 if (wait_for_completion) 161 waitForIdle(); 162 163 Iterator iter = POAs.iterator(); 164 while (iter.hasNext()) 165 { 166 gnuPOA poa = (gnuPOA) iter.next(); 167 168 // If the servant activator is non null, this means it has been 169 // set - hence the policies are appropriate. 170 if (poa.servant_activator != null) 171 poa.etherealizeAll(); 172 } 173 } 174 175 /** 176 * Turns the associated POAs into discaring state. In this state, the POAs 177 * discard the incoming requests. This mode is used in situations when 178 * the server is flooded with requests. The client receives remote exception 179 * ({@link org.omg.CORBA.TRANSIENT}, minor code 1). 180 * 181 * @param wait_for_completion if true, the method call suspends the current 182 * thread till POAs complete the requests they are currently processing. If 183 * false, the method returns immediately. 184 185 * @throws AdapterInactive if the POAs are in the inactive state. 186 */ discard_requests(boolean wait_for_completion)187 public void discard_requests(boolean wait_for_completion) 188 throws AdapterInactive 189 { 190 if (state != State.INACTIVE) 191 state = State.DISCARDING; 192 else 193 throw new AdapterInactive(); 194 195 notifyInterceptors(state.value()); 196 197 if (wait_for_completion) 198 waitForIdle(); 199 } 200 201 /** 202 * Suspend the current thread while at least one of the associated POA is 203 * actively processing some requests. The method assumes that the POAs 204 * are not accepting the <i>new</i> requests due manager state. 205 * 206 * @throws BAD_INV_ORDER if the POAs are in the active state. 207 */ waitForIdle()208 public void waitForIdle() 209 { 210 if (state == State.ACTIVE) 211 throw new BAD_INV_ORDER("The state is active"); 212 213 gnuPOA poa; 214 Iterator iter = POAs.iterator(); 215 216 while (iter.hasNext()) 217 { 218 poa = (gnuPOA) iter.next(); 219 poa.waitWhileRunning(); 220 } 221 } 222 223 /** 224 * Add the POA that will be controlled by this manager. 225 * 226 * @param poa the POA. 227 */ addPoa(gnuPOA poa)228 public void addPoa(gnuPOA poa) 229 { 230 POAs.add(poa); 231 } 232 233 /** 234 * Remove the POA, releasing it from the control of this manager. 235 * Called in POA finaliser. 236 * 237 * @param poa the POA to remove. 238 */ removePOA(gnuPOA poa)239 public void removePOA(gnuPOA poa) 240 { 241 POAs.remove(poa); 242 } 243 244 /** 245 * This method is called when POA is destryed. The interceptors are 246 * notified. 247 */ poaDestroyed(gnuPOA poa)248 public void poaDestroyed(gnuPOA poa) 249 { 250 notifyInterceptors(NON_EXISTENT.value); 251 } 252 253 /** 254 * Notify CORBA 3.0 interceptors about the status change. 255 */ notifyInterceptors(int new_state)256 public synchronized void notifyInterceptors(int new_state) 257 { 258 gnuPOA poa; 259 Iterator iter = POAs.iterator(); 260 261 // The System.identityHashCode is also called in gnuIorInfo. 262 while (iter.hasNext()) 263 { 264 poa = (gnuPOA) iter.next(); 265 if (poa.m_orb.iIor != null) 266 { 267 poa.m_orb.iIor.adapter_manager_state_changed( 268 System.identityHashCode(this), (short) new_state); 269 } 270 } 271 } 272 } 273