/*
 * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.java2d;

import java.lang.ref.Reference;

/**
* This ReentrantContextProvider implementation uses a ThreadLocal to hold
 * the first ReentrantContext per thread and a ReentrantContextProviderCLQ to
 * store child ReentrantContext instances needed during recursion.
 *
 * Note: this implementation may keep up to one context in memory per thread.
 * Child contexts for recursive uses are stored in the queue using a WEAK
 * reference by default unless specified in the 2 argument constructor.
 *
 * @param <K> ReentrantContext subclass
 */
public abstract class ReentrantContextProviderTL<K extends ReentrantContext>
    extends ReentrantContextProvider<K>
{
    // Thread-local storage:
    private final ThreadLocal<Reference<K>> ctxTL
        = new ThreadLocal<>();

    // ReentrantContext CLQ provider for child contexts:
    private final ReentrantContextProviderCLQ<K> ctxProviderCLQ;

    /**
     * Create a new ReentrantContext provider using the given reference type
     * among hard, soft or weak.
     * It uses weak reference for the child contexts.
     *
     * @param refType reference type
     */
    public ReentrantContextProviderTL(final int refType) {
        this(refType, REF_WEAK);
    }

    /**
     * Create a new ReentrantContext provider using the given reference types
     * among hard, soft or weak
     *
     * @param refTypeTL reference type used by ThreadLocal
     * @param refTypeCLQ reference type used by ReentrantContextProviderCLQ
     */
    public ReentrantContextProviderTL(final int refTypeTL, final int refTypeCLQ)
    {
        super(refTypeTL);

        final ReentrantContextProviderTL<K> parent = this;

        this.ctxProviderCLQ = new ReentrantContextProviderCLQ<>(refTypeCLQ) {
            @Override
            protected K newContext() {
                return parent.newContext();
            }
        };
    }

    /**
     * Give a ReentrantContext instance for the current thread
     *
     * @return ReentrantContext instance
     */
    @Override
    public final K acquire() {
        K ctx = null;
        final Reference<K> ref = ctxTL.get();
        if (ref != null) {
            ctx = ref.get();
        }
        if (ctx == null) {
            // create a new ReentrantContext if none is available
            ctx = newContext();
            // update thread local reference:
            ctxTL.set(getOrCreateReference(ctx));
        }
        // Check reentrance:
        if (ctx.usage == USAGE_TL_INACTIVE) {
           ctx.usage = USAGE_TL_IN_USE;
        } else {
            // get or create another ReentrantContext from CLQ provider:
            ctx = ctxProviderCLQ.acquire();
        }
        return ctx;
    }

    /**
     * Restore the given ReentrantContext instance for reuse
     *
     * @param ctx ReentrantContext instance
     */
    @Override
    public final void release(final K ctx) {
        if (ctx.usage == USAGE_TL_IN_USE) {
           ctx.usage = USAGE_TL_INACTIVE;
        } else {
            ctxProviderCLQ.release(ctx);
        }
    }
}
