~ubuntu-branches/ubuntu/maverick/electric/maverick

« back to all changes in this revision

Viewing changes to com/sun/electric/tool/MultiTaskJob.java

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2010-01-09 16:26:04 UTC
  • mfrom: (1.1.4 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100109162604-1ypvmy8ijmlc6oq7
Tags: 8.10-1
* New upstream version.
* debian/control
  - Add libjava3d-java and quilt build dependencies.
  - Update standards version to 3.8.3.
  - Add libjava3d-java as recommends to binary package.
* debian/rules
  - Use quilt patch system instead of simple patchsys.
  - Add java3d related jar files to DEB_JARS.
* debian/patches/*
  - Update as per current upstream source. Convert to quilt.
* debian/ant.properties
  - Do not disable 3D plugin anymore.
  - Use new property to disable compilation of OS X related classes.
* debian/wrappers/electric
  - Add java3d related jar files to runtime classpath.
* debian/README.source
  - Change text to the appropriate one for quilt.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 */
24
24
package com.sun.electric.tool;
25
25
 
 
26
import com.sun.electric.database.Environment;
 
27
import java.util.ArrayList;
26
28
import java.util.LinkedHashMap;
27
29
import java.util.Map;
28
30
 
40
42
 * This stage is performed by consumer.consume method.
41
43
 */
42
44
public abstract class MultiTaskJob<TaskKey,TaskResult,Result> extends Job {
43
 
    private transient LinkedHashMap<TaskKey,TaskJob> tasks;
 
45
    private transient LinkedHashMap<TaskKey,Task> tasks;
 
46
    private transient ArrayList<Task> allTasks;
 
47
    private transient int tasksDone;
 
48
    private transient Environment env;
 
49
    private transient EThread ownerThread;
 
50
    private transient int numberOfRunningThreads;
 
51
    private transient int numberOfFinishedThreads;
44
52
    private Consumer<Result> consumer;
45
 
    
 
53
 
46
54
    /**
47
55
         * Constructor creates a new instance of MultiTaskJob.
48
56
         * @param jobName a string that describes this MultiTaskJob.
49
57
         * @param t the Tool that originated this MultiTaskJob.
50
 
         * @param jobType the Type of this Job (SERVER_EXAMINE or CHANGE).
51
58
     * @param c interface which consumes the result on server
52
59
         */
53
 
    public MultiTaskJob(String jobName, Tool t, Type jobType, Consumer<Result> c) {
54
 
        super(jobName, t, jobType, null, null, Job.Priority.USER);
 
60
    public MultiTaskJob(String jobName, Tool t, Consumer<Result> c) {
 
61
        super(jobName, t, Job.Type.SERVER_EXAMINE, null, null, Job.Priority.USER);
55
62
        this.consumer = c;
56
63
    }
57
 
    
 
64
 
58
65
    /**
59
66
     * This abstract method split large computation into smaller task.
60
67
     * Smaller tasks are identified by TaskKey class.
61
68
     * Each task is scheduled by startTask method.
62
69
     * @throws com.sun.electric.tool.JobException
63
70
     */
64
 
    public abstract void prepareTasks() throws JobException; 
65
 
    
 
71
    public abstract void prepareTasks() throws JobException;
 
72
 
66
73
    /**
67
74
     * This abtract methods performs computation of each task.
68
75
     * @param taskKey task key which identifies the task
70
77
     * @throws com.sun.electric.tool.JobException
71
78
     */
72
79
    public abstract TaskResult runTask(TaskKey taskKey) throws JobException;
73
 
    
 
80
 
74
81
    /**
75
82
     * This abtract method combines task results into final result.
76
83
     * @param taskResults map which contains result of each completed task.
78
85
     * @throws com.sun.electric.tool.JobException
79
86
     */
80
87
    public abstract Result mergeTaskResults(Map<TaskKey,TaskResult> taskResults) throws JobException;
81
 
    
 
88
 
82
89
//    /**
83
90
//     * This method executes in the Client side after normal termination of full computation.
84
91
//     * This method should perform all needed termination actions.
85
92
//     * @param result result of full computation.
86
93
//     */
87
94
//    public void terminateOK(Result result) {}
88
 
    
89
 
    /**
90
 
     * Schedules task. Should be callled from prepareTasks or runTask methods only.
91
 
     * @param taskName task name which is appeared in Jobs Explorer Tree
92
 
     * @param taskKey task key which identifies the task.
93
 
     */
94
 
    public void startTask(String taskName, TaskKey taskKey) {
95
 
        TaskJob task = new TaskJob(taskName, taskKey);
96
 
        synchronized (this) {
97
 
            if (tasks.containsKey(taskKey))
98
 
                throw new IllegalArgumentException();
99
 
            tasks.put(taskKey, task);
100
 
        }
101
 
        task.startJobOnMyResult();
102
 
    }
103
 
    
 
95
 
104
96
    /**
105
97
     * This method is not overriden by subclasses.
106
98
     * Override methods prepareTasks, runTask, mergeTaskResults instead.
108
100
     */
109
101
    @Override
110
102
    public final boolean doIt() throws JobException {
111
 
        tasks = new LinkedHashMap<TaskKey,TaskJob>();
 
103
        tasks = new LinkedHashMap<TaskKey,Task>();
 
104
        allTasks = new ArrayList<Task>();
112
105
        prepareTasks();
113
 
        (new MergeJob()).startJob();
 
106
        env = Environment.getThreadEnvironment();
 
107
        ownerThread = (EThread)Thread.currentThread();
 
108
        numberOfRunningThreads = ServerJobManager.getMaxNumberOfThreads();
 
109
        for (int id = 0; id < numberOfRunningThreads; id++)
 
110
            new WorkingThread(id).start();
 
111
        waitTasks();
 
112
 
 
113
        LinkedHashMap<TaskKey,TaskResult> taskResults = new LinkedHashMap<TaskKey,TaskResult>();
 
114
        for (Task task: tasks.values()) {
 
115
            if (task.taskResult != null)
 
116
                taskResults.put(task.taskKey, task.taskResult);
 
117
        }
 
118
        Result result = mergeTaskResults(taskResults);
 
119
        if (consumer != null)
 
120
            consumer.consume(result);
114
121
        return true;
115
122
    }
116
 
    
117
 
    private class TaskJob extends Job {
118
 
        private transient final TaskKey taskKey;
119
 
        private transient TaskResult taskResult;
120
 
        
121
 
        private TaskJob(String taskName, TaskKey tK) {
122
 
            super(taskName, MultiTaskJob.this.tool, 
123
 
                    Job.Type.SERVER_EXAMINE, null, null, Job.Priority.USER);
124
 
            this.taskKey = tK;
125
 
        }
126
 
        
127
 
        @Override
128
 
        public boolean doIt() throws JobException {
129
 
            taskResult = runTask(taskKey);
130
 
            return true;
131
 
        }
132
 
        
133
 
        @Override
134
 
        public void abort() {
135
 
            MultiTaskJob.this.abort();
136
 
        }
137
 
    }
138
 
    
139
 
    private class MergeJob extends Job {
140
 
        private Result result;
141
 
        
142
 
        private MergeJob() {
143
 
            super(MultiTaskJob.this.ejob.jobName + "merge", MultiTaskJob.this.tool, 
144
 
                    Job.Type.CHANGE, null, null, Job.Priority.USER);
145
 
        }
146
 
        
147
 
        @Override
148
 
        public boolean doIt() throws JobException {
149
 
            LinkedHashMap<TaskKey,TaskResult> taskResults = new LinkedHashMap<TaskKey,TaskResult>();
150
 
            for (TaskJob task: tasks.values()) {
151
 
                if (task.taskResult != null)
152
 
                    taskResults.put(task.taskKey, task.taskResult);
 
123
 
 
124
    /**
 
125
     * Schedules task. Should be callled from prepareTasks or runTask methods only.
 
126
     * @param taskName task name which is appeared in Jobs Explorer Tree
 
127
     * @param taskKey task key which identifies the task.
 
128
     */
 
129
    public synchronized void startTask(String taskName, TaskKey taskKey) {
 
130
        Task task = new Task(taskName, taskKey);
 
131
        if (tasks.containsKey(taskKey))
 
132
            throw new IllegalArgumentException();
 
133
        tasks.put(taskKey, task);
 
134
        allTasks.add(task);
 
135
    }
 
136
 
 
137
    private synchronized Task getTask() {
 
138
        if (tasksDone == allTasks.size()) {
 
139
            return null;
 
140
        }
 
141
        return allTasks.get(tasksDone++);
 
142
    }
 
143
 
 
144
    private synchronized void waitTasks() {
 
145
        try {
 
146
            while (numberOfFinishedThreads < numberOfRunningThreads)
 
147
                wait();
 
148
        } catch (InterruptedException e) {
 
149
            e.printStackTrace();
 
150
        }
 
151
    }
 
152
 
 
153
    private synchronized void finishWorkingThread() {
 
154
        numberOfFinishedThreads++;
 
155
        notify();
 
156
    }
 
157
 
 
158
    private class Task {
 
159
        private final String taskName;
 
160
        private final TaskKey taskKey;
 
161
        private TaskResult taskResult;
 
162
 
 
163
        private Task(String taskName, TaskKey taskKey) {
 
164
            this.taskName = taskName;
 
165
            this.taskKey = taskKey;
 
166
        }
 
167
    }
 
168
 
 
169
    class WorkingThread extends EThread {
 
170
 
 
171
        private WorkingThread(int id) {
 
172
            super("WorkingThread-"+id);
 
173
            userInterface = new ServerJobManager.UserInterfaceRedirect(ownerThread.ejob.jobKey);
 
174
            ejob = ownerThread.ejob;
 
175
            isServerThread = ownerThread.isServerThread;
 
176
            database = ownerThread.database;
 
177
        }
 
178
 
 
179
        @Override
 
180
        public void run() {
 
181
            Environment.setThreadEnvironment(env);
 
182
            for (;;) {
 
183
                Task t = getTask();
 
184
                if (t == null) {
 
185
                    break;
 
186
                }
 
187
                try {
 
188
                    t.taskResult = runTask(t.taskKey);
 
189
                } catch (Throwable e) {
 
190
                    e.getStackTrace();
 
191
                    e.printStackTrace(System.out);
 
192
                    e.printStackTrace();
 
193
                }
153
194
            }
154
 
            result = mergeTaskResults(taskResults);
155
 
            if (consumer != null)
156
 
                consumer.consume(result);
157
 
//            fieldVariableChanged("result");
158
 
            return true;
159
 
        }
160
 
        
161
 
        @Override
162
 
        public void abort() {
163
 
            MultiTaskJob.this.abort();
164
 
        }
165
 
//        /**
166
 
//         * This method executes in the Client side after normal termination of doIt method.
167
 
//         * This method should perform all needed termination actions.
168
 
//         */
169
 
//        @Override
170
 
//        public void terminateOK() {
171
 
//            MultiTaskJob.this.terminateOK(result);
172
 
//        }
 
195
            finishWorkingThread();
 
196
        }
173
197
    }
174
198
}