/* * This file is part of Mixin, licensed under the MIT License (MIT). * * Copyright (c) SpongePowered * Copyright (c) contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.spongepowered.asm.util; /** * Re-entrance semaphore used to share re-entrance data with the metadata * service */ public class ReEntranceLock { /** * Max valid depth */ private final int maxDepth; /** * Re-entrance depth */ private int depth = 0; /** * Semaphore set when check exceeds a depth of 1 */ private boolean semaphore = false; public ReEntranceLock(int maxDepth) { this.maxDepth = maxDepth; } /** * Get max depth */ public int getMaxDepth() { return this.maxDepth; } /** * Get current depth */ public int getDepth() { return this.depth; } /** * Increase the re-entrance depth counter and set the semaphore if depth * exceeds max depth * * @return fluent interface */ public ReEntranceLock push() { this.depth++; this.checkAndSet(); return this; } /** * Decrease the re-entrance depth * * @return fluent interface */ public ReEntranceLock pop() { if (this.depth == 0) { throw new IllegalStateException("ReEntranceLock pop() with zero depth"); } this.depth--; return this; } /** * Run the depth check but do not set the semaphore * * @return true if depth has exceeded max */ public boolean check() { return this.depth > this.maxDepth; } /** * Run the depth check and set the semaphore if depth is exceeded * * @return true if semaphore is set */ public boolean checkAndSet() { return this.semaphore |= this.check(); } /** * Set the semaphore * * @return fluent interface */ public ReEntranceLock set() { this.semaphore = true; return this; } /** * Get whether the semaphore is set */ public boolean isSet() { return this.semaphore; } /** * Clear the semaphore * * @return fluent interface */ public ReEntranceLock clear() { this.semaphore = false; return this; } }