jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-object-private.hh
changeset 34414 e496a8d8fc8a
equal deleted inserted replaced
34413:bbed9966db6e 34414:e496a8d8fc8a
       
     1 /*
       
     2  * Copyright © 2007  Chris Wilson
       
     3  * Copyright © 2009,2010  Red Hat, Inc.
       
     4  * Copyright © 2011,2012  Google, Inc.
       
     5  *
       
     6  *  This is part of HarfBuzz, a text shaping library.
       
     7  *
       
     8  * Permission is hereby granted, without written agreement and without
       
     9  * license or royalty fees, to use, copy, modify, and distribute this
       
    10  * software and its documentation for any purpose, provided that the
       
    11  * above copyright notice and the following two paragraphs appear in
       
    12  * all copies of this software.
       
    13  *
       
    14  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
       
    15  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
       
    16  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
       
    17  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
       
    18  * DAMAGE.
       
    19  *
       
    20  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
       
    21  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
       
    22  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
       
    23  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
       
    24  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
       
    25  *
       
    26  * Contributor(s):
       
    27  *      Chris Wilson <chris@chris-wilson.co.uk>
       
    28  * Red Hat Author(s): Behdad Esfahbod
       
    29  * Google Author(s): Behdad Esfahbod
       
    30  */
       
    31 
       
    32 #ifndef HB_OBJECT_PRIVATE_HH
       
    33 #define HB_OBJECT_PRIVATE_HH
       
    34 
       
    35 #include "hb-private.hh"
       
    36 
       
    37 #include "hb-atomic-private.hh"
       
    38 #include "hb-mutex-private.hh"
       
    39 
       
    40 
       
    41 /* Debug */
       
    42 
       
    43 #ifndef HB_DEBUG_OBJECT
       
    44 #define HB_DEBUG_OBJECT (HB_DEBUG+0)
       
    45 #endif
       
    46 
       
    47 
       
    48 /* reference_count */
       
    49 
       
    50 #define HB_REFERENCE_COUNT_INERT_VALUE -1
       
    51 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
       
    52 #define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
       
    53 
       
    54 struct hb_reference_count_t
       
    55 {
       
    56   hb_atomic_int_t ref_count;
       
    57 
       
    58   inline void init (int v) { ref_count.set_unsafe (v); }
       
    59   inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
       
    60   inline int inc (void) { return ref_count.inc (); }
       
    61   inline int dec (void) { return ref_count.dec (); }
       
    62   inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
       
    63 
       
    64   inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
       
    65   inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
       
    66 };
       
    67 
       
    68 
       
    69 /* user_data */
       
    70 
       
    71 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
       
    72 struct hb_user_data_array_t
       
    73 {
       
    74   struct hb_user_data_item_t {
       
    75     hb_user_data_key_t *key;
       
    76     void *data;
       
    77     hb_destroy_func_t destroy;
       
    78 
       
    79     inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
       
    80     inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
       
    81 
       
    82     void finish (void) { if (destroy) destroy (data); }
       
    83   };
       
    84 
       
    85   hb_mutex_t lock;
       
    86   hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
       
    87 
       
    88   inline void init (void) { lock.init (); items.init (); }
       
    89 
       
    90   HB_INTERNAL bool set (hb_user_data_key_t *key,
       
    91                         void *              data,
       
    92                         hb_destroy_func_t   destroy,
       
    93                         hb_bool_t           replace);
       
    94 
       
    95   HB_INTERNAL void *get (hb_user_data_key_t *key);
       
    96 
       
    97   inline void finish (void) { items.finish (lock); lock.finish (); }
       
    98 };
       
    99 
       
   100 
       
   101 /* object_header */
       
   102 
       
   103 struct hb_object_header_t
       
   104 {
       
   105   hb_reference_count_t ref_count;
       
   106   hb_user_data_array_t user_data;
       
   107 
       
   108 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
       
   109 
       
   110   private:
       
   111   ASSERT_POD ();
       
   112 };
       
   113 
       
   114 
       
   115 /* object */
       
   116 
       
   117 template <typename Type>
       
   118 static inline void hb_object_trace (const Type *obj, const char *function)
       
   119 {
       
   120   DEBUG_MSG (OBJECT, (void *) obj,
       
   121              "%s refcount=%d",
       
   122              function,
       
   123              obj ? obj->header.ref_count.get_unsafe () : 0);
       
   124 }
       
   125 
       
   126 template <typename Type>
       
   127 static inline Type *hb_object_create (void)
       
   128 {
       
   129   Type *obj = (Type *) calloc (1, sizeof (Type));
       
   130 
       
   131   if (unlikely (!obj))
       
   132     return obj;
       
   133 
       
   134   hb_object_init (obj);
       
   135   hb_object_trace (obj, HB_FUNC);
       
   136   return obj;
       
   137 }
       
   138 template <typename Type>
       
   139 static inline void hb_object_init (Type *obj)
       
   140 {
       
   141   obj->header.ref_count.init (1);
       
   142   obj->header.user_data.init ();
       
   143 }
       
   144 template <typename Type>
       
   145 static inline bool hb_object_is_inert (const Type *obj)
       
   146 {
       
   147   return unlikely (obj->header.ref_count.is_inert ());
       
   148 }
       
   149 template <typename Type>
       
   150 static inline bool hb_object_is_valid (const Type *obj)
       
   151 {
       
   152   return likely (obj->header.ref_count.is_valid ());
       
   153 }
       
   154 template <typename Type>
       
   155 static inline Type *hb_object_reference (Type *obj)
       
   156 {
       
   157   hb_object_trace (obj, HB_FUNC);
       
   158   if (unlikely (!obj || hb_object_is_inert (obj)))
       
   159     return obj;
       
   160   assert (hb_object_is_valid (obj));
       
   161   obj->header.ref_count.inc ();
       
   162   return obj;
       
   163 }
       
   164 template <typename Type>
       
   165 static inline bool hb_object_destroy (Type *obj)
       
   166 {
       
   167   hb_object_trace (obj, HB_FUNC);
       
   168   if (unlikely (!obj || hb_object_is_inert (obj)))
       
   169     return false;
       
   170   assert (hb_object_is_valid (obj));
       
   171   if (obj->header.ref_count.dec () != 1)
       
   172     return false;
       
   173 
       
   174   obj->header.ref_count.finish (); /* Do this before user_data */
       
   175   obj->header.user_data.finish ();
       
   176   return true;
       
   177 }
       
   178 template <typename Type>
       
   179 static inline bool hb_object_set_user_data (Type               *obj,
       
   180                                             hb_user_data_key_t *key,
       
   181                                             void *              data,
       
   182                                             hb_destroy_func_t   destroy,
       
   183                                             hb_bool_t           replace)
       
   184 {
       
   185   if (unlikely (!obj || hb_object_is_inert (obj)))
       
   186     return false;
       
   187   assert (hb_object_is_valid (obj));
       
   188   return obj->header.user_data.set (key, data, destroy, replace);
       
   189 }
       
   190 
       
   191 template <typename Type>
       
   192 static inline void *hb_object_get_user_data (Type               *obj,
       
   193                                              hb_user_data_key_t *key)
       
   194 {
       
   195   if (unlikely (!obj || hb_object_is_inert (obj)))
       
   196     return NULL;
       
   197   assert (hb_object_is_valid (obj));
       
   198   return obj->header.user_data.get (key);
       
   199 }
       
   200 
       
   201 
       
   202 #endif /* HB_OBJECT_PRIVATE_HH */