1 /* 2 * Copyright (c) 1996, 2001, 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 package sun.rmi.transport; 26 27 import java.lang.ref.*; 28 import sun.rmi.runtime.Log; 29 30 /** 31 * WeakRef objects are used by the RMI runtime to hold potentially weak 32 * references to exported remote objects in the local object table. 33 * 34 * This class extends the functionality of java.lang.ref.WeakReference in 35 * several ways. The methods pin() and unpin() can be used to set 36 * whether the contained reference is strong or weak (it is weak upon 37 * construction). The hashCode() and equals() methods are overridden so 38 * that WeakRef objects hash and compare to each other according to the 39 * object identity of their referents. 40 * 41 * @author Ann Wollrath 42 * @author Peter Jones 43 */ 44 class WeakRef extends WeakReference<Object> { 45 46 /** value of the referent's "identity" hash code */ 47 private int hashValue; 48 49 /** strong reference to the referent, for when this WeakRef is "pinned" */ 50 private Object strongRef = null; 51 52 /** 53 * Create a new WeakRef to the given object. 54 */ 55 public WeakRef(Object obj) { 56 super(obj); 57 setHashValue(obj); // cache object's "identity" hash code 58 } 59 60 /** 61 * Create a new WeakRef to the given object, registered with a queue. 62 */ 63 public WeakRef(Object obj, ReferenceQueue<Object> q) { 64 super(obj, q); 65 setHashValue(obj); // cache object's "identity" hash code 66 } 67 68 /** 69 * Pin the contained reference (make this a strong reference). 70 */ 71 public synchronized void pin() { 72 if (strongRef == null) { 73 strongRef = get(); 74 75 if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { 76 DGCImpl.dgcLog.log(Log.VERBOSE, 77 "strongRef = " + strongRef); 78 } 79 } 80 } 81 82 /** 83 * Unpin the contained reference (make this a weak reference). 84 */ 85 public synchronized void unpin() { 86 if (strongRef != null) { 87 if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { 88 DGCImpl.dgcLog.log(Log.VERBOSE, 89 "strongRef = " + strongRef); 90 } 91 92 strongRef = null; 93 } 94 } 95 96 /* 97 * Cache referent's "identity" hash code (so that we still have the 98 * value after the referent gets cleared). 99 * 100 * We cannot use the value from the object's hashCode() method, since 101 * if the object is of a remote class not extended from RemoteObject 102 * and it is trying to implement hashCode() and equals() so that it 103 * can be compared to stub objects, its own hash code could not have 104 * been initialized yet (see bugid 4102938). Also, object table keys 105 * based on server objects are indeed matched on object identity, so 106 * this is the correct hash technique regardless. 107 */ 108 private void setHashValue(Object obj) { 109 if (obj != null) { 110 hashValue = System.identityHashCode(obj); 111 } else { 112 hashValue = 0; 113 } 114 } 115 116 /** 117 * Always return the "identity" hash code of the original referent. 118 */ 119 public int hashCode() { 120 return hashValue; 121 } 122 123 /** 124 * Return true if "obj" is this identical WeakRef object, or, if the 125 * contained reference has not been cleared, if "obj" is another WeakRef 126 * object with the identical non-null referent. Otherwise, return false. 127 */ 128 public boolean equals(Object obj) { 129 if (obj instanceof WeakRef) { 130 if (obj == this) 131 return true; 132 133 Object referent = get(); 134 return (referent != null) && (referent == ((WeakRef) obj).get()); 135 } else { 136 return false; 137 } 138 } 139 }