KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > transport > CorbaResponseWaitingRoomImpl


1 /*
2  * @(#)CorbaResponseWaitingRoomImpl.java 1.29 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.transport;
9
10 import java.util.Hashtable JavaDoc;
11
12 import org.omg.CORBA.CompletionStatus JavaDoc;
13 import org.omg.CORBA.SystemException JavaDoc;
14
15 import com.sun.corba.se.pept.encoding.InputObject;
16 import com.sun.corba.se.pept.encoding.OutputObject;
17 import com.sun.corba.se.pept.protocol.MessageMediator;
18
19 import com.sun.corba.se.spi.logging.CORBALogDomains;
20 import com.sun.corba.se.spi.orb.ORB;
21 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
22 import com.sun.corba.se.spi.transport.CorbaConnection;
23 import com.sun.corba.se.spi.transport.CorbaResponseWaitingRoom;
24
25 import com.sun.corba.se.impl.encoding.BufferManagerReadStream;
26 import com.sun.corba.se.impl.encoding.CDRInputObject;
27 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
28 import com.sun.corba.se.impl.orbutil.ORBUtility;
29 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyOrReplyMessage;
30 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
31
32 /**
33  * @author Harold Carr
34  */

35 public class CorbaResponseWaitingRoomImpl
36     implements
37     CorbaResponseWaitingRoom
38 {
39     final static class OutCallDesc
40     {
41         java.lang.Object JavaDoc done = new java.lang.Object JavaDoc();
42         Thread JavaDoc thread;
43     MessageMediator messageMediator;
44         SystemException JavaDoc exception;
45         InputObject inputObject;
46     }
47
48     private ORB orb;
49     private ORBUtilSystemException wrapper ;
50
51     private CorbaConnection connection;
52     // Maps requestId to an OutCallDesc.
53
private Hashtable JavaDoc out_calls = null; // REVISIT - use int hastable/map
54

55     public CorbaResponseWaitingRoomImpl(ORB orb, CorbaConnection connection)
56     {
57     this.orb = orb;
58     wrapper = ORBUtilSystemException.get( orb,
59         CORBALogDomains.RPC_TRANSPORT ) ;
60     this.connection = connection;
61         out_calls = new Hashtable JavaDoc();
62     }
63
64     ////////////////////////////////////////////////////
65
//
66
// pept.transport.ResponseWaitingRoom
67
//
68

69     public void registerWaiter(MessageMediator mediator)
70     {
71     CorbaMessageMediator messageMediator = (CorbaMessageMediator) mediator;
72
73     if (orb.transportDebugFlag) {
74         dprint(".registerWaiter: " + opAndId(messageMediator));
75     }
76
77     Integer JavaDoc requestId = messageMediator.getRequestIdInteger();
78         
79     OutCallDesc call = new OutCallDesc();
80     call.thread = Thread.currentThread();
81     call.messageMediator = messageMediator;
82     out_calls.put(requestId, call);
83     }
84
85     public void unregisterWaiter(MessageMediator mediator)
86     {
87     CorbaMessageMediator messageMediator = (CorbaMessageMediator) mediator;
88
89     if (orb.transportDebugFlag) {
90         dprint(".unregisterWaiter: " + opAndId(messageMediator));
91     }
92
93     Integer JavaDoc requestId = messageMediator.getRequestIdInteger();
94
95         out_calls.remove(requestId);
96     }
97
98     public InputObject waitForResponse(MessageMediator mediator)
99     {
100       CorbaMessageMediator messageMediator = (CorbaMessageMediator) mediator;
101
102       try {
103
104         InputObject returnStream = null;
105
106     if (orb.transportDebugFlag) {
107         dprint(".waitForResponse->: " + opAndId(messageMediator));
108     }
109
110     Integer JavaDoc requestId = messageMediator.getRequestIdInteger();
111
112         if (messageMediator.isOneWay()) {
113             // The waiter is removed in releaseReply in the same
114
// way as a normal request.
115

116         if (orb.transportDebugFlag) {
117         dprint(".waitForResponse: one way - not waiting: "
118                + opAndId(messageMediator));
119         }
120
121             return null;
122         }
123
124         OutCallDesc call = (OutCallDesc)out_calls.get(requestId);
125         if (call == null) {
126         throw wrapper.nullOutCall(CompletionStatus.COMPLETED_MAYBE);
127     }
128
129         synchronized(call.done) {
130
131             while (call.inputObject == null && call.exception == null) {
132                 // Wait for the reply from the server.
133
// The ReaderThread reads in the reply IIOP message
134
// and signals us.
135
try {
136             if (orb.transportDebugFlag) {
137             dprint(".waitForResponse: waiting: "
138                    + opAndId(messageMediator));
139             }
140                     call.done.wait();
141                 } catch (InterruptedException JavaDoc ie) {};
142             }
143
144             if (call.exception != null) {
145         if (orb.transportDebugFlag) {
146             dprint(".waitForResponse: exception: "
147                + opAndId(messageMediator));
148         }
149                 throw call.exception;
150             }
151
152             returnStream = call.inputObject;
153         }
154
155     // REVISIT -- exceptions from unmarshaling code will
156
// go up through this client thread!
157

158         if (returnStream != null) {
159         // On fragmented streams the header MUST be unmarshaled here
160
// (in the client thread) in case it blocks.
161
// If the header was already unmarshaled, this won't
162
// do anything
163
// REVISIT: cast - need interface method.
164
((CDRInputObject)returnStream).unmarshalHeader();
165     }
166
167         return returnStream;
168
169       } finally {
170     if (orb.transportDebugFlag) {
171         dprint(".waitForResponse<-: " + opAndId(messageMediator));
172     }
173       }
174     }
175
176     public void responseReceived(InputObject is)
177     {
178     CDRInputObject inputObject = (CDRInputObject) is;
179     LocateReplyOrReplyMessage header = (LocateReplyOrReplyMessage)
180         inputObject.getMessageHeader();
181         Integer JavaDoc requestId = new Integer JavaDoc(header.getRequestId());
182         OutCallDesc call = (OutCallDesc) out_calls.get(requestId);
183
184     if (orb.transportDebugFlag) {
185         dprint(".responseReceived: id/"
186            + requestId + ": "
187            + header);
188     }
189
190         // This is an interesting case. It could mean that someone sent us a
191
// reply message, but we don't know what request it was for. That
192
// would probably call for an error. However, there's another case
193
// that's normal and we should think about --
194
//
195
// If the unmarshaling thread does all of its work inbetween the time
196
// the ReaderThread gives it the last fragment and gets to the
197
// out_calls.get line, then it will also be null, so just return;
198
if (call == null) {
199         if (orb.transportDebugFlag) {
200         dprint(".responseReceived: id/"
201                + requestId
202                + ": no waiter: "
203                + header);
204         }
205             return;
206     }
207
208         // Set the reply InputObject and signal the client thread
209
// that the reply has been received.
210
// The thread signalled will remove outcall descriptor if appropriate.
211
// Otherwise, it'll be removed when last fragment for it has been put on
212
// BufferManagerRead's queue.
213
synchronized (call.done) {
214         CorbaMessageMediator messageMediator = (CorbaMessageMediator)
215         call.messageMediator;
216
217         if (orb.transportDebugFlag) {
218         dprint(".responseReceived: "
219                + opAndId(messageMediator)
220                + ": notifying waiters");
221         }
222
223         messageMediator.setReplyHeader(header);
224         messageMediator.setInputObject(is);
225         inputObject.setMessageMediator(messageMediator);
226             call.inputObject = is;
227             call.done.notify();
228         }
229     }
230
231     public int numberRegistered()
232     {
233         // Note: Hashtable.size() is not synchronized
234
return out_calls.size();
235     }
236
237     //////////////////////////////////////////////////
238
//
239
// CorbaResponseWaitingRoom
240
//
241

242     public void signalExceptionToAllWaiters(SystemException JavaDoc systemException)
243     {
244
245     if (orb.transportDebugFlag) {
246         dprint(".signalExceptionToAllWaiters: " + systemException);
247     }
248
249         OutCallDesc call;
250         java.util.Enumeration JavaDoc e = out_calls.elements();
251         while(e.hasMoreElements()) {
252             call = (OutCallDesc) e.nextElement();
253         
254             synchronized(call.done){
255                 // anything waiting for BufferManagerRead's fragment queue
256
// needs to be cancelled
257
CorbaMessageMediator corbaMsgMediator =
258                              (CorbaMessageMediator)call.messageMediator;
259                 CDRInputObject inputObject =
260                            (CDRInputObject)corbaMsgMediator.getInputObject();
261                 // IMPORTANT: If inputObject is null, then no need to tell
262
// BufferManagerRead to cancel request processing.
263
if (inputObject != null) {
264                     BufferManagerReadStream bufferManager =
265                         (BufferManagerReadStream)inputObject.getBufferManager();
266                     int requestId = corbaMsgMediator.getRequestId();
267                     bufferManager.cancelProcessing(requestId);
268                 }
269                 call.inputObject = null;
270                 call.exception = systemException;
271                 call.done.notify();
272             }
273         }
274     }
275
276     public MessageMediator getMessageMediator(int requestId)
277     {
278         Integer JavaDoc id = new Integer JavaDoc(requestId);
279         OutCallDesc call = (OutCallDesc) out_calls.get(id);
280     if (call == null) {
281         // This can happen when getting early reply fragments for a
282
// request which has completed (e.g., client marshaling error).
283
return null;
284     }
285     return call.messageMediator;
286     }
287
288     ////////////////////////////////////////////////////
289
//
290
// Implementation.
291
//
292

293     protected void dprint(String JavaDoc msg)
294     {
295     ORBUtility.dprint("CorbaResponseWaitingRoomImpl", msg);
296     }
297
298     protected String JavaDoc opAndId(CorbaMessageMediator mediator)
299     {
300     return ORBUtility.operationNameAndRequestId(mediator);
301     }
302 }
303
304 // End of file.
305
Popular Tags