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

org.bouncycastle.util.dispose.DisposalDaemon Maven / Gradle / Ivy

Go to download

The Long Term Stable (LTS) Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains the JCA/JCE provider and low-level API for the BC LTS version 2.73.7 for Java 8 and later.

There is a newer version: 2.73.7
Show newest version
package org.bouncycastle.util.dispose;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DisposalDaemon
        implements Runnable
{
    private static final Logger LOG = Logger.getLogger(DisposalDaemon.class.getName());

    private static ReferenceQueue referenceQueue = new ReferenceQueue();

    private static Set refs =
            Collections.synchronizedSet(new HashSet());

    private static AtomicLong ctr = new AtomicLong(Long.MIN_VALUE);

    private static final DisposalDaemon disposalDaemon = new DisposalDaemon();
    private static final Thread disposalThread;

    static
    {
        //
        // Sets up the daemon thread that deals with items on the reference
        // queue that may have native code that needs disposing.
        //
        disposalThread = new Thread(disposalDaemon, "BC Disposal Daemon");
        disposalThread.setDaemon(true);
        disposalThread.start();

        addShutdownHook();
    }

    private static void addShutdownHook()
    {
        //
        // On shutdown clean up the reference queue.
        //
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                if (LOG.isLoggable(Level.FINE))
                {
                    LOG.fine("Shutdown hook started");
                }
                ReferenceWrapperWithDisposerRunnable item =
                        (ReferenceWrapperWithDisposerRunnable) referenceQueue.poll();
                while (item != null)
                {
                    refs.remove(item);
                    item.dispose();
                    item = (ReferenceWrapperWithDisposerRunnable) referenceQueue.poll();

                    if (LOG.isLoggable(Level.FINE))
                    {
                        LOG.fine("Shutdown hook disposed: " + item);
                    }
                }

            }
        });
    }

    public static void addDisposable(Disposable disposable)
    {
        ReferenceWrapperWithDisposerRunnable ref = new ReferenceWrapperWithDisposerRunnable(disposable, referenceQueue);
        refs.add(ref);
        if (LOG.isLoggable(Level.FINE))
        {
            LOG.fine("Registered: " + disposable.toString());
        }
    }

    public void run()
    {
        for (; ; )
        {
            try
            {
                ReferenceWrapperWithDisposerRunnable item =
                        (ReferenceWrapperWithDisposerRunnable) referenceQueue.remove();
                refs.remove(item);
                item.dispose();
                if (LOG.isLoggable(Level.FINE))
                {
                    LOG.fine("Disposed: " + item);
                }
            }
            catch (InterruptedException iex)
            {
                Thread.currentThread().interrupt();
            }
            catch (Throwable e)
            {
                LOG.warning("exception in disposal thread: " + e.getMessage());
            }
        }
    }

    private static class ReferenceWrapperWithDisposerRunnable
            extends PhantomReference
    {

        private final Runnable disposer;
        private final String label;

        /**
         * Creates a new phantom reference that refers to the given object and
         * is registered with the given queue.
         *
         * 

It is possible to create a phantom reference with a null * queue, but such a reference is completely useless: Its get * method will always return null and, since it does not have a queue, it * will never be enqueued. * * @param referent the object the new phantom reference will refer to * @param q the queue with which the reference is to be registered, * or null if registration is not required */ public ReferenceWrapperWithDisposerRunnable(Disposable referent, ReferenceQueue q) { super(referent, q); this.label = referent.toString(); // capture label from referent this.disposer = referent.getDisposeAction(); } public void dispose() { disposer.run(); } public String toString() { return label; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy