/* * Copyright (C) 2012, 2016 higherfrequencytrading.com * Copyright (C) 2016 Roman Leventov * * This program 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. * * 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 net.openhft.chronicle.map.ipc; import net.openhft.chronicle.bytes.Byteable; import net.openhft.chronicle.bytes.BytesStore; /** * */ public class StateMachineData implements Byteable { private BytesStore bs; private long offset; /** * c-tor */ public StateMachineData() { this.bs = null; this.offset = -1; } // ************************************************************************* // // ************************************************************************* /** * @param states * @return */ public boolean stateIn(StateMachineState... states) { StateMachineState currentState = getState(); for (StateMachineState state : states) { if (state == currentState) { return true; } } return false; } /** * @param from * @param to */ public boolean setState(StateMachineState from, StateMachineState to) { if (this.bs == null) throw new NullPointerException("Byteable is not set to off heap"); return this.bs.compareAndSwapInt(this.offset, from.value(), to.value()); } /** * @return */ public StateMachineState getState() { if (this.bs == null) throw new NullPointerException("Byteable is not set to off heap"); int value = this.bs.readVolatileInt(this.offset); return StateMachineState.fromValue(value); } /** * @param state */ public void setState(StateMachineState state) { if (this.bs == null) throw new NullPointerException("Byteable is not set to off heap"); this.bs.writeInt(this.offset, state.value()); } /** * Wait for a state and make a transition. * It spins initially (1000 iterations), then uses a Thread.yield() . * * @param from * @param to */ public void waitForState(StateMachineState from, StateMachineState to) { if (this.bs == null) throw new NullPointerException("Byteable is not set to off heap"); // spin for (int i = 0; !setState(from, to); i++) { if (i > 1000) { Thread.yield(); // back off a little. } } } // ************************************************************************* // // ************************************************************************* /** * @return */ public int getStateData() { if (this.bs != null) { return this.bs.readVolatileInt(this.offset + 4); } return -1; } /** * @param data */ public void setStateData(int data) { if (this.bs != null) { this.bs.writeInt(this.offset + 4, data); } } /** * @return */ public int incStateData() { if (this.bs != null) { return this.bs.addAndGetInt(this.offset + 4, 1); } return -1; } /** * @return */ public boolean done() { if (this.bs != null) { return getStateData() > 100; } return true; } // ************************************************************************* // // ************************************************************************* @Override public void bytesStore(BytesStore bytes, long offset, long size) { if (size != 16) throw new IllegalArgumentException(); this.bs = bytes; this.offset = offset; } @Override public BytesStore bytesStore() { return this.bs; } @Override public long offset() { return this.offset; } @Override public long maxSize() { return 16; } }