/* * Copyright (C) 2008 Universidade Federal de Campina Grande * * This file is part of OurGrid. * * OurGrid 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 3 of the License, or (at your option) * any later version. * * This program 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 program. If not, see <http://www.gnu.org/licenses/>. * */ package org.ourgrid.common.executor; import java.util.Map; import java.util.TreeMap; import br.edu.ufcg.lsd.commune.container.logging.CommuneLogger; /** * This class defines an abstraction for the operating system dependent part of * executing commands. The concrete implementors of this class must provide the * correct behavior for executing a command, killing a process and changing the * permissions of files. */ public abstract class AbstractExecutor implements Executor { private static final long serialVersionUID = 33L; /* The processes which results were not collected yet. */ private Map< ExecutorHandle, HandleEntry > commandHandleEntries; /* The current handle of the preparing allocation */ private ExecutorHandle preparingAllocationHandle; /* Logger to store log messages */ private transient final CommuneLogger logger; /* This is the next handle that can be issued. */ private int nextHandle = 0; public AbstractExecutor(CommuneLogger logger) { this.commandHandleEntries = new TreeMap< ExecutorHandle, HandleEntry >(); this.logger = logger; } /* (non-Javadoc) * @see org.ourgrid.common.executor.Executor#prepareAllocation() */ public abstract void prepareAllocation() throws ExecutorException; /* (non-Javadoc) * @see org.ourgrid.common.executor.Executor#finishCommandExecution(org.ourgrid.common.executor.ExecutorHandle) */ public abstract void finishCommandExecution(ExecutorHandle handle) throws ExecutorException; /* (non-Javadoc) * @see org.ourgrid.common.executor.Executor#finishPrepareAllocation() */ public void finishPrepareAllocation() { ExecutorHandle handle = getPreparingAllocatioHandle(); if (handle != null) { removeProcess(handle); } } /* (non-Javadoc) * @see org.ourgrid.common.executor.Executor#killCommand(org.ourgrid.common.executor.ExecutorHandle) */ public void killCommand(ExecutorHandle handle) throws ExecutorException { /* Process to be killed */ Process processToKill; /* Get the process from the initiated execution */ if (handle != null) { processToKill = getProcess( handle ); /* call the method kill for each SO */ if( processToKill != null ) { processToKill.destroy(); } else{ logger.debug( "Command kill for handle " + handle.toString() + " is not necessary because this process is already finished." ); } removeProcess(handle); } } /** * Provides a synchronized access to the Map containing the * Processes. * * @param handle An identificator of the the Process in the Map. * @return An instance of Process identified by the Map. */ protected synchronized Process getProcess(ExecutorHandle handle) { Process process = null; HandleEntry handleEntry = commandHandleEntries.get(handle); if (handleEntry != null) { process = handleEntry.getProcess(); } return process; } /** * Removes a process identified by the handle passed as an argument from the Map containing the * Processes. * * @param handle An identificator of the the Process in the Map. * @return The removed instance of Process. */ protected synchronized Process removeProcess(ExecutorHandle handle) { Process process = null; HandleEntry handleEntry = commandHandleEntries.remove(handle); if (handleEntry != null) { process = handleEntry.getProcess(); } return process; } /** * This method manage the handles issued of the each command execution. * * @return A handle to be used by the client to identify its execution */ protected synchronized ExecutorHandle getNextHandle( ) { IntegerExecutorHandle newHandle = new IntegerExecutorHandle( nextHandle ); this.nextHandle++; return newHandle; } /** * Gets the processes which results were not collected yet. * @return a map containing all processes */ protected Map<ExecutorHandle, HandleEntry> getHandleEntries() { return commandHandleEntries; } /** * Sets the identificator of the current process of the preparing allocation. * @param preparingAllocationHandle the handle of the process */ public void setPreparingAllocationHandle(ExecutorHandle preparingAllocationHandle) { this.preparingAllocationHandle = preparingAllocationHandle; } /** * Adds a identificator for a new process into the map of processes whose results are yet to be collected. * @param handle the process handle * @param entry an entry containing the handle and the process */ public void addHandleEntry(ExecutorHandle handle, HandleEntry entry) { commandHandleEntries.put(handle, entry); } /** * Adds a identificator of the process for preparing allocation. * @param handle the process handle * @param entry an entry containing the handle and the preparing allocation process */ public void addPreparingAllocationEntry(ExecutorHandle handle, HandleEntry entry) { addHandleEntry(handle, entry); setPreparingAllocationHandle(handle); } /** * Returns a logger object used to store logs. * @return the logger object */ public CommuneLogger getLogger() { return logger; } /** * Returns the current handle of the preparing allocation. * @return the current preparing allocation handle */ public ExecutorHandle getPreparingAllocatioHandle() { return preparingAllocationHandle; } }