/* * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.rmi.transport; import java.lang.ref.*; import sun.rmi.runtime.Log; /** * WeakRef objects are used by the RMI runtime to hold potentially weak * references to exported remote objects in the local object table. * * This class extends the functionality of java.lang.ref.WeakReference in * several ways. The methods pin() and unpin() can be used to set * whether the contained reference is strong or weak (it is weak upon * construction). The hashCode() and equals() methods are overridden so * that WeakRef objects hash and compare to each other according to the * object identity of their referents. * * @author Ann Wollrath * @author Peter Jones */ class WeakRef extends WeakReference { /** value of the referent's "identity" hash code */ private int hashValue; /** strong reference to the referent, for when this WeakRef is "pinned" */ private Object strongRef = null; /** * Create a new WeakRef to the given object. */ public WeakRef(Object obj) { super(obj); setHashValue(obj); // cache object's "identity" hash code } /** * Create a new WeakRef to the given object, registered with a queue. */ public WeakRef(Object obj, ReferenceQueue q) { super(obj, q); setHashValue(obj); // cache object's "identity" hash code } /** * Pin the contained reference (make this a strong reference). */ public synchronized void pin() { if (strongRef == null) { strongRef = get(); if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { DGCImpl.dgcLog.log(Log.VERBOSE, "strongRef = " + strongRef); } } } /** * Unpin the contained reference (make this a weak reference). */ public synchronized void unpin() { if (strongRef != null) { if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { DGCImpl.dgcLog.log(Log.VERBOSE, "strongRef = " + strongRef); } strongRef = null; } } /* * Cache referent's "identity" hash code (so that we still have the * value after the referent gets cleared). * * We cannot use the value from the object's hashCode() method, since * if the object is of a remote class not extended from RemoteObject * and it is trying to implement hashCode() and equals() so that it * can be compared to stub objects, its own hash code could not have * been initialized yet (see bugid 4102938). Also, object table keys * based on server objects are indeed matched on object identity, so * this is the correct hash technique regardless. */ private void setHashValue(Object obj) { if (obj != null) { hashValue = System.identityHashCode(obj); } else { hashValue = 0; } } /** * Always return the "identity" hash code of the original referent. */ public int hashCode() { return hashValue; } /** * Return true if "obj" is this identical WeakRef object, or, if the * contained reference has not been cleared, if "obj" is another WeakRef * object with the identical non-null referent. Otherwise, return false. */ public boolean equals(Object obj) { if (obj instanceof WeakRef) { if (obj == this) return true; Object referent = get(); return (referent != null) && (referent == ((WeakRef) obj).get()); } else { return false; } } }