blob: bf9ea8ad71a7b7146dbf4bbe19520aa64cb81ce1 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.java2d;
27
28import java.lang.ref.Reference;
29import java.lang.ref.ReferenceQueue;
30import java.lang.ref.PhantomReference;
31import java.lang.ref.WeakReference;
32import java.util.Hashtable;
33
34/**
35 * This class is used for registering and disposing the native
36 * data associated with java objects.
37 *
38 * The object can register itself by calling one of the addRecord
39 * methods and providing either the pointer to the native disposal
40 * method or a descendant of the DisposerRecord class with overridden
41 * dispose() method.
42 *
43 * When the object becomes unreachable, the dispose() method
44 * of the associated DisposerRecord object will be called.
45 *
46 * @see DisposerRecord
47 */
48public class Disposer implements Runnable {
49 private static final ReferenceQueue queue = new ReferenceQueue();
50 private static final Hashtable records = new Hashtable();
51
52 private static Disposer disposerInstance;
53 public static final int WEAK = 0;
54 public static final int PHANTOM = 1;
55 public static int refType = PHANTOM;
56
57 static {
58 java.security.AccessController.doPrivileged(
59 new sun.security.action.LoadLibraryAction("awt"));
60 initIDs();
61 String type = (String) java.security.AccessController.doPrivileged(
62 new sun.security.action.GetPropertyAction("sun.java2d.reftype"));
63 if (type != null) {
64 if (type.equals("weak")) {
65 refType = WEAK;
66 System.err.println("Using WEAK refs");
67 } else {
68 refType = PHANTOM;
69 System.err.println("Using PHANTOM refs");
70 }
71 }
72 disposerInstance = new Disposer();
73 java.security.AccessController.doPrivileged(
74 new java.security.PrivilegedAction() {
75 public Object run() {
76 /* The thread must be a member of a thread group
77 * which will not get GCed before VM exit.
78 * Make its parent the top-level thread group.
79 */
80 ThreadGroup tg = Thread.currentThread().getThreadGroup();
81 for (ThreadGroup tgn = tg;
82 tgn != null;
83 tg = tgn, tgn = tg.getParent());
84 Thread t =
85 new Thread(tg, disposerInstance, "Java2D Disposer");
86 t.setDaemon(true);
87 t.setPriority(Thread.MAX_PRIORITY);
88 t.start();
89 return null;
90 }
91 }
92 );
93 }
94
95 /**
96 * Registers the object and the native data for later disposal.
97 * @param target Object to be registered
98 * @param disposeMethod pointer to the native disposal method
99 * @param pData pointer to the data to be passed to the
100 * native disposal method
101 */
102 public static void addRecord(Object target,
103 long disposeMethod, long pData)
104 {
105 disposerInstance.add(target,
106 new DefaultDisposerRecord(disposeMethod, pData));
107 }
108
109 /**
110 * Registers the object and the native data for later disposal.
111 * @param target Object to be registered
112 * @param rec the associated DisposerRecord object
113 * @see DisposerRecord
114 */
115 public static void addRecord(Object target, DisposerRecord rec) {
116 disposerInstance.add(target, rec);
117 }
118
119 /**
120 * Performs the actual registration of the target object to be disposed.
121 * @param target Object to be registered, or if target is an instance
122 * of DisposerTarget, its associated disposer referent
123 * will be the Object that is registered
124 * @param rec the associated DisposerRecord object
125 * @see DisposerRecord
126 */
127 synchronized void add(Object target, DisposerRecord rec) {
128 if (target instanceof DisposerTarget) {
129 target = ((DisposerTarget)target).getDisposerReferent();
130 }
131 java.lang.ref.Reference ref;
132 if (refType == PHANTOM) {
133 ref = new PhantomReference(target, queue);
134 } else {
135 ref = new WeakReference(target, queue);
136 }
137 records.put(ref, rec);
138 }
139
140 public void run() {
141 while (true) {
142 try {
143 Object obj = queue.remove();
144 ((Reference)obj).clear();
145 DisposerRecord rec = (DisposerRecord)records.remove(obj);
146 rec.dispose();
147 obj = null;
148 rec = null;
149 } catch (Exception e) {
150 System.out.println("Exception while removing reference: " + e);
151 e.printStackTrace();
152 }
153 }
154 }
155
156 private static native void initIDs();
157
158 /*
159 * This was added for use by the 2D font implementation to avoid creation
160 * of an additional disposer thread.
161 * WARNING: this thread class monitors a specific queue, so a reference
162 * added here must have been created with this queue. Failure to do
163 * so will clutter the records hashmap and no one will be cleaning up
164 * the reference queue.
165 */
166 public static void addReference(Reference ref, DisposerRecord rec) {
167 records.put(ref, rec);
168 }
169
170 public static void addObjectRecord(Object obj, DisposerRecord rec) {
171 records.put(new WeakReference(obj, queue) , rec);
172 }
173
174 /* This is intended for use in conjunction with addReference(..)
175 */
176 public static ReferenceQueue getQueue() {
177 return queue;
178 }
179
180}