/* Copyright 2009-2016 David Hadka * * This file is part of the MOEA Framework. * * The MOEA Framework 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. * * The MOEA Framework 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 the MOEA Framework. If not, see <http://www.gnu.org/licenses/>. */ package org.moeaframework.algorithm.pisa; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import org.moeaframework.core.Settings; /** * Reads and writes PISA state files. */ public class State { /** * The state file. */ private final File file; /** * The delay in milliseconds between successive reads of the state file. */ private static final long pollRate = Settings.getPISAPollRate(); /** * The number of times this class will attempt to write to the state file * until propagating the error. Failures primarily result from PISA * selectors locking the state file. */ private static final int numberOfRetries = 5; /** * Constructs a state indicator backed by the specified file. * * @param file the state file */ public State(File file) { super(); this.file = file; } /** * Reads the state. * * @return the state * @throws IOException if an I/O error occurred */ public int get() throws IOException { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); String line = reader.readLine(); if (line == null) { return -1; } else { return Integer.parseInt(line); } } finally { if (reader != null) { reader.close(); } } } /** * Sets the state. * * @param state the state * @throws IOException if an I/O error occurred * @throws InterruptedException if {@link Thread#sleep(long)} was * interrupted */ public void set(int state) throws IOException, InterruptedException { PrintWriter writer = null; int retriesRemaining = numberOfRetries; while (true) { try { writer = new PrintWriter(new FileWriter(file)); writer.print(state); break; } catch (IOException e) { retriesRemaining--; if (retriesRemaining <= 0) { throw e; } } finally { if (writer != null) { writer.close(); } } Thread.sleep(pollRate); } } /** * Blocks until the state becomes the specified value. * * @param state the state to wait for * @throws IOException if an I/O error occurred * @throws InterruptedException if {@link Thread#sleep(long)} was * interrupted */ public void waitFor(int state) throws IOException, InterruptedException { while (!file.exists() || (get() != state)) { Thread.sleep(pollRate); } } /** * Blocks while the state remains at the specified value, returning the * new state value when it changes. * * @param state the state to wait on * @return the new state * @throws IOException if an I/O error occurred * @throws InterruptedException if {@link Thread#sleep(long)} was * interrupted */ public int waitWhile(int state) throws IOException, InterruptedException { int current; do { Thread.sleep(pollRate); } while (!file.exists() || ((current = get()) == state)); return current; } }