/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package java.lang.ref;

import android.compat.annotation.UnsupportedAppUsage;
import dalvik.annotation.optimization.FastNative;

/**
 * @hide
 */
public final class FinalizerReference<T> extends Reference<T> {
    // This queue contains those objects eligible for finalization.
    @UnsupportedAppUsage
    public static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();

    // Guards the list (not the queue).
    private static final Object LIST_LOCK = new Object();

    // This list contains a FinalizerReference for every finalizable object in the heap.
    // Objects in this list may or may not be eligible for finalization yet.
    @UnsupportedAppUsage
    private static FinalizerReference<?> head = null;

    // The links used to construct the list.
    private FinalizerReference<?> prev;
    @UnsupportedAppUsage
    private FinalizerReference<?> next;

    // When the GC wants something finalized, it moves it from the 'referent' field to
    // the 'zombie' field instead.
    private T zombie;

    public FinalizerReference(T r, ReferenceQueue<? super T> q) {
        super(r, q);
    }

    @Override public T get() {
        return zombie;
    }

    @Override public void clear() {
        zombie = null;
    }

    @UnsupportedAppUsage
    public static void add(Object referent) {
        FinalizerReference<?> reference = new FinalizerReference<Object>(referent, queue);
        synchronized (LIST_LOCK) {
            reference.prev = null;
            reference.next = head;
            if (head != null) {
                head.prev = reference;
            }
            head = reference;
        }
    }

    @UnsupportedAppUsage
    public static void remove(FinalizerReference<?> reference) {
        synchronized (LIST_LOCK) {
            FinalizerReference<?> next = reference.next;
            FinalizerReference<?> prev = reference.prev;
            reference.next = null;
            reference.prev = null;
            if (prev != null) {
                prev.next = next;
            } else {
                head = next;
            }
            if (next != null) {
                next.prev = prev;
            }
        }
    }

    /**
     * Waits for all currently-enqueued references to be finalized.
     */
    public static void finalizeAllEnqueued(long timeout) throws InterruptedException {
        // Alloate a new sentinel, this creates a FinalizerReference.
        Sentinel sentinel;
        // Keep looping until we safely enqueue our sentinel FinalizerReference.
        // This is done to prevent races where the GC updates the pendingNext
        // before we get the chance.
        do {
            sentinel = new Sentinel();
        } while (!enqueueSentinelReference(sentinel));
        sentinel.awaitFinalization(timeout);
    }

    private static boolean enqueueSentinelReference(Sentinel sentinel) {
        synchronized (LIST_LOCK) {
            // When a finalizable object is allocated, a FinalizerReference is added to the list.
            // We search the list for that FinalizerReference (it should be at or near the head),
            // and then put it on the queue so that it can be finalized.
            for (FinalizerReference<?> r = head; r != null; r = r.next) {
                // Use getReferent() instead of directly accessing the referent field not to race
                // with GC reference processing. Can't use get() either because it's overridden to
                // return the zombie.
                if (r.getReferent() == sentinel) {
                    FinalizerReference<Sentinel> sentinelReference = (FinalizerReference<Sentinel>) r;
                    sentinelReference.clearReferent();
                    sentinelReference.zombie = sentinel;
                    // Make a single element list, then enqueue the reference on the daemon unenqueued
                    // list. This is required instead of enqueuing directly on the finalizer queue
                    // since there could be recently freed objects in the unqueued list which are not
                    // yet on the finalizer queue. This could cause the sentinel to run before the
                    // objects are finalized. b/17381967
                    // Make circular list if unenqueued goes through native so that we can prevent
                    // races where the GC updates the pendingNext before we do. If it is non null, then
                    // we update the pending next to make a circular list while holding a lock.
                    // b/17462553
                    if (!sentinelReference.makeCircularListIfUnenqueued()) {
                        return false;
                    }
                    ReferenceQueue.add(sentinelReference);
                    return true;
                }
            }
        }
        // We just created a finalizable object and still hold a reference to it.
        // It must be on the list.
        throw new AssertionError("newly-created live Sentinel not on list!");
    }

    @FastNative
    private final native T getReferent();
    @FastNative
    private native boolean makeCircularListIfUnenqueued();

    /**
     * A marker object that we can immediately enqueue. When this object's
     * finalize() method is called, we know all previously-enqueued finalizable
     * references have been finalized.
     */
    private static class Sentinel {
        boolean finalized = false;

        @Override protected synchronized void finalize() throws Throwable {
            if (finalized) {
                throw new AssertionError();
            }
            finalized = true;
            notifyAll();
        }

        synchronized void awaitFinalization(long timeout) throws InterruptedException {
            final long startTime = System.nanoTime();
            final long endTime = startTime + timeout;  // May wrap.
            while (!finalized) {
                // 0 signifies no timeout.
                if (timeout != 0) {
                    final long deltaTime = endTime - System.nanoTime();
                    if (deltaTime <= 0) {
                        break;
                    } else {
                        wait(deltaTime / 1_000_000, (int)(deltaTime % 1_000_000));
                    }
                } else {
                    wait();
                }
            }
        }
    }
}
