1 31 package org.jruby.internal.runtime; 32 33 import java.util.ArrayList ; 34 import java.util.Collections ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Set ; 38 39 import org.jruby.Ruby; 40 import org.jruby.RubyThread; 41 import org.jruby.runtime.ThreadContext; 42 import org.jruby.util.collections.WeakHashSet; 43 44 public class ThreadService { 45 private Ruby runtime; 46 private ThreadContext mainContext; 47 private ThreadLocal localContext; 48 private ThreadGroup rubyThreadGroup; 49 private Set rubyThreadList; 50 private Thread mainThread; 51 private RubyThread criticalThread; 52 53 public ThreadService(Ruby runtime) { 54 this.runtime = runtime; 55 this.mainContext = new ThreadContext(runtime); 56 this.localContext = new ThreadLocal (); 57 this.rubyThreadGroup = new ThreadGroup ("Ruby Threads#" + runtime.hashCode()); 58 this.rubyThreadList = Collections.synchronizedSet(new WeakHashSet()); 59 60 mainThread = Thread.currentThread(); 62 localContext.set(mainContext); 63 rubyThreadList.add(mainThread); 64 } 65 66 public void disposeCurrentThread() { 67 localContext.set(null); 68 } 69 70 public ThreadContext getCurrentContext() { 71 ThreadContext tc = (ThreadContext) localContext.get(); 72 73 if (tc == null) { 74 tc = adoptCurrentThread(); 75 } 76 77 return tc; 78 } 79 80 private ThreadContext adoptCurrentThread() { 81 Thread current = Thread.currentThread(); 82 83 RubyThread.adopt(runtime.getClass("Thread"), current); 84 85 return (ThreadContext) localContext.get(); 86 } 87 88 public RubyThread getMainThread() { 89 return mainContext.getThread(); 90 } 91 92 public void setMainThread(RubyThread thread) { 93 mainContext.setThread(thread); 94 } 95 96 public synchronized RubyThread[] getActiveRubyThreads() { 97 99 synchronized(rubyThreadList) { 100 List rtList = new ArrayList (rubyThreadList.size()); 101 102 for (Iterator iter = rubyThreadList.iterator(); iter.hasNext();) { 103 Thread t = (Thread )iter.next(); 104 105 if (!t.isAlive()) continue; 106 107 RubyThread rt = getRubyThreadFromThread(t); 108 rtList.add(rt); 109 } 110 111 RubyThread[] rubyThreads = new RubyThread[rtList.size()]; 112 rtList.toArray(rubyThreads); 113 114 return rubyThreads; 115 } 116 } 117 118 public ThreadGroup getRubyThreadGroup() { 119 return rubyThreadGroup; 120 } 121 122 public synchronized void registerNewThread(RubyThread thread) { 123 localContext.set(new ThreadContext(runtime)); 124 getCurrentContext().setThread(thread); 125 rubyThreadList.add(Thread.currentThread()); 127 } 128 129 public synchronized void setCritical(boolean critical) { 130 RubyThread currentThread = getCurrentContext().getThread(); 131 132 if (criticalThread != null) { 134 if (critical) { 136 return; 138 } 139 if (criticalThread != currentThread) { 140 return; 142 } 143 144 synchronized (criticalThread) { 146 RubyThread critThread = criticalThread; 147 criticalThread = null; 148 critThread.notifyAll(); 149 } 150 } else { 151 if (!critical) { 153 return; 155 } 156 157 criticalThread = currentThread; 159 } 160 } 161 162 private RubyThread getRubyThreadFromThread(Thread activeThread) { 163 RubyThread rubyThread; 164 if (activeThread instanceof RubyNativeThread) { 165 RubyNativeThread rubyNativeThread = (RubyNativeThread)activeThread; 166 rubyThread = rubyNativeThread.getRubyThread(); 167 } else { 168 rubyThread = mainContext.getThread(); 170 } 171 return rubyThread; 172 } 173 174 public RubyThread getCriticalThread() { 175 return criticalThread; 176 } 177 178 } 179 | Popular Tags |