Link Here
|
1 |
/* |
2 |
* Sun Public License Notice |
3 |
* |
4 |
* The contents of this file are subject to the Sun Public License |
5 |
* Version 1.0 (the "License"). You may not use this file except in |
6 |
* compliance with the License. A copy of the License is available at |
7 |
* http://www.sun.com/ |
8 |
* |
9 |
* The Original Code is NetBeans. The Initial Developer of the Original |
10 |
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun |
11 |
* Microsystems, Inc. All Rights Reserved. |
12 |
*/ |
13 |
|
14 |
package org.netbeans.modules.applemenu; |
15 |
|
16 |
import java.awt.Font; |
17 |
import java.lang.ref.Reference; |
18 |
import java.lang.ref.ReferenceQueue; |
19 |
import java.lang.reflect.Field; |
20 |
|
21 |
// #57664: Random crash on Mac OS X. Apple JDK apparently has a bug in |
22 |
// the native part of the font handling code. Font instances seems to share |
23 |
// native data structures which are released when the instances are finalized. |
24 |
// Because the native data are shared, their premature release causes random |
25 |
// JVM crashes. |
26 |
// |
27 |
// This evil hack forces Font.finalize() not to run. The native font data |
28 |
// are leaked but it's still better than total crash |
29 |
|
30 |
class FontReferenceQueue extends ReferenceQueue { |
31 |
/** |
32 |
* Polls this queue to see if a reference object is available. If one is |
33 |
* available without further delay then it is removed from the queue and |
34 |
* returned. Otherwise this method immediately returns <tt>null</tt>. |
35 |
* |
36 |
* @return A reference object, if one was immediately available, |
37 |
* otherwise <code>null</code> |
38 |
*/ |
39 |
public Reference poll() { |
40 |
Reference ref; |
41 |
|
42 |
for (;;) { |
43 |
ref = super.poll(); |
44 |
if (ref == null) |
45 |
break; |
46 |
|
47 |
Object obj = ref.get(); |
48 |
if (! (obj instanceof Font)) |
49 |
break; |
50 |
} |
51 |
return ref; |
52 |
} |
53 |
|
54 |
/** |
55 |
* Removes the next reference object in this queue, blocking until either |
56 |
* one becomes available or the given timeout period expires. |
57 |
* |
58 |
* <p> This method does not offer real-time guarantees: It schedules the |
59 |
* timeout as if by invoking the {@link Object#wait(long)} method. |
60 |
* |
61 |
* @param timeout If positive, block for up <code>timeout</code> |
62 |
* milliseconds while waiting for a reference to be |
63 |
* added to this queue. If zero, block indefinitely. |
64 |
* |
65 |
* @return A reference object, if one was available within the specified |
66 |
* timeout period, otherwise <code>null</code> |
67 |
* |
68 |
* @throws IllegalArgumentException |
69 |
* If the value of the timeout argument is negative |
70 |
* |
71 |
* @throws InterruptedException |
72 |
* If the timeout wait is interrupted |
73 |
*/ |
74 |
public Reference remove(long timeout) throws IllegalArgumentException, InterruptedException { |
75 |
// timeout is not handled correctly, but good enough for our purposes |
76 |
|
77 |
Reference ref; |
78 |
|
79 |
for (;;) { |
80 |
ref = super.remove(timeout); |
81 |
if (ref == null) |
82 |
break; |
83 |
|
84 |
Object obj = ref.get(); |
85 |
if (! (obj instanceof Font)) |
86 |
break; |
87 |
} |
88 |
return ref; |
89 |
} |
90 |
|
91 |
static void install() { |
92 |
try { |
93 |
Class clzz = Class.forName("java.lang.ref.Finalizer"); // NOI18N |
94 |
Field fld = clzz.getDeclaredField("queue"); // NOI18N |
95 |
fld.setAccessible(true); |
96 |
fld.set(null, new FontReferenceQueue()); |
97 |
} catch (NoClassDefFoundError ex) { |
98 |
// ex.printStackTrace(); |
99 |
} catch (ClassNotFoundException ex) { |
100 |
// ex.printStackTrace(); |
101 |
} catch (Exception ex) { |
102 |
// ex.printStackTrace(); |
103 |
} |
104 |
|
105 |
} |
106 |
} |