/* * This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com> * Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/) */ /* * @(#)Disposer.java 1.4 03/03/19 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package sun.java2d; import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference; import java.lang.ref.WeakReference; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Hashtable; /** * This class is used for registering and disposing the native * data associated with java objects. * * The object can register itself by calling one of the addRecord * methods and providing either the pointer to the native disposal * method or 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 class Disposer implements Runnable { private static final ReferenceQueue queue = new ReferenceQueue(); private static final Hashtable records = new Hashtable(); public static final int WEAK = 0; public static final int PHANTOM = 1; public static int refType = PHANTOM; static { AccessController.doPrivileged( new sun.security.action.LoadLibraryAction("awt")); initIDs(); String type = (String) AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.java2d.reftype")); if (type != null) { if (type.equals("weak")) { refType = WEAK; System.out.println("Disposer: using WEAK refs"); } else { System.out.println("Disposer: using PHANTOM refs"); } } } private static final Disposer disposerInstance = new Disposer(); static { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tg2 = tg; tg2 != null; tg2 = tg.getParent()) tg = tg2; Thread t = new Thread(tg, disposerInstance, "Java2D Disposer"); t.setDaemon(true); t.setPriority(Thread.MAX_PRIORITY); t.start(); return null; } }); } /** * Registers the object and the native data for later disposal. * @param obj Object to be registered * @param disposeMethod pointer to the native disposal method * @param pData pointer to the data to be passed to the * native disposal method */ public static void addRecord(DisposerTarget target, long disposeMethod, long pData) { disposerInstance.add(target, new DefaultDisposerRecord(disposeMethod, pData)); } /** * Registers the object and the native data for later disposal. * @param obj Object to be registered * @param rec The assosicated DisposerRecord class * @see DisposerRecord */ public static void addRecord(DisposerTarget target, DisposerRecord rec) { disposerInstance.add(target, rec); } public static void addRecord(Object target, DisposerRecord rec) { disposerInstance.add(target, rec); } synchronized void add(Object target, DisposerRecord rec) { DisposerTarget disposerTarget = null; if (target instanceof DisposerTarget) { disposerTarget = (DisposerTarget)target; target = disposerTarget.getDisposerReferent(); } java.lang.ref.Reference ref; if (refType == PHANTOM) { ref = new PhantomReference(target, queue); } else { ref = new WeakReference(target, queue); } records.put(ref, rec); /* store the disposer record for later use */ if (disposerTarget != null) { disposerTarget.setDisposerRecord(rec); } } public void run() { while (true) { try { java.lang.ref.Reference obj = queue.remove(); DisposerRecord rec = (DisposerRecord)records.remove(obj); rec.dispose(); obj = null; rec = null; } catch (Exception e) { System.out.println("Exception while removing reference: " + e); e.printStackTrace(); } } } private static native void initIDs(); }