Package org.jmol.script

Source Code of org.jmol.script.ParallelProcessor$Process

/* $Author: hansonr $
* $Date: 2010-04-22 13:16:44 -0500 (Thu, 22 Apr 2010) $
* $Revision: 12904 $
*
* Copyright (C) 2002-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library 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
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package org.jmol.script;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.jmol.util.Logger;
import org.jmol.viewer.ShapeManager;
import org.jmol.viewer.Viewer;

public class ParallelProcessor extends ScriptFunction {

 
  ParallelProcessor(String name, int tok) {
    super(name, tok);
  }

  public static Object getExecutor() {
    return Executors.newCachedThreadPool();
  }
 
  /**
   * the idea here is that the process { ... } command would collect and
   * preprocess the scripts, then pass them here for storage until the end of
   * the parallel block is reached.
   */

  static class Process {
    String processName;
    ScriptContext context;

    Process(String name, ScriptContext context) {
      //System.out.println("Creating process " + name);
      processName = name;
      this.context = context;
    }
  }

  Viewer viewer;
  volatile List vShapeManagers = null;
  volatile int counter = 0;
  volatile Error error = null;
  Object lock = new Object() ;
 
  public void runAllProcesses(Viewer viewer, boolean inParallel) {
    if (processes.size() == 0)
      return;
    this.viewer = viewer;
    boolean allowParallel = inParallel && !viewer.isParallel() && viewer.setParallel(true);
    vShapeManagers = new ArrayList();
    error = null;
    counter = 0;
    if (Logger.debugging)
      Logger.debug("running " + processes.size() + " processes on "
          + Viewer.nProcessors + " processesors");

    counter = processes.size();
    for (int i = processes.size(); --i >= 0;) {
      runProcess((Process) processes.remove(0), allowParallel);
    }

    synchronized (lock) {
      while (counter > 0) {
        try {
          lock.wait();
        } catch (InterruptedException e) {
        }
        if (error != null)
          throw error;
      }
    }
    mergeResults();
    viewer.setParallel(false);
  }

  void mergeResults() {
    try {
      for (int i = 0; i < vShapeManagers.size(); i++)
        viewer.mergeShapes(((ShapeManager) vShapeManagers.get(i)).getShapes());
    } catch (Error e) {
      throw e;
    } finally {
      counter = -1;
      vShapeManagers = null;
    }
  }

  void clearShapeManager(Error er) {
    synchronized (this) {
      this.error = er;
      vShapeManagers = null;
      this.notifyAll();
    }
  }

  List processes = new ArrayList();

  void addProcess(String name, ScriptContext context) {
    processes.add(new Process(name, context));
  }

  class RunProcess implements Runnable {
    Process process;
    Object processLock;
    boolean inParallel;
   
    public RunProcess(Process process, Object lock, boolean inParallel) {
      this.process = process;
      processLock = lock;
      this.inParallel = inParallel;
    }

    public void run() {
      try {
        if (error == null) {
          if (Logger.debugging)
            Logger.debug("Running process " + process.processName + " "
                + process.context.pc + " - " + (process.context.pcEnd - 1));
          ShapeManager shapeManager = null;
          if (inParallel) {
            shapeManager = new ShapeManager(viewer, viewer.getModelSet());
            vShapeManagers.add(shapeManager);
          }
          viewer.eval(process.context, shapeManager);
          if (Logger.debugging)
            Logger.debug("Process " + process.processName + " complete");
        }
      } catch (Exception e) {
        if (tok != Token.trycmd)
          e.printStackTrace();
      } catch (Error er) {
        clearShapeManager(er);
      } finally {
        synchronized (processLock) {
          --counter;
          processLock.notifyAll();
        }
      }
    }
  }

  private void runProcess(final Process process, boolean allowParallel) {
    RunProcess r = new RunProcess(process, lock, allowParallel);
    Executor exec = (allowParallel ? (Executor) viewer.getExecutor() : null);
    if (exec != null) {
      exec.execute(r);
    } else {
      r.run();
    }
  }
}
TOP

Related Classes of org.jmol.script.ParallelProcessor$Process

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.