KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > oa > poa > POAPolicyMediatorImpl_R_USM


1 /*
2  * @(#)POAPolicyMediatorImpl_R_USM.java 1.39 04/03/01
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.oa.poa ;
9
10 import java.util.Set JavaDoc ;
11
12 import org.omg.CORBA.SystemException JavaDoc ;
13
14 import org.omg.PortableServer.ServantActivator JavaDoc ;
15 import org.omg.PortableServer.Servant JavaDoc ;
16 import org.omg.PortableServer.ServantManager JavaDoc ;
17 import org.omg.PortableServer.ForwardRequest JavaDoc ;
18 import org.omg.PortableServer.POAPackage.WrongPolicy JavaDoc ;
19 import org.omg.PortableServer.POAPackage.ObjectNotActive JavaDoc ;
20 import org.omg.PortableServer.POAPackage.ServantNotActive JavaDoc ;
21 import org.omg.PortableServer.POAPackage.ObjectAlreadyActive JavaDoc ;
22 import org.omg.PortableServer.POAPackage.ServantAlreadyActive JavaDoc ;
23 import org.omg.PortableServer.POAPackage.NoServant JavaDoc ;
24
25 import com.sun.corba.se.impl.orbutil.concurrent.SyncUtil ;
26 import com.sun.corba.se.impl.orbutil.ORBUtility ;
27 import com.sun.corba.se.impl.orbutil.ORBConstants ;
28
29 import com.sun.corba.se.impl.oa.NullServantImpl ;
30
31 import com.sun.corba.se.impl.javax.rmi.CORBA.Util ;
32
33 import com.sun.corba.se.spi.oa.OAInvocationInfo ;
34 import com.sun.corba.se.spi.oa.NullServant ;
35
36 /** Implementation of POARequesHandler that provides policy specific
37  * operations on the POA.
38  */

39 public class POAPolicyMediatorImpl_R_USM extends POAPolicyMediatorBase_R {
40     protected ServantActivator JavaDoc activator ;
41
42     POAPolicyMediatorImpl_R_USM( Policies policies, POAImpl poa )
43     {
44     // assert policies.retainServants()
45
super( policies, poa ) ;
46     activator = null ;
47
48     if (!policies.useServantManager())
49         throw poa.invocationWrapper().policyMediatorBadPolicyInFactory() ;
50     }
51    
52     /* This handles a rather subtle bug (4939892). The problem is that
53      * enter will wait on the entry if it is being etherealized. When the
54      * deferred state transition completes, the entry is no longer in the
55      * AOM, and so we need to get a new entry, otherwise activator.incarnate
56      * will be called twice, once for the old entry, and again when a new
57      * entry is created. This fix also required extending the FSM StateEngine
58      * to allow actions to throw exceptions, and adding a new state in the
59      * AOMEntry FSM to detect this condition.
60      */

61     private AOMEntry enterEntry( ActiveObjectMap.Key key )
62     {
63     AOMEntry result = null ;
64     boolean failed ;
65     do {
66         failed = false ;
67         result = activeObjectMap.get(key) ;
68
69         try {
70         result.enter() ;
71         } catch (Exception JavaDoc exc) {
72         failed = true ;
73         }
74     } while (failed) ;
75
76     return result ;
77     }
78
79     protected java.lang.Object JavaDoc internalGetServant( byte[] id,
80     String JavaDoc operation ) throws ForwardRequest JavaDoc
81     {
82     if (poa.getDebug()) {
83         ORBUtility.dprint( this,
84         "Calling POAPolicyMediatorImpl_R_USM.internalGetServant " +
85         "for poa " + poa + " operation=" + operation ) ;
86     }
87
88     try {
89         ActiveObjectMap.Key key = new ActiveObjectMap.Key( id ) ;
90         AOMEntry entry = enterEntry(key) ;
91         java.lang.Object JavaDoc servant = activeObjectMap.getServant( entry ) ;
92         if (servant != null) {
93         if (poa.getDebug()) {
94             ORBUtility.dprint( this,
95             "internalGetServant: servant already activated" ) ;
96         }
97
98         return servant ;
99         }
100
101         if (activator == null) {
102         if (poa.getDebug()) {
103             ORBUtility.dprint( this,
104             "internalGetServant: no servant activator in POA" ) ;
105         }
106
107         entry.incarnateFailure() ;
108         throw poa.invocationWrapper().poaNoServantManager() ;
109         }
110        
111         // Drop the POA lock during the incarnate call and
112
// re-acquire it afterwards. The entry state machine
113
// prevents more than one thread from executing the
114
// incarnate method at a time within the same POA.
115
try {
116         if (poa.getDebug()) {
117             ORBUtility.dprint( this,
118             "internalGetServant: upcall to incarnate" ) ;
119         }
120
121         poa.unlock() ;
122
123         servant = activator.incarnate(id, poa);
124
125         if (servant == null)
126             servant = new NullServantImpl(
127             poa.omgInvocationWrapper().nullServantReturned() ) ;
128         } catch (ForwardRequest JavaDoc freq) {
129         if (poa.getDebug()) {
130             ORBUtility.dprint( this,
131             "internalGetServant: incarnate threw ForwardRequest" ) ;
132         }
133
134         throw freq ;
135         } catch (SystemException JavaDoc exc) {
136         if (poa.getDebug()) {
137             ORBUtility.dprint( this,
138             "internalGetServant: incarnate threw SystemException " + exc ) ;
139         }
140
141         throw exc ;
142         } catch (Throwable JavaDoc exc) {
143         if (poa.getDebug()) {
144             ORBUtility.dprint( this,
145             "internalGetServant: incarnate threw Throwable " + exc ) ;
146         }
147
148         throw poa.invocationWrapper().poaServantActivatorLookupFailed(
149             exc ) ;
150         } finally {
151         poa.lock() ;
152
153         // servant == null means incarnate threw an exception,
154
// while servant instanceof NullServant means incarnate returned a
155
// null servant. Either case is an incarnate failure to the
156
// entry state machine.
157
if ((servant == null) || (servant instanceof NullServant)) {
158             if (poa.getDebug()) {
159             ORBUtility.dprint( this,
160                 "internalGetServant: incarnate failed" ) ;
161             }
162
163             // XXX Does the AOM leak in this case? Yes,
164
// but the problem is hard to fix. There may be
165
// a number of threads waiting for the state to change
166
// from INCARN to something else, which is VALID or
167
// INVALID, depending on the incarnate result.
168
// The activeObjectMap.get() call above creates an
169
// ActiveObjectMap.Entry if one does not already exist,
170
// and stores it in the keyToEntry map in the AOM.
171
entry.incarnateFailure() ;
172         } else {
173             // here check for unique_id policy, and if the servant
174
// is already registered for a different ID, then throw
175
// OBJ_ADAPTER exception, else activate it. Section 11.3.5.1
176
// 99-10-07.pdf
177
if (isUnique) {
178             // check if the servant already is associated with some id
179
if (activeObjectMap.contains((Servant JavaDoc)servant)) {
180                 if (poa.getDebug()) {
181                 ORBUtility.dprint( this,
182                     "internalGetServant: servant already assigned to ID" ) ;
183                 }
184
185                 entry.incarnateFailure() ;
186                 throw poa.invocationWrapper().poaServantNotUnique() ;
187             }
188             }
189
190             if (poa.getDebug()) {
191             ORBUtility.dprint( this,
192                 "internalGetServant: incarnate complete" ) ;
193             }
194
195             entry.incarnateComplete() ;
196             activateServant(key, entry, (Servant JavaDoc)servant);
197         }
198         }
199
200         return servant ;
201     } finally {
202         if (poa.getDebug()) {
203         ORBUtility.dprint( this,
204             "Exiting POAPolicyMediatorImpl_R_USM.internalGetServant " +
205             "for poa " + poa ) ;
206         }
207     }
208     }
209
210     public void returnServant()
211     {
212     OAInvocationInfo info = orb.peekInvocationInfo();
213     byte[] id = info.id() ;
214     ActiveObjectMap.Key key = new ActiveObjectMap.Key( id ) ;
215     AOMEntry entry = activeObjectMap.get( key ) ;
216     entry.exit() ;
217     }
218
219     public void etherealizeAll()
220     {
221     if (activator != null) {
222         Set JavaDoc keySet = activeObjectMap.keySet() ;
223
224         // Copy the elements in the set to an array to avoid
225
// changes in the set due to concurrent modification
226
ActiveObjectMap.Key[] keys =
227         (ActiveObjectMap.Key[])keySet.toArray(
228             new ActiveObjectMap.Key[ keySet.size() ] ) ;
229
230         for (int ctr=0; ctr<keySet.size(); ctr++) {
231         ActiveObjectMap.Key key = keys[ctr] ;
232         AOMEntry entry = activeObjectMap.get( key ) ;
233         Servant JavaDoc servant = activeObjectMap.getServant( entry ) ;
234         if (servant != null) {
235             boolean remainingActivations =
236             activeObjectMap.hasMultipleIDs(entry) ;
237
238             // Here we etherealize in the thread that called this
239
// method, rather than etherealizing in a new thread
240
// as in the deactivate case. We still inform the
241
// entry state machine so that only one thread at a
242
// time can call the etherealize method.
243
entry.startEtherealize( null ) ;
244             try {
245             poa.unlock() ;
246             try {
247                 activator.etherealize(key.id, poa, servant, true,
248                 remainingActivations);
249             } catch (Exception JavaDoc exc) {
250                 // ignore all exceptions
251
}
252             } finally {
253             poa.lock() ;
254             entry.etherealizeComplete() ;
255             }
256         }
257         }
258     }
259     }
260
261     public ServantManager JavaDoc getServantManager() throws WrongPolicy JavaDoc
262     {
263     return activator;
264     }
265
266     public void setServantManager(
267     ServantManager JavaDoc servantManager ) throws WrongPolicy JavaDoc
268     {
269     if (activator != null)
270         throw poa.invocationWrapper().servantManagerAlreadySet() ;
271
272     if (servantManager instanceof ServantActivator JavaDoc)
273         activator = (ServantActivator JavaDoc)servantManager;
274     else
275         throw poa.invocationWrapper().servantManagerBadType() ;
276     }
277
278     public Servant JavaDoc getDefaultServant() throws NoServant JavaDoc, WrongPolicy JavaDoc
279     {
280     throw new WrongPolicy JavaDoc();
281     }
282
283     public void setDefaultServant( Servant JavaDoc servant ) throws WrongPolicy JavaDoc
284     {
285     throw new WrongPolicy JavaDoc();
286     }
287
288     class Etherealizer extends Thread JavaDoc {
289     private POAPolicyMediatorImpl_R_USM mediator ;
290     private ActiveObjectMap.Key key ;
291     private AOMEntry entry ;
292     private Servant JavaDoc servant ;
293     private boolean debug ;
294
295     public Etherealizer( POAPolicyMediatorImpl_R_USM mediator,
296         ActiveObjectMap.Key key, AOMEntry entry, Servant JavaDoc servant,
297         boolean debug )
298     {
299         this.mediator = mediator ;
300         this.key = key ;
301         this.entry = entry;
302         this.servant = servant;
303         this.debug = debug ;
304     }
305
306     public void run() {
307         if (debug) {
308         ORBUtility.dprint( this, "Calling Etherealizer.run on key " +
309             key ) ;
310         }
311
312         try {
313         try {
314             mediator.activator.etherealize( key.id, mediator.poa, servant,
315             false, mediator.activeObjectMap.hasMultipleIDs( entry ) );
316         } catch (Exception JavaDoc exc) {
317             // ignore all exceptions
318
}
319
320         try {
321             mediator.poa.lock() ;
322
323             entry.etherealizeComplete() ;
324             mediator.activeObjectMap.remove( key ) ;
325
326             POAManagerImpl pm = (POAManagerImpl)mediator.poa.the_POAManager() ;
327             POAFactory factory = pm.getFactory() ;
328             factory.unregisterPOAForServant( mediator.poa, servant);
329         } finally {
330             mediator.poa.unlock() ;
331         }
332         } finally {
333         if (debug) {
334             ORBUtility.dprint( this, "Exiting Etherealizer.run" ) ;
335         }
336         }
337     }
338     }
339
340     public void deactivateHelper( ActiveObjectMap.Key key, AOMEntry entry,
341     Servant JavaDoc servant ) throws ObjectNotActive JavaDoc, WrongPolicy JavaDoc
342     {
343     if (activator == null)
344         throw poa.invocationWrapper().poaNoServantManager() ;
345         
346     Etherealizer eth = new Etherealizer( this, key, entry, servant, poa.getDebug() ) ;
347     entry.startEtherealize( eth ) ;
348     }
349
350     public Servant JavaDoc idToServant( byte[] id )
351     throws WrongPolicy JavaDoc, ObjectNotActive JavaDoc
352     {
353     ActiveObjectMap.Key key = new ActiveObjectMap.Key( id ) ;
354     AOMEntry entry = activeObjectMap.get(key);
355
356     Servant JavaDoc servant = activeObjectMap.getServant( entry ) ;
357     if (servant != null)
358         return servant ;
359     else
360         throw new ObjectNotActive JavaDoc() ;
361     }
362 }
363
Popular Tags