gfx/harfbuzz/src/hb-object-private.hh

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/harfbuzz/src/hb-object-private.hh	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,227 @@
     1.4 +/*
     1.5 + * Copyright © 2007  Chris Wilson
     1.6 + * Copyright © 2009,2010  Red Hat, Inc.
     1.7 + * Copyright © 2011,2012  Google, Inc.
     1.8 + *
     1.9 + *  This is part of HarfBuzz, a text shaping library.
    1.10 + *
    1.11 + * Permission is hereby granted, without written agreement and without
    1.12 + * license or royalty fees, to use, copy, modify, and distribute this
    1.13 + * software and its documentation for any purpose, provided that the
    1.14 + * above copyright notice and the following two paragraphs appear in
    1.15 + * all copies of this software.
    1.16 + *
    1.17 + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
    1.18 + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
    1.19 + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
    1.20 + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    1.21 + * DAMAGE.
    1.22 + *
    1.23 + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
    1.24 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    1.25 + * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
    1.26 + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
    1.27 + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
    1.28 + *
    1.29 + * Contributor(s):
    1.30 + *	Chris Wilson <chris@chris-wilson.co.uk>
    1.31 + * Red Hat Author(s): Behdad Esfahbod
    1.32 + * Google Author(s): Behdad Esfahbod
    1.33 + */
    1.34 +
    1.35 +#ifndef HB_OBJECT_PRIVATE_HH
    1.36 +#define HB_OBJECT_PRIVATE_HH
    1.37 +
    1.38 +#include "hb-private.hh"
    1.39 +
    1.40 +#include "hb-atomic-private.hh"
    1.41 +#include "hb-mutex-private.hh"
    1.42 +
    1.43 +
    1.44 +/* Debug */
    1.45 +
    1.46 +#ifndef HB_DEBUG_OBJECT
    1.47 +#define HB_DEBUG_OBJECT (HB_DEBUG+0)
    1.48 +#endif
    1.49 +
    1.50 +
    1.51 +/* reference_count */
    1.52 +
    1.53 +#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
    1.54 +#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
    1.55 +struct hb_reference_count_t
    1.56 +{
    1.57 +  hb_atomic_int_t ref_count;
    1.58 +
    1.59 +  inline void init (int v) { ref_count = v; }
    1.60 +  inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count),  1); }
    1.61 +  inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
    1.62 +  inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
    1.63 +
    1.64 +  inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
    1.65 +
    1.66 +};
    1.67 +
    1.68 +
    1.69 +/* user_data */
    1.70 +
    1.71 +#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
    1.72 +struct hb_user_data_array_t
    1.73 +{
    1.74 +  /* TODO Add tracing. */
    1.75 +
    1.76 +  struct hb_user_data_item_t {
    1.77 +    hb_user_data_key_t *key;
    1.78 +    void *data;
    1.79 +    hb_destroy_func_t destroy;
    1.80 +
    1.81 +    inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
    1.82 +    inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
    1.83 +
    1.84 +    void finish (void) { if (destroy) destroy (data); }
    1.85 +  };
    1.86 +
    1.87 +  hb_mutex_t lock;
    1.88 +  hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
    1.89 +
    1.90 +  inline void init (void) { lock.init (); items.init (); }
    1.91 +
    1.92 +  HB_INTERNAL bool set (hb_user_data_key_t *key,
    1.93 +			void *              data,
    1.94 +			hb_destroy_func_t   destroy,
    1.95 +			hb_bool_t           replace);
    1.96 +
    1.97 +  HB_INTERNAL void *get (hb_user_data_key_t *key);
    1.98 +
    1.99 +  inline void finish (void) { items.finish (lock); lock.finish (); }
   1.100 +};
   1.101 +
   1.102 +
   1.103 +/* object_header */
   1.104 +
   1.105 +struct hb_object_header_t
   1.106 +{
   1.107 +  hb_reference_count_t ref_count;
   1.108 +  hb_user_data_array_t user_data;
   1.109 +
   1.110 +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
   1.111 +
   1.112 +  static inline void *create (unsigned int size) {
   1.113 +    hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
   1.114 +
   1.115 +    if (likely (obj))
   1.116 +      obj->init ();
   1.117 +
   1.118 +    return obj;
   1.119 +  }
   1.120 +
   1.121 +  inline void init (void) {
   1.122 +    ref_count.init (1);
   1.123 +    user_data.init ();
   1.124 +  }
   1.125 +
   1.126 +  inline bool is_inert (void) const {
   1.127 +    return unlikely (ref_count.is_invalid ());
   1.128 +  }
   1.129 +
   1.130 +  inline void reference (void) {
   1.131 +    if (unlikely (!this || this->is_inert ()))
   1.132 +      return;
   1.133 +    ref_count.inc ();
   1.134 +  }
   1.135 +
   1.136 +  inline bool destroy (void) {
   1.137 +    if (unlikely (!this || this->is_inert ()))
   1.138 +      return false;
   1.139 +    if (ref_count.dec () != 1)
   1.140 +      return false;
   1.141 +
   1.142 +    ref_count.finish (); /* Do this before user_data */
   1.143 +    user_data.finish ();
   1.144 +
   1.145 +    return true;
   1.146 +  }
   1.147 +
   1.148 +  inline bool set_user_data (hb_user_data_key_t *key,
   1.149 +			     void *              data,
   1.150 +			     hb_destroy_func_t   destroy_func,
   1.151 +			     hb_bool_t           replace) {
   1.152 +    if (unlikely (!this || this->is_inert ()))
   1.153 +      return false;
   1.154 +
   1.155 +    return user_data.set (key, data, destroy_func, replace);
   1.156 +  }
   1.157 +
   1.158 +  inline void *get_user_data (hb_user_data_key_t *key) {
   1.159 +    if (unlikely (!this || this->is_inert ()))
   1.160 +      return NULL;
   1.161 +
   1.162 +    return user_data.get (key);
   1.163 +  }
   1.164 +
   1.165 +  inline void trace (const char *function) const {
   1.166 +    if (unlikely (!this)) return;
   1.167 +    /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only
   1.168 +     * prints the class name and throws away the template info. */
   1.169 +    DEBUG_MSG (OBJECT, (void *) this,
   1.170 +	       "%s refcount=%d",
   1.171 +	       function,
   1.172 +	       this ? ref_count.ref_count : 0);
   1.173 +  }
   1.174 +
   1.175 +  private:
   1.176 +  ASSERT_POD ();
   1.177 +};
   1.178 +
   1.179 +
   1.180 +/* object */
   1.181 +
   1.182 +template <typename Type>
   1.183 +static inline void hb_object_trace (const Type *obj, const char *function)
   1.184 +{
   1.185 +  obj->header.trace (function);
   1.186 +}
   1.187 +template <typename Type>
   1.188 +static inline Type *hb_object_create (void)
   1.189 +{
   1.190 +  Type *obj = (Type *) hb_object_header_t::create (sizeof (Type));
   1.191 +  hb_object_trace (obj, HB_FUNC);
   1.192 +  return obj;
   1.193 +}
   1.194 +template <typename Type>
   1.195 +static inline bool hb_object_is_inert (const Type *obj)
   1.196 +{
   1.197 +  return unlikely (obj->header.is_inert ());
   1.198 +}
   1.199 +template <typename Type>
   1.200 +static inline Type *hb_object_reference (Type *obj)
   1.201 +{
   1.202 +  hb_object_trace (obj, HB_FUNC);
   1.203 +  obj->header.reference ();
   1.204 +  return obj;
   1.205 +}
   1.206 +template <typename Type>
   1.207 +static inline bool hb_object_destroy (Type *obj)
   1.208 +{
   1.209 +  hb_object_trace (obj, HB_FUNC);
   1.210 +  return obj->header.destroy ();
   1.211 +}
   1.212 +template <typename Type>
   1.213 +static inline bool hb_object_set_user_data (Type               *obj,
   1.214 +					    hb_user_data_key_t *key,
   1.215 +					    void *              data,
   1.216 +					    hb_destroy_func_t   destroy,
   1.217 +					    hb_bool_t           replace)
   1.218 +{
   1.219 +  return obj->header.set_user_data (key, data, destroy, replace);
   1.220 +}
   1.221 +
   1.222 +template <typename Type>
   1.223 +static inline void *hb_object_get_user_data (Type               *obj,
   1.224 +					     hb_user_data_key_t *key)
   1.225 +{
   1.226 +  return obj->header.get_user_data (key);
   1.227 +}
   1.228 +
   1.229 +
   1.230 +#endif /* HB_OBJECT_PRIVATE_HH */

mercurial