1 55 56 package org.apache.bsf.debug.util; 57 58 import java.util.*; 59 import org.apache.bsf.debug.*; 60 import java.net.*; 61 import java.io.*; 62 import java.rmi.RemoteException ; 63 import org.apache.bsf.debug.util.DebugConstants; 64 65 public class Stub implements RemoteService { 66 67 public static Stub UNDEFINED; 68 public static Stub NOT_FOUND; 69 70 public static void Init(SocketConnection con) { 71 UNDEFINED = 72 new Stub(con, DebugConstants.SPECIAL_TID, DebugConstants.UNDEFINED_UID); 73 NOT_FOUND = 74 new Stub(con, DebugConstants.SPECIAL_TID, DebugConstants.NOT_FOUND_UID); 75 } 76 77 protected int m_tid, m_uid; 78 protected boolean m_revoked; 79 protected SocketConnection m_con; 80 81 public Stub(SocketConnection con, int tid, int uid) { 82 m_con = con; 83 m_tid = tid; 84 m_uid = uid; 85 } 86 87 public boolean equals(Object o) { 88 if (o instanceof Stub) 89 return m_uid == ((Stub) o).m_uid; 90 return false; 91 } 92 93 public int getTid() { 94 return m_tid; 95 } 96 public int getUid() { 97 return m_uid; 98 } 99 100 public void revoked() { 101 Enumeration e; 102 RemoteServiceListener l; 103 104 DebugLog.stdoutPrintln("Revoking a stub " + this, DebugLog.BSF_LOG_L3); 105 m_revoked = true; 106 107 if (m_listeners == null) 108 return; 109 110 e = m_listeners.elements(); 111 while (e.hasMoreElements()) { 112 l = (RemoteServiceListener) e.nextElement(); 113 l.revokedNotify(this); 114 } 115 116 FutureCell cell = null; 117 Exception ex = new RemoteException ("Lost connection... stub revoked"); 118 119 DebugLog.stdoutPrintln(" revoking futures...", DebugLog.BSF_LOG_L3); 120 synchronized (m_futureLock) { 121 e = m_futureCells.elements(); 122 while (e.hasMoreElements()) { 123 cell = (FutureCell) e.nextElement(); 124 DebugLog.stdoutPrintln( 125 " revoking for requester " + cell.requester, 126 DebugLog.BSF_LOG_L3); 127 cell.resume = true; 128 cell.ex = ex; 129 m_futureLock.notifyAll(); 130 } 131 DebugLog.stdoutPrintln(" Done with futures.", DebugLog.BSF_LOG_L3); 132 m_futureCells = new Vector(); 133 } 134 } 135 136 public SocketConnection getConnection() { 137 return m_con; 138 } 139 140 public Stub swizzle(int tid, int uid) { 141 return m_con.swizzle(tid, uid); 142 } 143 144 private Vector m_listeners; 145 146 public void addListener(RemoteServiceListener l) { 147 if (m_listeners == null) 148 m_listeners = new Vector(); 149 m_listeners.addElement(l); 150 } 151 152 public void removeListener(RemoteServiceListener l) { 153 if (m_listeners != null) { 154 m_listeners.removeElement(l); 155 } 156 } 157 158 private static Object m_futureLock = new Object (); 159 private Vector m_futureCells = new Vector(); class FutureCell { 161 Object requester; 162 Thread thread; 163 boolean resume; 164 Exception ex; 165 } 166 167 public void createFuture(Object requester) throws RemoteException { 168 Enumeration e; 169 FutureCell cell; 170 171 DebugLog.stdoutPrintln( 172 "Creating future for requester " + requester + " on " + this, 173 DebugLog.BSF_LOG_L3); 174 try { 175 synchronized (m_futureLock) { 176 e = m_futureCells.elements(); 177 while (e.hasMoreElements()) { 178 cell = (FutureCell) e.nextElement(); 179 if (cell.requester == requester) 180 throw new Exception ("Can't create multiple future on same requester."); 181 } 182 cell = new FutureCell(); 183 cell.requester = requester; 184 cell.thread = Thread.currentThread(); 185 cell.resume = false; 186 m_futureCells.addElement(cell); 187 } 188 } catch (Exception ex) { 189 throw new RemoteException ("Error in future management", ex); 190 } 191 } 192 public void suspendFuture(Object requester) throws RemoteException { 193 194 Enumeration e; 195 FutureCell cell = null; 196 197 DebugLog.stdoutPrintln( 198 "Suspending on future for requester " + requester + " on " + this, 199 DebugLog.BSF_LOG_L3); 200 try { 201 synchronized (m_futureLock) { 202 cell = findFuture(requester); 203 DebugLog.stdoutPrintln( 204 "Suspending future for " 205 + cell.requester 206 + " on thread " 207 + cell.thread 208 + " on " 209 + this, 210 DebugLog.BSF_LOG_L3); 211 212 if (!cell.resume & !this.m_revoked) { 213 while (true) { 218 try { 219 m_futureLock.wait(1000); 220 if (cell.resume) 221 break; 222 if (this.m_revoked) 223 break; 224 } catch (InterruptedException ex) { 225 } 226 } 227 } 228 m_futureCells.removeElement(cell); 230 if (cell.ex != null) { 232 DebugLog.stdoutPrintln( 233 "Future for " 234 + cell.requester 235 + " on thread " 236 + cell.thread 237 + " throwing Exception " 238 + cell.ex, 239 DebugLog.BSF_LOG_L3); 240 throw cell.ex; 241 } else { 242 DebugLog.stdoutPrintln( 243 "Future for " + cell.requester + " on thread " + cell.thread + " resuming...", 244 DebugLog.BSF_LOG_L3); 245 } 246 } 247 } catch (Exception ex) { 248 throw new RemoteException ("Error in future management", ex); 249 } 250 } 251 252 public void completeFuture(Object requester) throws RemoteException { 253 254 Enumeration e; 255 FutureCell cell = null; 256 257 DebugLog.stdoutPrintln( 258 "Completing future for requester " + requester + " on " + this, 259 DebugLog.BSF_LOG_L3); 260 try { 261 synchronized (m_futureLock) { 262 cell = findFuture(requester); 263 DebugLog.stdoutPrintln( 264 "Waking up future for requester " + requester + " on " + this, 265 DebugLog.BSF_LOG_L3); 266 cell.resume = true; 268 m_futureLock.notifyAll(); 269 } 270 } catch (Exception ex) { 271 throw new RemoteException ("Error in future management", ex); 272 } 273 } 274 275 public void revokeFuture(Object requester, Exception ex) throws Exception { 276 277 Enumeration e; 278 FutureCell cell = null; 279 280 DebugLog.stdoutPrintln( 281 "revoking future for requester " + requester + " on " + this, 282 DebugLog.BSF_LOG_L3); 283 284 try { 285 synchronized (m_futureLock) { 286 cell = findFuture(requester); 287 DebugLog.stdoutPrintln( 288 "Waking up future for requester " + requester + " on " + this, 289 DebugLog.BSF_LOG_L3); 290 cell.resume = true; 292 cell.ex = ex; 293 m_futureLock.notifyAll(); 294 } 295 } catch (Exception ex2) { 296 throw new RemoteException ("Error in future management", ex2); 297 } 298 } 299 private FutureCell findFuture(Object requester) throws Exception { 300 301 Enumeration e; 302 FutureCell cell = null; 303 304 DebugLog.stdoutPrintln( 305 "finding future for requester " + requester + " on " + this, 306 DebugLog.BSF_LOG_L3); 307 e = m_futureCells.elements(); 308 while (e.hasMoreElements()) { 309 cell = (FutureCell) e.nextElement(); 310 if (cell.requester == requester) 311 return cell; 312 } 313 DebugLog.stdoutPrintln( 314 "Non-existant future for requester " + requester, 315 DebugLog.BSF_LOG_L2); 316 throw new Exception ("Non-existant future for requester " + requester); 317 } 318 319 } 320 321 | Popular Tags |