📄 serverjobmanager.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ServerJobManager.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool;import com.sun.electric.database.Snapshot;import com.sun.electric.database.geometry.Dimension2D;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.EDatabase;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.UserInterface;import com.sun.electric.tool.user.ActivityLogger;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.tool.user.MessagesStream;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.ui.JobTree;import com.sun.electric.tool.user.ui.TopLevel;import java.awt.geom.Point2D;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Observable;import java.util.Observer;import java.util.concurrent.locks.Condition;import java.util.logging.Level;import javax.swing.SwingUtilities;/** * */public class ServerJobManager extends JobManager implements Observer, Runnable { private static final String CLASS_NAME = Job.class.getName(); private static final int DEFAULT_NUM_THREADS = 2; /** mutex for database synchronization. */ private final Condition databaseChangesMutex = newCondition(); private final ServerSocket serverSocket;// private final ArrayList<EJob> finishedJobs = new ArrayList<EJob>(); private final ArrayList<Client> serverConnections = new ArrayList<Client>();// private final UserInterface redirectInterface = new UserInterfaceRedirect(); private int numThreads; private final int maxNumThreads; private boolean runningChangeJob; private boolean guiChanged; private boolean signalledEThread; private Snapshot currentSnapshot = EDatabase.serverDatabase().getInitialSnapshot(); /** Creates a new instance of JobPool */ ServerJobManager(int recommendedNumThreads) { maxNumThreads = initThreads(recommendedNumThreads); serverSocket = null; } ServerJobManager(int recommendedNumThreads, int socketPort) { maxNumThreads = initThreads(recommendedNumThreads); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(socketPort); System.out.println("ServerSocket waits for port " + socketPort); } catch (IOException e) { System.out.println("ServerSocket mode failure: " + e.getMessage()); } this.serverSocket = serverSocket; if (User.isSnapshotLogging()) initSnapshotLogging(); } private int initThreads(int recommendedNumThreads) { int maxNumThreads = DEFAULT_NUM_THREADS; if (recommendedNumThreads > 0) maxNumThreads = recommendedNumThreads; Job.logger.logp(Level.FINE, CLASS_NAME, "initThreads", "maxNumThreads=" + maxNumThreads); return maxNumThreads; } void initSnapshotLogging() { int connectionId = serverConnections.size(); StreamClient conn; lock(); try { File tempFile = File.createTempFile("elec", ".slog"); FileOutputStream out = new FileOutputStream(tempFile); System.out.println("Writing snapshot log to " + tempFile); ActivityLogger.logMessage("Writing snapshot log to " + tempFile); conn = new StreamClient(connectionId, null, new BufferedOutputStream(out), currentSnapshot); serverConnections.add(conn); } catch (IOException e) { System.out.println("Failed to create snapshot log file:" + e.getMessage()); return; } finally { unlock(); } System.out.println("Accepted connection " + connectionId); conn.start(); } /** Add job to list of jobs */ void addJob(EJob ejob, boolean onMySnapshot) { lock(); try { if (onMySnapshot) waitingJobs.add(0, ejob); else waitingJobs.add(ejob); setEJobState(ejob, EJob.State.WAITING, onMySnapshot ? EJob.WAITING_NOW : "waiting"); invokeEThread(); } finally { unlock(); } } /** Remove job from list of jobs */ void removeJob(Job j) { EJob ejob = j.ejob; lock(); try { switch (j.ejob.state) { case WAITING: setEJobState(ejob, EJob.State.SERVER_DONE, null); case SERVER_DONE: setEJobState(ejob, EJob.State.CLIENT_DONE, null); case CLIENT_DONE:// finishedJobs.remove(j.ejob); if (!Job.BATCHMODE && !guiChanged) SwingUtilities.invokeLater(this); guiChanged = true; break; } } finally { unlock(); } } void setProgress(EJob ejob, String progress) { lock(); try { if (ejob.state == EJob.State.RUNNING) setEJobState(ejob, EJob.State.RUNNING, progress); } finally { unlock(); } } /** get all jobs iterator */ Iterator<Job> getAllJobs() { lock(); try { ArrayList<Job> jobsList = new ArrayList<Job>();// for (EJob ejob: finishedJobs) {// Job job = ejob.getJob();// if (job != null)// jobsList.add(job);// } for (EJob ejob: startedJobs) { Job job = ejob.getJob(); if (job != null) jobsList.add(job); } for (EJob ejob: waitingJobs) { Job job = ejob.getJob(); if (job != null) jobsList.add(job); } return jobsList.iterator(); } finally { unlock(); } } /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ public void update(Observable o, Object arg) { Thread currentThread = Thread.currentThread(); if (currentThread instanceof EThread) ((EThread)currentThread).print((String)arg); } //--------------------------PRIVATE JOB METHODS-------------------------- private void invokeEThread() { if (signalledEThread || startedJobs.size() >= maxNumThreads) return; if (!canDoIt()) return; if (startedJobs.size() < numThreads) databaseChangesMutex.signal(); else new EThread(numThreads++); signalledEThread = true; }// private EJob selectTerminateIt() {// lock();// try {// for (int i = 0; i < finishedJobs.size(); i++) {// EJob ejob = finishedJobs.get(i);// if (ejob.state == EJob.State.CLIENT_DONE) continue;//// finishedJobs.remove(i);// return ejob;// }// } finally {// unlock();// }// return null;// } void wantUpdateGui() { lock(); try { this.guiChanged = true; } finally { unlock(); } } private boolean guiChanged() { lock(); try { boolean b = this.guiChanged; this.guiChanged = false; return b; } finally { unlock(); } } private boolean canDoIt() { if (waitingJobs.isEmpty()) return false; EJob ejob = waitingJobs.get(0); return startedJobs.isEmpty() || !runningChangeJob && ejob.isExamine(); } private void setEJobState(EJob ejob, EJob.State newState, String info) { Job.logger.logp(Level.FINE, CLASS_NAME, "setEjobState", newState + " "+ ejob.jobName); EJob.State oldState = ejob.state; switch (newState) { case WAITING: break; case RUNNING: if (oldState == EJob.State.RUNNING) { assert oldState == EJob.State.RUNNING; ejob.progress = info; if (info.equals(EJob.ABORTING)) ejob.serverJob.scheduledToAbort = true; } break; case SERVER_DONE: currentSnapshot = ejob.newSnapshot; boolean removed; if (oldState == EJob.State.WAITING) { removed = waitingJobs.remove(ejob); } else { assert oldState == EJob.State.RUNNING; removed = startedJobs.remove(ejob); if (startedJobs.isEmpty()) runningChangeJob = false; } assert removed;// if (Job.threadMode != Job.Mode.BATCH && ejob.client == null)// finishedJobs.add(ejob); break; case CLIENT_DONE: assert oldState == EJob.State.SERVER_DONE;// if (ejob.clientJob.deleteWhenDone)// finishedJobs.remove(ejob); } ejob.state = newState; Client.fireEJobEvent(ejob); if (!Job.BATCHMODE && !guiChanged) SwingUtilities.invokeLater(this); guiChanged = true; Job.logger.exiting(CLASS_NAME, "setJobState"); } private boolean isChangeJobQueuedOrRunning() { lock(); try { for (EJob ejob: startedJobs) { Job job = ejob.getJob(); if (job != null && job.finished) continue; if (ejob.jobType == Job.Type.CHANGE) return true; } for (EJob ejob: waitingJobs) { if (ejob.jobType == Job.Type.CHANGE) return true; } return false; } finally { unlock(); } } public void runLoop() { if (serverSocket == null) return; MessagesStream.getMessagesStream().addObserver(this); try { // Wait for connections for (;;) { Socket socket = serverSocket.accept();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -