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 jdk.internal.ref; 27 28 import java.lang.ref.Cleaner; 29 import java.lang.ref.Cleaner.Cleanable; 30 import java.lang.ref.ReferenceQueue; 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 import java.util.concurrent.ThreadFactory; 34 import java.util.concurrent.atomic.AtomicInteger; 35 import java.util.function.Function; 36 37 import jdk.internal.misc.InnocuousThread; 38 39 /** 40 * CleanerImpl manages a set of object references and corresponding cleaning actions. 41 * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}. 42 */ 43 public final class CleanerImpl implements Runnable { 44 45 /** 46 * An object to access the CleanerImpl from a Cleaner; set by Cleaner init. 47 */ 48 private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null; 49 50 /** 51 * Heads of a CleanableList for each reference type. 52 */ 53 final PhantomCleanable<?> phantomCleanableList; 54 55 final WeakCleanable<?> weakCleanableList; 56 57 final SoftCleanable<?> softCleanableList; 167 * @param obj the object to monitor 168 * @param cleaner the cleaner 169 * @param action the action Runnable 170 */ 171 public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) { 172 super(obj, cleaner); 173 this.action = action; 174 } 175 176 /** 177 * Constructor used only for root of phantom cleanable list. 178 */ 179 PhantomCleanableRef() { 180 super(); 181 this.action = null; 182 } 183 184 @Override 185 protected void performCleanup() { 186 action.run(); 187 } 188 189 /** 190 * Prevent access to referent even when it is still alive. 191 * 192 * @throws UnsupportedOperationException always 193 */ 194 @Override 195 public Object get() { 196 throw new UnsupportedOperationException("get"); 197 } 198 199 /** 200 * Direct clearing of the referent is not supported. 201 * 202 * @throws UnsupportedOperationException always 203 */ 204 @Override 205 public void clear() { 206 throw new UnsupportedOperationException("clear"); | 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 jdk.internal.ref; 27 28 import jdk.internal.misc.InnocuousThread; 29 30 import java.lang.ref.Cleaner; 31 import java.lang.ref.Cleaner.Cleanable; 32 import java.lang.ref.ReferenceQueue; 33 import java.security.AccessController; 34 import java.security.PrivilegedAction; 35 import java.util.concurrent.ThreadFactory; 36 import java.util.concurrent.atomic.AtomicInteger; 37 import java.util.function.Consumer; 38 import java.util.function.Function; 39 import java.util.function.LongConsumer; 40 import java.util.function.LongSupplier; 41 import java.util.function.Supplier; 42 43 /** 44 * CleanerImpl manages a set of object references and corresponding cleaning actions. 45 * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}. 46 */ 47 public final class CleanerImpl implements Runnable { 48 49 /** 50 * An object to access the CleanerImpl from a Cleaner; set by Cleaner init. 51 */ 52 private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null; 53 54 /** 55 * Heads of a CleanableList for each reference type. 56 */ 57 final PhantomCleanable<?> phantomCleanableList; 58 59 final WeakCleanable<?> weakCleanableList; 60 61 final SoftCleanable<?> softCleanableList; 171 * @param obj the object to monitor 172 * @param cleaner the cleaner 173 * @param action the action Runnable 174 */ 175 public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) { 176 super(obj, cleaner); 177 this.action = action; 178 } 179 180 /** 181 * Constructor used only for root of phantom cleanable list. 182 */ 183 PhantomCleanableRef() { 184 super(); 185 this.action = null; 186 } 187 188 @Override 189 protected void performCleanup() { 190 action.run(); 191 } 192 193 /** 194 * Prevent access to referent even when it is still alive. 195 * 196 * @throws UnsupportedOperationException always 197 */ 198 @Override 199 public Object get() { 200 throw new UnsupportedOperationException("get"); 201 } 202 203 /** 204 * Direct clearing of the referent is not supported. 205 * 206 * @throws UnsupportedOperationException always 207 */ 208 @Override 209 public void clear() { 210 throw new UnsupportedOperationException("clear"); 211 } 212 } 213 214 /** 215 * Reference-valued resource, automatically cleaned when 216 * the tracked referent becomes phantom-reachable. 217 * 218 * @param <T> the type of resource 219 * @since 10 220 */ 221 public static final class PhantomCleanableResource<T> 222 extends PhantomCleanable<Object> 223 implements Cleaner.CleanableResource<T> { 224 225 private final T resource; 226 private Consumer<? super T> deallocator; 227 228 /** 229 * Constructor for a phantom cleanable resource. 230 * @param obj the object to monitor 231 * @param cleaner the cleaner 232 * @param allocator the resource allocator function 233 * @param deallocator the resource de-allocator function 234 */ 235 public PhantomCleanableResource(Object obj, Cleaner cleaner, 236 Supplier<? extends T> allocator, 237 Consumer<? super T> deallocator) { 238 super(obj, cleaner); 239 try { 240 this.resource = allocator.get(); 241 } catch (Throwable t) { 242 // effectively de-register this cleanable in case 243 // resource allocation fails 244 super.clear(); 245 throw t; 246 } 247 this.deallocator = deallocator; 248 } 249 250 251 @Override 252 protected void performCleanup() { 253 Consumer<? super T> deallocator = this.deallocator; 254 // only when deallocator was assigned, we can be sure that 255 // allocator.get() returned successfully 256 if (deallocator != null) { 257 // mark that cleanup has been performed 258 this.deallocator = null; 259 deallocator.accept(resource); 260 } 261 } 262 263 /** 264 * Access to the allocated resource. 265 * 266 * @return the allocated resource 267 */ 268 @Override 269 public T value() { 270 if (deallocator == null) { 271 throw new IllegalStateException("Already cleaned"); 272 } 273 return resource; 274 } 275 276 /** 277 * Prevent access to referent even when it is still alive. 278 * 279 * @throws UnsupportedOperationException always 280 */ 281 @Override 282 public Object get() { 283 throw new UnsupportedOperationException("get"); 284 } 285 286 /** 287 * Direct clearing of the referent is not supported. 288 * 289 * @throws UnsupportedOperationException always 290 */ 291 @Override 292 public void clear() { 293 throw new UnsupportedOperationException("clear"); 294 } 295 } 296 297 /** 298 * Long-valued resource, automatically cleaned when 299 * the tracked referent becomes phantom-reachable. 300 * 301 * @since 10 302 */ 303 public static final class PhantomLongCleanableResource 304 extends PhantomCleanable<Object> 305 implements Cleaner.LongCleanableResource { 306 307 private final long resource; 308 private LongConsumer deallocator; 309 310 /** 311 * Constructor for a phantom cleanable resource. 312 * @param obj the object to monitor 313 * @param cleaner the cleaner 314 * @param allocator the resource allocator function 315 * @param deallocator the resource de-allocator function 316 */ 317 public PhantomLongCleanableResource(Object obj, Cleaner cleaner, 318 LongSupplier allocator, 319 LongConsumer deallocator) { 320 super(obj, cleaner); 321 try { 322 this.resource = allocator.getAsLong(); 323 } catch (Throwable t) { 324 // effectively de-register this cleanable in case 325 // resource allocation fails 326 super.clear(); 327 throw t; 328 } 329 this.deallocator = deallocator; 330 } 331 332 333 @Override 334 protected void performCleanup() { 335 LongConsumer deallocator = this.deallocator; 336 // only when deallocator was assigned, we can be sure that 337 // allocator.get() returned successfully 338 if (deallocator != null) { 339 // mark that cleanup has been performed 340 this.deallocator = null; 341 deallocator.accept(resource); 342 } 343 } 344 345 /** 346 * Access to the allocated resource. 347 * 348 * @return the allocated resource 349 */ 350 @Override 351 public long value() { 352 if (deallocator == null) { 353 throw new IllegalStateException("Already cleaned"); 354 } 355 return resource; 356 } 357 358 /** 359 * Prevent access to referent even when it is still alive. 360 * 361 * @throws UnsupportedOperationException always 362 */ 363 @Override 364 public Object get() { 365 throw new UnsupportedOperationException("get"); 366 } 367 368 /** 369 * Direct clearing of the referent is not supported. 370 * 371 * @throws UnsupportedOperationException always 372 */ 373 @Override 374 public void clear() { 375 throw new UnsupportedOperationException("clear"); |