// 
// Decompiled by Procyon v0.6.0
// 

package io.sentry.transport;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.TimeUnit;
import org.jetbrains.annotations.NotNull;

public final class ReusableCountLatch
{
    @NotNull
    private final Sync sync;
    
    public ReusableCountLatch(final int initialCount) {
        if (initialCount < 0) {
            throw new IllegalArgumentException("negative initial count '" + initialCount + "' is not allowed");
        }
        this.sync = new Sync(initialCount);
    }
    
    public ReusableCountLatch() {
        this(0);
    }
    
    public int getCount() {
        return this.sync.getCount();
    }
    
    public void decrement() {
        this.sync.decrement();
    }
    
    public void increment() {
        this.sync.increment();
    }
    
    public void waitTillZero() throws InterruptedException {
        this.sync.acquireSharedInterruptibly(1);
    }
    
    public boolean waitTillZero(final long timeout, @NotNull final TimeUnit unit) throws InterruptedException {
        return this.sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }
    
    private static final class Sync extends AbstractQueuedSynchronizer
    {
        private static final long serialVersionUID = 5970133580157457018L;
        
        Sync(final int count) {
            this.setState(count);
        }
        
        private int getCount() {
            return this.getState();
        }
        
        private void increment() {
            int oldCount;
            int newCount;
            do {
                oldCount = this.getState();
                newCount = oldCount + 1;
            } while (!this.compareAndSetState(oldCount, newCount));
        }
        
        private void decrement() {
            this.releaseShared(1);
        }
        
        public int tryAcquireShared(final int acquires) {
            return (this.getState() == 0) ? 1 : -1;
        }
        
        public boolean tryReleaseShared(final int releases) {
            while (true) {
                final int oldCount = this.getState();
                if (oldCount == 0) {
                    return false;
                }
                final int newCount = oldCount - 1;
                if (this.compareAndSetState(oldCount, newCount)) {
                    return newCount == 0;
                }
            }
        }
    }
}
