ICURWLock.java 4.71 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.agl.impl;

public class ICURWLock {
    private Object writeLock = new Object();
    private Object readLock = new Object();
    private int wwc;
    private int rc;
    private int wrc;
    private Stats stats = new Stats();

    private synchronized boolean gotRead() {
        ++this.rc;
        if (this.stats != null) {
            ++this.stats._rc;
            if (this.rc > 1) {
                ++this.stats._mrc;
            }
        }
        return true;
    }

    private synchronized boolean getRead() {
        if (this.rc >= 0 && this.wwc == 0) {
            return this.gotRead();
        }
        ++this.wrc;
        return false;
    }

    private synchronized boolean retryRead() {
        if (this.stats != null) {
            ++this.stats._wrc;
        }
        if (this.rc >= 0 && this.wwc == 0) {
            --this.wrc;
            return this.gotRead();
        }
        return false;
    }

    private synchronized boolean finishRead() {
        if (this.rc > 0) {
            return 0 == --this.rc && this.wwc > 0;
        }
        throw new IllegalStateException("no current reader to release");
    }

    private synchronized boolean gotWrite() {
        this.rc = -1;
        if (this.stats != null) {
            ++this.stats._wc;
        }
        return true;
    }

    private synchronized boolean getWrite() {
        if (this.rc == 0) {
            return this.gotWrite();
        }
        ++this.wwc;
        return false;
    }

    private synchronized boolean retryWrite() {
        if (this.stats != null) {
            ++this.stats._wwc;
        }
        if (this.rc == 0) {
            --this.wwc;
            return this.gotWrite();
        }
        return false;
    }

    private synchronized int finishWrite() {
        if (this.rc < 0) {
            this.rc = 0;
            if (this.wwc > 0) {
                return 1;
            }
            if (this.wrc > 0) {
                return 2;
            }
            return 0;
        }
        throw new IllegalStateException("no current writer to release");
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void acquireRead() {
        if (!this.getRead()) {
            do {
                try {
                    do {
                        Object object = this.readLock;
                        synchronized (object) {
                            this.readLock.wait();
                            continue;
                        }
                    } while (!this.retryRead());
                    return;
                }
                catch (InterruptedException e) {
                    continue;
                }
                break;
            } while (true);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void releaseRead() {
        if (this.finishRead()) {
            Object object = this.writeLock;
            synchronized (object) {
                this.writeLock.notify();
            }
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void acquireWrite() {
        if (!this.getWrite()) {
            do {
                try {
                    do {
                        Object object = this.writeLock;
                        synchronized (object) {
                            this.writeLock.wait();
                            continue;
                        }
                    } while (!this.retryWrite());
                    return;
                }
                catch (InterruptedException e) {
                    continue;
                }
                break;
            } while (true);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void releaseWrite() {
        switch (this.finishWrite()) {
            case 1: {
                Object object = this.writeLock;
                synchronized (object) {
                    this.writeLock.notify();
                    break;
                }
            }
            case 2: {
                Object object = this.readLock;
                synchronized (object) {
                    this.readLock.notifyAll();
                    break;
                }
            }
        }
    }

    public static final class Stats {
        public int _rc;
        public int _mrc;
        public int _wrc;
        public int _wc;
        public int _wwc;

        private Stats() {
        }

        public String toString() {
            return " rc: " + this._rc + " mrc: " + this._mrc + " wrc: " + this._wrc + " wc: " + this._wc + " wwc: " + this._wwc;
        }
    }

}