1 21 22 package org.apache.derby.iapi.services.context; 23 24 import org.apache.derby.iapi.services.monitor.Monitor; 25 import org.apache.derby.iapi.services.sanity.SanityManager; 26 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 27 28 import java.util.Hashtable ; 29 import java.util.Enumeration ; 30 31 import java.util.HashSet ; 32 import java.util.Iterator ; 33 34 37 public final class ContextService { 39 40 private static ContextService factory; 41 private HeaderPrintWriter errorStream; 42 43 160 private ThreadLocal threadContextList = new ThreadLocal (); 161 162 171 private HashSet allContexts; 172 173 178 public ContextService() { 179 180 errorStream = Monitor.getStream(); 182 183 ContextService.factory = this; 184 185 allContexts = new HashSet (); 186 187 } 188 189 192 public static void stop() { 193 ContextService fact = ContextService.factory; 197 if (fact != null) { 198 synchronized (fact) { 199 fact.allContexts = null; 200 fact.threadContextList = null; 201 ContextService.factory = null; 202 } 203 } 204 } 205 206 public static ContextService getFactory() { 207 ContextService csf = factory; 208 209 if (csf == null) 210 throw new ShutdownException(); 211 return csf; 212 } 213 219 public static Context getContext(String contextId) { 220 221 ContextManager cm = getFactory().getCurrentContextManager(); 222 223 if( cm == null) 224 return null; 225 226 return cm.getContext(contextId); 227 } 228 229 238 public static Context getContextOrNull(String contextId) { 239 ContextService csf = factory; 240 241 if (csf == null) 242 return null; 243 244 ContextManager cm = csf.getCurrentContextManager(); 245 246 if (cm == null) 247 return null; 248 249 return cm.getContext(contextId); 250 } 251 252 253 263 public ContextManager getCurrentContextManager() { 264 265 ThreadLocal tcl = threadContextList; 266 if (tcl == null) { 267 return null; 269 } 270 271 Object list = tcl.get(); 272 273 if (list instanceof ContextManager) { 274 275 Thread me = Thread.currentThread(); 276 277 ContextManager cm = (ContextManager) list; 278 if (cm.activeThread == me) 279 return cm; 280 return null; 281 } 282 283 if (list == null) 284 return null; 285 286 java.util.Stack stack = (java.util.Stack ) list; 287 return (ContextManager) (stack.peek()); 288 289 } 290 291 296 public void resetCurrentContextManager(ContextManager cm) { 297 ThreadLocal tcl = threadContextList; 298 299 if (tcl == null) { 300 return; 302 } 303 304 if (SanityManager.DEBUG) { 305 306 if (Thread.currentThread() != cm.activeThread) { 307 SanityManager.THROWASSERT("resetCurrentContextManager - mismatch threads - current" + Thread.currentThread() + " - cm's " + cm.activeThread); 308 } 309 310 if (getCurrentContextManager() != cm) { 311 SanityManager.THROWASSERT("resetCurrentContextManager - mismatch contexts - " + Thread.currentThread()); 312 } 313 314 if (cm.activeCount < -1) { 315 SanityManager.THROWASSERT("resetCurrentContextManager - invalid count - current" + Thread.currentThread() + " - count " + cm.activeCount); 316 } 317 318 if (cm.activeCount == 0) { 319 SanityManager.THROWASSERT("resetCurrentContextManager - invalid count - current" + Thread.currentThread() + " - count " + cm.activeCount); 320 } 321 322 if (cm.activeCount > 0) { 323 if (tcl.get() != cm) 324 SanityManager.THROWASSERT("resetCurrentContextManager - invalid thread local " + Thread.currentThread() + " - object " + tcl.get()); 325 326 } 327 } 328 329 if (cm.activeCount != -1) { 330 if (--cm.activeCount == 0) { 331 cm.activeThread = null; 332 333 if (cm.isEmpty()) 342 tcl.set(null); 343 344 } 345 return; 346 } 347 348 java.util.Stack stack = (java.util.Stack ) tcl.get(); 349 350 Object oldCM = stack.pop(); 351 352 ContextManager nextCM = (ContextManager) stack.peek(); 353 354 boolean seenMultipleCM = false; 355 boolean seenCM = false; 356 for (int i = 0; i < stack.size(); i++) { 357 358 Object stackCM = stack.elementAt(i); 359 if (stackCM != nextCM) 360 seenMultipleCM = true; 361 362 if (stackCM == cm) 363 seenCM = true; 364 } 365 366 if (!seenCM) { 367 cm.activeThread = null; 368 cm.activeCount = 0; 369 } 370 371 if (!seenMultipleCM) 372 { 373 nextCM.activeCount = stack.size(); 376 tcl.set(nextCM); 377 } 378 } 379 380 392 private boolean addToThreadList(Thread me, ContextManager associateCM) { 393 394 ThreadLocal tcl = threadContextList; 395 396 if (tcl == null) { 397 return false; 399 } 400 401 Object list = tcl.get(); 402 403 if (associateCM == list) 405 return true; 406 407 if (list == null) 409 { 410 tcl.set(associateCM); 411 return true; 412 } 413 414 java.util.Stack stack; 415 if (list instanceof ContextManager) { 416 417 421 ContextManager threadsCM = (ContextManager) list; 422 if (me == null) 423 me = Thread.currentThread(); 424 425 if (threadsCM.activeThread != me) { 426 tcl.set(associateCM); 429 return true; 430 } 431 432 stack = new java.util.Stack (); 435 tcl.set(stack); 436 437 for (int i = 0; i < threadsCM.activeCount; i++) 442 { 443 stack.push(threadsCM); 444 } 445 threadsCM.activeCount = -1; 446 } 447 else 448 { 449 stack = (java.util.Stack ) list; 452 } 453 454 stack.push(associateCM); 455 associateCM.activeCount = -1; 456 457 if (SanityManager.DEBUG) { 458 459 if (SanityManager.DEBUG_ON("memoryLeakTrace")) { 460 461 if (stack.size() > 10) 462 System.out.println("memoryLeakTrace:ContextService:threadLocal " + stack.size()); 463 } 464 } 465 466 return false; 467 } 468 469 493 public void setCurrentContextManager(ContextManager cm) { 494 495 496 if (SanityManager.DEBUG) { 497 Thread me = Thread.currentThread(); 498 499 if (cm.activeThread != null && me != cm.activeThread) { 500 SanityManager.THROWASSERT("setCurrentContextManager - mismatch threads - current " + me + " - cm's " + cm.activeThread); 501 } 502 503 } 504 505 Thread me = null; 506 507 if (cm.activeThread == null) { 508 cm.activeThread = (me = Thread.currentThread()); 509 } 510 if (addToThreadList(me, cm)) 511 cm.activeCount++; 512 } 513 514 519 public ContextManager newContextManager() 520 { 521 ContextManager cm = new ContextManager(this, errorStream); 522 523 new SystemContext(cm); 526 527 synchronized (this) { 528 allContexts.add(cm); 529 530 if (SanityManager.DEBUG) { 531 532 if (SanityManager.DEBUG_ON("memoryLeakTrace")) { 533 534 if (allContexts.size() > 50) 535 System.out.println("memoryLeakTrace:ContextService:allContexts " + allContexts.size()); 536 } 537 } 538 } 539 540 return cm; 541 } 542 543 public void notifyAllActiveThreads(Context c) { 544 Thread me = Thread.currentThread(); 545 546 synchronized (this) { 547 for (Iterator i = allContexts.iterator(); i.hasNext(); ) { 548 549 ContextManager cm = (ContextManager) i.next(); 550 551 Thread active = cm.activeThread; 552 553 if (active == me) 554 continue; 555 556 if (active == null) 557 continue; 558 559 if (cm.setInterrupted(c)) 560 active.interrupt(); 561 } 562 } 563 } 564 565 569 synchronized void removeContext(ContextManager cm) 570 { 571 if (allContexts != null) 572 allContexts.remove( cm); 573 } 574 } 575 | Popular Tags |