1 55 56 package org.apache.bsf.debug.util; 57 58 import org.apache.bsf.debug.util.DebugLog; 59 60 public class ThreadCell implements Runnable { 61 62 static private int ThreadIdGenerator = 0; 63 static boolean isServer; 64 65 static { 66 ThreadIdGenerator = (int)System.currentTimeMillis(); 67 isServer = Boolean.getBoolean("org.apache.bsf.isServer"); 68 } 69 70 Thread m_thread; 71 Object m_streamLock; 72 Object m_waitLock; 73 ResultCell m_stack; 74 int m_thid; 75 boolean m_loopback; 76 SocketConnection m_con; 77 boolean m_started; 78 79 90 ThreadCell(SocketConnection con, Thread thread) { 91 92 m_streamLock = new Object (); 93 m_waitLock = new Object (); 94 95 m_con = con; 96 if (isServer) 97 m_thid = ++ThreadIdGenerator; 98 else 99 m_thid = --ThreadIdGenerator; 100 101 m_thread = thread; 102 } 103 104 113 114 ThreadCell(SocketConnection con, int thId) { 115 m_streamLock = new Object (); 116 m_waitLock = new Object (); 117 m_thread = new Thread (this, "BSF Thread " + thId); 118 119 m_started = false; 120 m_thread.start(); 121 synchronized (m_waitLock) { 122 while (!m_started) { 123 try { 124 m_waitLock.wait(1); 125 } catch (InterruptedException ex) { 126 } 127 } 128 } 129 m_con = con; 130 m_thid = thId; 131 m_stack = null; 132 } 133 134 int getThId() { 135 return m_thid; 136 } 137 138 Thread getThread() { 139 return m_thread; 140 } 141 142 147 public synchronized void run() { 148 boolean loop = true; 149 150 m_started = true; 151 while (loop) { 152 try { 153 this.wait(); 154 } catch (InterruptedException ex) { 155 loop = false; 156 continue; 157 } 158 if (m_loopback) { 159 m_loopback = false; 163 execTopStack(); 164 165 try { 166 popInvocation(null,true); 167 } catch (Exception ex) { 168 } 170 continue; 171 } 172 } 173 } 174 175 186 private synchronized void execTopStack() { 187 try { 188 m_con.dispatchInvocation(m_stack); 189 } catch (Exception ex) { 190 DebugLog.stderrPrintln("\nException Raised in loopback...", DebugLog.BSF_LOG_L3); 191 m_stack.setException(ex); 192 } 193 m_stack.sendResult(); 196 } 197 198 204 public synchronized void waitOnCompletion(ResultCell rcell) 205 throws Exception { 206 207 if (rcell != m_stack) 208 throw new Error ("About to wait for completion, but not on the top of the stack..."); 209 210 rcell.sendInvocation(); 212 213 while (!rcell.done) { 216 try { 217 this.wait(); 218 } catch (InterruptedException ex) { 219 } 220 224 if (m_loopback) { 225 m_loopback = false; 230 231 execTopStack(); 235 236 popInvocation(m_stack, true); 240 continue; 241 } 242 if (m_stack.done) break; 243 } 244 popInvocation(rcell, false); 245 } 246 247 public synchronized void completionNotify(ResultCell rcell) { 248 rcell.done = true; 249 if (rcell.disconnected) m_thread.interrupt(); 250 this.notify(); 251 } 252 253 public synchronized void pushLoopback(ResultCell rcell) { 254 pushInvocation(rcell); 257 m_loopback = true; 258 this.notify(); 259 } 260 261 public synchronized void pushInvocation(ResultCell rcell) { 262 rcell.thread = this; 265 rcell.parent = m_stack; 266 m_stack = rcell; 267 } 268 269 private synchronized ResultCell popInvocation (ResultCell rcell, 270 boolean loopback) 271 throws Exception { 272 Exception ex; 275 if (m_stack==null) 276 throw new Error ("***** Unpaired Push/Pop."); 277 if (rcell==null) { 278 if (m_stack.parent!=null) 279 throw new Error ("***** Not popping last frame..."); 280 rcell = m_stack; 281 m_stack = null; 282 } else { 283 if (m_stack!=rcell) 284 throw new Error ("***** Popping but not top of stack."); 285 286 m_stack = rcell.parent; 287 } 288 289 if (!loopback) { 290 ex = rcell.getException(); 291 if (ex!=null) 292 throw ex; 293 } 294 return rcell; 295 } 296 } 297 | Popular Tags |