All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webkit.Disposer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 */
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.sun.webkit;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * This class is used for registering and disposing the native
 * data associated with java objects.
 *
 * The object can register itself by calling the addRecord method and
 * providing a descendant of the DisposerRecord class with overridden
 * dispose() method.
 *
 * When the object becomes unreachable, the dispose() method
 * of the associated DisposerRecord object will be called.
 *
 * @see DisposerRecord
 */
public final class Disposer implements Runnable {
    private static final ReferenceQueue queue = new ReferenceQueue();
    private static final Disposer disposerInstance = new Disposer();
    private static final Set records =
            new HashSet();

    static {
        Thread t = new Thread(disposerInstance, "Disposer");
        t.setDaemon(true);
        t.setPriority(Thread.MAX_PRIORITY);
        t.start();
    }

    /**
     * Registers the object and the native data for later disposal.
     * @param target Object to be registered
     * @param rec the associated DisposerRecord object
     * @see DisposerRecord
     */
    public static void addRecord(Object target, DisposerRecord rec) {
        disposerInstance.add(target, rec);
    }

    /**
     * Performs the actual registration of the target object to be disposed.
     * @param target Object to be registered
     * @param rec the associated DisposerRecord object
     * @see DisposerRecord
     */
    private synchronized void add(Object target, DisposerRecord rec) {
        records.add(new WeakDisposerRecord(target, rec));
    }

    public void run() {
        while (true) {
            try {
                WeakDisposerRecord obj = (WeakDisposerRecord) queue.remove();
                obj.clear();
                DisposerRunnable.getInstance().enqueue(obj);
            } catch (Exception e) {
                System.out.println("Exception while removing reference: " + e);
                e.printStackTrace();
            }
        }
    }

    private static final class DisposerRunnable implements Runnable {
        private static final DisposerRunnable theInstance = new DisposerRunnable();

        private static DisposerRunnable getInstance() {
            return theInstance;
        }

        private boolean isRunning = false;
        private final Object disposerLock = new Object();
        private final LinkedBlockingQueue disposerQueue
                = new LinkedBlockingQueue();

        private void enqueueAll(Collection objs) {
            synchronized (disposerLock) {
                disposerQueue.addAll(objs);
                if (!isRunning) {
                    Invoker.getInvoker().invokeOnEventThread(this);
                    isRunning = true;
                }
            }
        }

        private void enqueue(WeakDisposerRecord obj) {
            enqueueAll(Arrays.asList(obj));
        }

        @Override public void run() {
            while (true) {
                WeakDisposerRecord obj;
                synchronized (disposerLock) {
                    obj = disposerQueue.poll();
                    if (obj == null) {
                        isRunning = false;
                        break;
                    }
                }
                // Check if the object has not yet been removed & disposed.
                if (records.contains(obj)) {
                    records.remove(obj);
                    obj.dispose();
                }
            }
        }
    }

    public static class WeakDisposerRecord
        extends WeakReference
        implements DisposerRecord
    {
        protected WeakDisposerRecord(Object referent) {
            super(referent, Disposer.queue);
            this.record = null;
        }

        private WeakDisposerRecord(Object referent, DisposerRecord record) {
            super(referent, Disposer.queue);
            this.record = record;
        }

        private final DisposerRecord record;

        @Override
        public void dispose() {
            record.dispose();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy