/******************************************************************************* * Copyright (c) 2006, 2011 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Intel Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.buildmodel; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; /** * This class implements process pool management for internal builder */ public class BuildProcessManager { protected OutputStream out; protected OutputStream err; protected boolean show; protected Vector<ProcessLauncher> processes; protected int maxProcesses; /** * Initializes process manager * * @param _out Output stream * @param _err Error output stream * @param _show If true, print command line before launching */ public BuildProcessManager(OutputStream _out, OutputStream _err, boolean _show, int _procNumber) { out = _out; err = _err; show = _show; maxProcesses = _procNumber; processes = new Vector<ProcessLauncher>(Math.min(10, maxProcesses), 10); } /** * Returns maximum number of processes */ public int getMaxProcesses() { return maxProcesses; } /** * Performs an attempt to launch new process. Returns BuildProcessLauncher * if it was successfully launched, null if there is no room for it yet in * the process pool. * * @param cmd Command to launch * @param cwd Command working directory * @param monitor Progress monitor for this task */ public ProcessLauncher launchProcess(IBuildCommand cmd, IPath cwd, IProgressMonitor monitor) { for (int i = 0; i < maxProcesses; i++) { if (i >= processes.size()) { ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); processes.add(process); process.launch(); return process; } if (processes.get(i).queryState() == ProcessLauncher.STATE_DONE) { ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); processes.set(i, process); process.launch(); return process; } } return null; } /** * Checks states of all currently running processes. If it finds * one with state other than STATE_DONE or STATE_RUNNING, it is * returned as a result. Otherwise this method returns null. */ public ProcessLauncher queryStates() { for (ProcessLauncher process : processes) { int state = process.queryState(); if (state != ProcessLauncher.STATE_RUNNING && state != ProcessLauncher.STATE_DONE) return process; } return null; } /** * Checks states of all currently running processes. */ public boolean hasEmpty() { if (processes.size() < maxProcesses) return true; for (ProcessLauncher process : processes) { if (process.queryState() != ProcessLauncher.STATE_RUNNING) return true; } return false; } /** * Returns maximum threads used up to that point */ public int getThreadsUsed() { return processes.size(); } /** * Converts map to strings array */ protected String[] mapToStringArray(Map<String, String> map){ if(map == null) return null; List<String> list = new ArrayList<String>(); Set<Entry<String, String>> entrySet = map.entrySet(); for (Entry<String, String> entry : entrySet) { list.add(entry.getKey() + '=' + entry.getValue()); } return list.toArray(new String[list.size()]); } /** * @return Number of processors detected * @deprecated since CDT 9.0 - just use Runtime.getRuntime().availableProcessors() */ @Deprecated static public int checkCPUNumber() { return Runtime.getRuntime().availableProcessors(); } }