History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/Disposer.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/Disposer.java+262−0
@@ -0,0 +1,262 @@
1+/*
2+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. 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. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.java2d;
27+
28+import java.lang.ref.Reference;
29+import java.lang.ref.ReferenceQueue;
30+import java.lang.ref.PhantomReference;
31+import java.lang.ref.WeakReference;
32+import java.util.ArrayList;
33+import java.util.Hashtable;
34+
35+/**
36+ * This class is used for registering and disposing the native
37+ * data associated with java objects.
38+ *
39+ * The object can register itself by calling one of the addRecord
40+ * methods and providing either the pointer to the native disposal
41+ * method or a descendant of the DisposerRecord class with overridden
42+ * dispose() method.
43+ *
44+ * When the object becomes unreachable, the dispose() method
45+ * of the associated DisposerRecord object will be called.
46+ *
47+ * @see DisposerRecord
48+ */
49+public class Disposer implements Runnable {
50+ private static final ReferenceQueue queue = new ReferenceQueue();
51+ private static final Hashtable records = new Hashtable();
52+
53+ private static Disposer disposerInstance;
54+ public static final int WEAK = 0;
55+ public static final int PHANTOM = 1;
56+ public static int refType = PHANTOM;
57+
58+ static {
59+ java.security.AccessController.doPrivileged(
60+ new sun.security.action.LoadLibraryAction("awt"));
61+ initIDs();
62+ String type = (String) java.security.AccessController.doPrivileged(
63+ new sun.security.action.GetPropertyAction("sun.java2d.reftype"));
64+ if (type != null) {
65+ if (type.equals("weak")) {
66+ refType = WEAK;
67+ System.err.println("Using WEAK refs");
68+ } else {
69+ refType = PHANTOM;
70+ System.err.println("Using PHANTOM refs");
71+ }
72+ }
73+ disposerInstance = new Disposer();
74+ java.security.AccessController.doPrivileged(
75+ new java.security.PrivilegedAction() {
76+ public Object run() {
77+ /* The thread must be a member of a thread group
78+ * which will not get GCed before VM exit.
79+ * Make its parent the top-level thread group.
80+ */
81+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
82+ for (ThreadGroup tgn = tg;
83+ tgn != null;
84+ tg = tgn, tgn = tg.getParent());
85+ Thread t =
86+ new Thread(tg, disposerInstance, "Java2D Disposer");
87+ t.setContextClassLoader(null);
88+ t.setDaemon(true);
89+ t.setPriority(Thread.MAX_PRIORITY);
90+ t.start();
91+ return null;
92+ }
93+ }
94+ );
95+ }
96+
97+ /**
98+ * Registers the object and the native data for later disposal.
99+ * @param target Object to be registered
100+ * @param disposeMethod pointer to the native disposal method
101+ * @param pData pointer to the data to be passed to the
102+ * native disposal method
103+ */
104+ public static void addRecord(Object target,
105+ long disposeMethod, long pData)
106+ {
107+ disposerInstance.add(target,
108+ new DefaultDisposerRecord(disposeMethod, pData));
109+ }
110+
111+ /**
112+ * Registers the object and the native data for later disposal.
113+ * @param target Object to be registered
114+ * @param rec the associated DisposerRecord object
115+ * @see DisposerRecord
116+ */
117+ public static void addRecord(Object target, DisposerRecord rec) {
118+ disposerInstance.add(target, rec);
119+ }
120+
121+ /**
122+ * Performs the actual registration of the target object to be disposed.
123+ * @param target Object to be registered, or if target is an instance
124+ * of DisposerTarget, its associated disposer referent
125+ * will be the Object that is registered
126+ * @param rec the associated DisposerRecord object
127+ * @see DisposerRecord
128+ */
129+ synchronized void add(Object target, DisposerRecord rec) {
130+ if (target instanceof DisposerTarget) {
131+ target = ((DisposerTarget)target).getDisposerReferent();
132+ }
133+ java.lang.ref.Reference ref;
134+ if (refType == PHANTOM) {
135+ ref = new PhantomReference(target, queue);
136+ } else {
137+ ref = new WeakReference(target, queue);
138+ }
139+ records.put(ref, rec);
140+ }
141+
142+ public void run() {
143+ while (true) {
144+ try {
145+ Object obj = queue.remove();
146+ ((Reference)obj).clear();
147+ DisposerRecord rec = (DisposerRecord)records.remove(obj);
148+ rec.dispose();
149+ obj = null;
150+ rec = null;
151+ clearDeferredRecords();
152+ } catch (Exception e) {
153+ System.out.println("Exception while removing reference: " + e);
154+ e.printStackTrace();
155+ }
156+ }
157+ }
158+
159+ /*
160+ * This is a marker interface that, if implemented, means it
161+ * doesn't acquire any special locks, and is safe to
162+ * be disposed in the poll loop on whatever thread
163+ * which happens to be the Toolkit thread, is in use.
164+ */
165+ public static interface PollDisposable {
166+ };
167+
168+ private static ArrayList<DisposerRecord> deferredRecords = null;
169+
170+ private static void clearDeferredRecords() {
171+ if (deferredRecords == null || deferredRecords.isEmpty()) {
172+ return;
173+ }
174+ for (int i=0;i<deferredRecords.size(); i++) {
175+ try {
176+ DisposerRecord rec = deferredRecords.get(i);
177+ rec.dispose();
178+ } catch (Exception e) {
179+ System.out.println("Exception while disposing deferred rec.");
180+ e.printStackTrace();
181+ }
182+ }
183+ deferredRecords.clear();
184+ }
185+
186+ /*
187+ * Set to indicate the queue is presently being polled.
188+ */
189+ public static volatile boolean pollingQueue = false;
190+
191+ /*
192+ * The pollRemove() method is called back from a dispose method
193+ * that is running on the toolkit thread and wants to
194+ * dispose any pending refs that are safe to be disposed
195+ * on that thread.
196+ */
197+ public static void pollRemove() {
198+
199+ /* This should never be called recursively, so this check
200+ * is just a safeguard against the unexpected.
201+ */
202+ if (pollingQueue) {
203+ return;
204+ }
205+ Object obj;
206+ pollingQueue = true;
207+ int freed = 0;
208+ int deferred = 0;
209+ try {
210+ while ((obj = queue.poll()) != null
211+ && freed < 10000 && deferred < 100) {
212+ freed++;
213+ ((Reference)obj).clear();
214+ DisposerRecord rec = (DisposerRecord)records.remove(obj);
215+ if (rec instanceof PollDisposable) {
216+ rec.dispose();
217+ obj = null;
218+ rec = null;
219+ } else {
220+ if (rec == null) { // shouldn't happen, but just in case.
221+ continue;
222+ }
223+ deferred++;
224+ if (deferredRecords == null) {
225+ deferredRecords = new ArrayList<DisposerRecord>(5);
226+ }
227+ deferredRecords.add(rec);
228+ }
229+ }
230+ } catch (Exception e) {
231+ System.out.println("Exception while removing reference: " + e);
232+ e.printStackTrace();
233+ } finally {
234+ pollingQueue = false;
235+ }
236+ }
237+
238+ private static native void initIDs();
239+
240+ /*
241+ * This was added for use by the 2D font implementation to avoid creation
242+ * of an additional disposer thread.
243+ * WARNING: this thread class monitors a specific queue, so a reference
244+ * added here must have been created with this queue. Failure to do
245+ * so will clutter the records hashmap and no one will be cleaning up
246+ * the reference queue.
247+ */
248+ public static void addReference(Reference ref, DisposerRecord rec) {
249+ records.put(ref, rec);
250+ }
251+
252+ public static void addObjectRecord(Object obj, DisposerRecord rec) {
253+ records.put(new WeakReference(obj, queue) , rec);
254+ }
255+
256+ /* This is intended for use in conjunction with addReference(..)
257+ */
258+ public static ReferenceQueue getQueue() {
259+ return queue;
260+ }
261+
262+}