KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > execution > RunClassThread


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.execution;
21
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Set JavaDoc;
27 import org.openide.util.NbBundle;
28 import org.openide.windows.InputOutput;
29
30 /** Simple class for executing tasks in extra threads */
31 final class RunClassThread extends Thread JavaDoc implements IOThreadIfc {
32
33     /** InputOutput that is to be used */
34     private InputOutput io;
35     /** name */
36     String JavaDoc allName; // used in innerclass Runnable
37
/** reference to outer class */
38     private final ExecutionEngine engine;
39     /** ref to a Task */
40     private final ExecutorTaskImpl task;
41     /** Task to run */
42     private /*final*/ Runnable JavaDoc run;
43
44     /** generated names */
45     static int number = 0;
46
47     /** Created group */
48     TaskThreadGroup mygroup;
49     
50     /** Is finalized? */
51     boolean finalized;
52
53     /**
54     * @param base is a ThreadGroup we want to be in
55     * @param m is a method to invoke
56     * @param argv are params for the method
57     */

58     public RunClassThread(TaskThreadGroup base,
59                     String JavaDoc name,
60                     int number,
61                     InputOutput io,
62                     org.netbeans.core.execution.ExecutionEngine engine,
63                     ExecutorTaskImpl task,
64                     Runnable JavaDoc run) {
65         super(base, "exec_" + name + "_" + number); // NOI18N
66
mygroup = base;
67         mygroup.setRunClassThread(this);
68         this.allName = name;
69         this.io = io;
70         this.engine = engine;
71         this.task = task;
72         this.run = run;
73         this.finalized = false;
74         // #33789 - this thread must not be daemon otherwise it is immediately destroyed
75
setDaemon(false);
76         this.start();
77     }
78
79     /** runs the thread
80     */

81     public void run() {
82         mygroup.setFinalizable(); // mark it finalizable - after the completetion of the current thread it will be finalized
83

84         boolean fire = true;
85
86         if (allName == null) {
87             allName = generateName();
88             fire = false;
89         }
90
91         String JavaDoc ioname = NbBundle.getMessage(RunClassThread.class, "CTL_ProgramIO", allName);
92
93         // prepare environment (threads, In/Out, atd.)
94
DefaultSysProcess def;
95         if (io != null) {
96             def = new DefaultSysProcess(this, mygroup, io, allName);
97             TaskIO tIO = new TaskIO(io, ioname, true);
98             io.select();
99             engine.getTaskIOs ().put (io, tIO);
100         } else { // advance TaskIO for this process
101
TaskIO tIO = null;
102             tIO = engine.getTaskIOs().getTaskIO(ioname);
103             if (tIO == null) { // executed for the first time
104
io = org.openide.windows.IOProvider.getDefault().getIO(ioname, true);
105                 tIO = new TaskIO(io, ioname);
106             } else {
107                 io = tIO.getInout();
108             }
109             io.select();
110             io.setFocusTaken(true);
111             engine.getTaskIOs().put(io, tIO);
112             def = new DefaultSysProcess(this, mygroup, io, allName);
113         }
114
115         ExecutionEvent ev = null;
116         try {
117
118             ev = new ExecutionEvent(engine, def);
119             if (fire) {
120                 engine.fireExecutionStarted(ev);
121             }
122
123             synchronized (task.lock) {
124                 task.proc = def;
125                 task.lock.notifyAll();
126             }
127
128             // exec foreign Runnable
129
run.run();
130             // throw away user runnable
131
run = null;
132
133             int result = 2;
134             try {
135                 result = def.result();
136             } catch (ThreadDeath JavaDoc err) { // terminated while executing
137
} catch (IllegalMonitorStateException JavaDoc e) {
138                 // killed while leaving synchronized section, ignore
139
}
140             task.result = result;
141
142         } finally {
143             Thread.interrupted(); // Clear the interruption status at first.
144
if (ev != null) {
145                 if (fire) {
146                     engine.fireExecutionFinished(ev);
147                 }
148             }
149
150             engine.closeGroup(mygroup); // free windows
151
task.finished();
152             engine.getTaskIOs().free(mygroup, io); // closes output
153

154             /* Disable for now unless really needed. Cf. #36395, #36393.
155             cleanUpHack(mygroup);
156             */

157             mygroup = null;
158             io = null;
159             synchronized (this) {
160                 finalized = true;
161                 notifyAll();
162             }
163         }
164     } // run method
165

166     public InputOutput getInputOutput() {
167         return io;
168     }
169     
170     public synchronized boolean waitForEnd() throws InterruptedException JavaDoc {
171         if (finalized) {
172             return true;
173         }
174         
175         this.wait(1000);
176         return finalized;
177     }
178     
179     static String JavaDoc generateName() {
180         return NbBundle.getMessage(RunClassThread.class, "CTL_GeneratedName", number++);
181     }
182     
183     /**
184      * Workaround for a JRE bug that unstarted threads are not GC'd.
185      * @see http://www.netbeans.org/issues/show_bug.cgi?id=36395
186      * @see http://developer.java.sun.com/developer/bugParade/bugs/4533087.html
187      * /
188     private static void cleanUpHack(ThreadGroup tg) {
189         try {
190             Field f = ThreadGroup.class.getDeclaredField("threads"); // NOI18N
191             f.setAccessible(true);
192             Method m = ThreadGroup.class.getDeclaredMethod("remove", new Class[] {Thread.class}); // NOI18N
193             m.setAccessible(true);
194             Set stillborn = new HashSet(); // Set<Thread>
195             synchronized (tg) {
196                 Thread[] ts = (Thread[])f.get(tg);
197                 if (ts == null) {
198                     return;
199                 }
200                 for (int j = 0; j < ts.length; j++) {
201                     Thread t = ts[j];
202                     if (t == null) {
203                         continue;
204                     }
205                     if (!t.isAlive()) {
206                         stillborn.add(t);
207                     }
208                 }
209             }
210             Iterator it = stillborn.iterator();
211             while (it.hasNext()) {
212                 Thread t = (Thread)it.next();
213                 m.invoke(tg, new Object[] {t});
214             }
215             // Handle child thread groups, too:
216             ThreadGroup[] kids = new ThreadGroup[tg.activeGroupCount()];
217             tg.enumerate(kids);
218             for (int i = 0; i < kids.length; i++) {
219                 if (kids[i] != null) {
220                     cleanUpHack(kids[i]);
221                 }
222             }
223         } catch (Exception e) {
224             // Oh well.
225             e.printStackTrace();
226         }
227     }
228     */

229     
230 }
231
232
Popular Tags