1 /*
   2  * Copyright (c) 2016, 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.java2d;
  26 
  27 import java.lang.ref.SoftReference;
  28 import java.lang.ref.WeakReference;
  29 
  30 /**
  31  *
  32  * @param <K>
  33  */
  34 public abstract class ReentrantContextProvider<K extends ReentrantContext>
  35 {
  36     // thread-local storage: inactive
  37     public static final byte USAGE_TL_INACTIVE = 0;
  38     // thread-local storage: in use
  39     public static final byte USAGE_TL_IN_USE = 1;
  40     // CLQ storage
  41     public static final byte USAGE_CLQ = 2;
  42 
  43     // hard reference
  44     public static final int REF_HARD = 0;
  45     // soft reference
  46     public static final int REF_SOFT = 1;
  47     // weak reference
  48     public static final int REF_WEAK = 2;
  49 
  50     /* members */
  51     // internal reference type
  52     protected final ReferenceWrapper<K> refWrapper;
  53 
  54     /**
  55      * Create a new ReentrantContext provider using the given reference type
  56      * among hard, soft or weak
  57      * @param refType reference type
  58      */
  59     protected ReentrantContextProvider(final int refType) {
  60         switch (refType) {
  61             case REF_HARD:
  62                 this.refWrapper = new ReferenceWrapper.HardReferenceWrapper<K>();
  63                 break;
  64             case REF_SOFT:
  65                 this.refWrapper = new ReferenceWrapper.SoftReferenceWrapper<K>();
  66                 break;
  67             default:
  68             case REF_WEAK:
  69                 this.refWrapper = new ReferenceWrapper.WeakReferenceWrapper<K>();
  70                 break;
  71         }
  72     }
  73 
  74     /**
  75      * Return a new ReentrantContext instance
  76      * @return new ReentrantContext instance
  77      */
  78     protected abstract K newContext();
  79 
  80     /**
  81      * Give a ReentrantContext instance for the current thread
  82      * @return ReentrantContext instance
  83      */
  84     public abstract K acquire();
  85 
  86     /**
  87      * Restore the given ReentrantContext instance for reuse
  88      * @param ctx ReentrantContext instance
  89      */
  90     public abstract void release(K ctx);
  91 
  92 
  93     static abstract class ReferenceWrapper<K extends ReentrantContext>
  94     {
  95         abstract K resolveReference(final Object ref);
  96 
  97         abstract Object getOrCreateReference(final K ctx);
  98 
  99 
 100         final static class HardReferenceWrapper<K extends ReentrantContext>
 101                 extends ReferenceWrapper<K>
 102         {
 103             @Override
 104             @SuppressWarnings("unchecked")
 105             K resolveReference(final Object ref) {
 106                 return (K)ref;
 107             }
 108 
 109             @Override
 110             Object getOrCreateReference(final K ctx) {
 111                 return ctx;
 112             }
 113         }
 114 
 115         final static class SoftReferenceWrapper<K extends ReentrantContext>
 116                 extends ReferenceWrapper<K>
 117         {
 118             @Override
 119             @SuppressWarnings("unchecked")
 120             K resolveReference(final Object ref) {
 121                 return (ref != null) ? ((SoftReference<K>) ref).get() : null;
 122             }
 123 
 124             @Override
 125             Object getOrCreateReference(final K ctx) {
 126                 if (ctx.reference == null) {
 127                     // Create the reference:
 128                     ctx.reference = new SoftReference<K>(ctx);
 129                 }
 130                 return ctx.reference;
 131             }
 132         }
 133 
 134         final static class WeakReferenceWrapper<K extends ReentrantContext>
 135                 extends ReferenceWrapper<K>
 136         {
 137             @Override
 138             @SuppressWarnings("unchecked")
 139             K resolveReference(final Object ref) {
 140                 return (ref != null) ? ((WeakReference<K>) ref).get() : null;
 141             }
 142 
 143             @Override
 144             Object getOrCreateReference(final K ctx) {
 145                 if (ctx.reference == null) {
 146                     // Create the reference:
 147                     ctx.reference = new WeakReference<K>(ctx);
 148                 }
 149                 return ctx.reference;
 150             }
 151         }
 152     }
 153 }