LCOV - code coverage report
Current view: top level - gfx/harfbuzz/src - hb-object-private.hh (source / functions) Hit Total Coverage
Test: output.info Lines: 43 57 75.4 %
Date: 2017-07-14 16:53:18 Functions: 57 84 67.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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         154 :   inline void init (int v) { ref_count.set_unsafe (v); }
      59         208 :   inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
      60          52 :   inline int inc (void) { return ref_count.inc (); }
      61          87 :   inline int dec (void) { return ref_count.dec (); }
      62          41 :   inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
      63             : 
      64         908 :   inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
      65         139 :   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           0 :     inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
      80           0 :     inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
      81             : 
      82           0 :     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         154 :   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          41 :   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         217 : static inline void hb_object_trace (const Type *obj, const char *function)
     119             : {
     120         217 :   DEBUG_MSG (OBJECT, (void *) obj,
     121             :              "%s refcount=%d",
     122             :              function,
     123             :              obj ? obj->header.ref_count.get_unsafe () : 0);
     124         217 : }
     125             : 
     126             : template <typename Type>
     127          58 : static inline Type *hb_object_create (void)
     128             : {
     129          58 :   Type *obj = (Type *) calloc (1, sizeof (Type));
     130             : 
     131          58 :   if (unlikely (!obj))
     132           0 :     return obj;
     133             : 
     134          58 :   hb_object_init (obj);
     135          58 :   hb_object_trace (obj, HB_FUNC);
     136          58 :   return obj;
     137             : }
     138             : template <typename Type>
     139         154 : static inline void hb_object_init (Type *obj)
     140             : {
     141         154 :   obj->header.ref_count.init (1);
     142         154 :   obj->header.user_data.init ();
     143         154 : }
     144             : template <typename Type>
     145         908 : static inline bool hb_object_is_inert (const Type *obj)
     146             : {
     147         908 :   return unlikely (obj->header.ref_count.is_inert ());
     148             : }
     149             : template <typename Type>
     150         139 : static inline bool hb_object_is_valid (const Type *obj)
     151             : {
     152         139 :   return likely (obj->header.ref_count.is_valid ());
     153             : }
     154             : template <typename Type>
     155          57 : static inline Type *hb_object_reference (Type *obj)
     156             : {
     157          57 :   hb_object_trace (obj, HB_FUNC);
     158          57 :   if (unlikely (!obj || hb_object_is_inert (obj)))
     159           5 :     return obj;
     160          52 :   assert (hb_object_is_valid (obj));
     161          52 :   obj->header.ref_count.inc ();
     162          52 :   return obj;
     163             : }
     164             : template <typename Type>
     165         102 : static inline bool hb_object_destroy (Type *obj)
     166             : {
     167         102 :   hb_object_trace (obj, HB_FUNC);
     168         102 :   if (unlikely (!obj || hb_object_is_inert (obj)))
     169          15 :     return false;
     170          87 :   assert (hb_object_is_valid (obj));
     171          87 :   if (obj->header.ref_count.dec () != 1)
     172          46 :     return false;
     173             : 
     174          41 :   obj->header.ref_count.finish (); /* Do this before user_data */
     175          41 :   obj->header.user_data.finish ();
     176          41 :   return true;
     177             : }
     178             : template <typename Type>
     179           0 : 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           0 :   if (unlikely (!obj || hb_object_is_inert (obj)))
     186           0 :     return false;
     187           0 :   assert (hb_object_is_valid (obj));
     188           0 :   return obj->header.user_data.set (key, data, destroy, replace);
     189             : }
     190             : 
     191             : template <typename Type>
     192           0 : static inline void *hb_object_get_user_data (Type               *obj,
     193             :                                              hb_user_data_key_t *key)
     194             : {
     195           0 :   if (unlikely (!obj || hb_object_is_inert (obj)))
     196           0 :     return NULL;
     197           0 :   assert (hb_object_is_valid (obj));
     198           0 :   return obj->header.user_data.get (key);
     199             : }
     200             : 
     201             : 
     202             : #endif /* HB_OBJECT_PRIVATE_HH */

Generated by: LCOV version 1.13