LCOV - code coverage report
Current view: directory - gfx/harfbuzz/src - hb-object-private.hh (source / functions) Found Hit Coverage
Test: app.info Lines: 60 1 1.7 %
Date: 2012-06-02 Functions: 59 1 1.7 %

       1                 : /*
       2                 :  * Copyright © 2007  Chris Wilson
       3                 :  * Copyright © 2009,2010  Red Hat, Inc.
       4                 :  * Copyright © 2011  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-mutex-private.hh"
      38                 : 
      39                 : 
      40                 : 
      41                 : /* Debug */
      42                 : 
      43                 : #ifndef HB_DEBUG_OBJECT
      44                 : #define HB_DEBUG_OBJECT (HB_DEBUG+0)
      45                 : #endif
      46                 : 
      47                 : 
      48                 : /* atomic_int */
      49                 : 
      50                 : /* We need external help for these */
      51                 : 
      52                 : #ifdef HAVE_GLIB
      53                 : 
      54                 : #include <glib.h>
      55                 : 
      56                 : typedef volatile int hb_atomic_int_t;
      57                 : #if GLIB_CHECK_VERSION(2,29,5)
      58                 : #define hb_atomic_int_add(AI, V)        g_atomic_int_add (&(AI), V)
      59                 : #else
      60                 : #define hb_atomic_int_add(AI, V)        g_atomic_int_exchange_and_add (&(AI), V)
      61                 : #endif
      62                 : #define hb_atomic_int_get(AI)           g_atomic_int_get (&(AI))
      63                 : #define hb_atomic_int_set(AI, V)        g_atomic_int_set (&(AI), V)
      64                 : 
      65                 : 
      66                 : #elif defined(_MSC_VER) && _MSC_VER >= 1600
      67                 : 
      68                 : #include <intrin.h>
      69                 : 
      70                 : typedef long hb_atomic_int_t;
      71                 : #define hb_atomic_int_add(AI, V)        _InterlockedExchangeAdd (&(AI), V)
      72                 : #define hb_atomic_int_get(AI)           (_ReadBarrier (), (AI))
      73                 : #define hb_atomic_int_set(AI, V)        ((void) _InterlockedExchange (&(AI), (V)))
      74                 : 
      75                 : 
      76                 : #else
      77                 : 
      78                 : #ifdef _MSC_VER
      79                 : #pragma message("Could not find any system to define atomic_int macros, library will NOT be thread-safe")
      80                 : #else
      81                 : #warning "Could not find any system to define atomic_int macros, library will NOT be thread-safe"
      82                 : #endif
      83                 : 
      84                 : typedef volatile int hb_atomic_int_t;
      85                 : #define hb_atomic_int_add(AI, V)        ((AI) += (V), (AI) - (V))
      86                 : #define hb_atomic_int_get(AI)           (AI)
      87                 : #define hb_atomic_int_set(AI, V)        ((void) ((AI) = (V)))
      88                 : 
      89                 : 
      90                 : #endif
      91                 : 
      92                 : 
      93                 : 
      94                 : 
      95                 : /* reference_count */
      96                 : 
      97                 : typedef struct {
      98                 :   hb_atomic_int_t ref_count;
      99                 : 
     100                 : #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
     101                 : #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
     102                 : 
     103               0 :   inline void init (int v) { ref_count = v; /* non-atomic is fine */ }
     104               0 :   inline int inc (void) { return hb_atomic_int_add (ref_count,  1); }
     105               0 :   inline int dec (void) { return hb_atomic_int_add (ref_count, -1); }
     106                 :   inline void set (int v) { hb_atomic_int_set (ref_count, v); }
     107                 : 
     108               0 :   inline int get (void) const { return hb_atomic_int_get (ref_count); }
     109               0 :   inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
     110                 : 
     111                 : } hb_reference_count_t;
     112                 : 
     113                 : 
     114                 : /* user_data */
     115                 : 
     116            8784 : struct hb_user_data_array_t {
     117                 : 
     118                 :   struct hb_user_data_item_t {
     119                 :     hb_user_data_key_t *key;
     120                 :     void *data;
     121                 :     hb_destroy_func_t destroy;
     122                 : 
     123               0 :     inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
     124               0 :     inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
     125                 : 
     126               0 :     void finish (void) { if (destroy) destroy (data); }
     127                 :   };
     128                 : 
     129                 :   hb_lockable_set_t<hb_user_data_item_t, hb_static_mutex_t> items;
     130                 : 
     131                 :   HB_INTERNAL bool set (hb_user_data_key_t *key,
     132                 :                         void *              data,
     133                 :                         hb_destroy_func_t   destroy,
     134                 :                         hb_bool_t           replace);
     135                 : 
     136                 :   HB_INTERNAL void *get (hb_user_data_key_t *key);
     137                 : 
     138                 :   HB_INTERNAL void finish (void);
     139                 : };
     140                 : 
     141                 : 
     142                 : /* object_header */
     143                 : 
     144                 : typedef struct _hb_object_header_t hb_object_header_t;
     145                 : 
     146                 : struct _hb_object_header_t {
     147                 :   hb_reference_count_t ref_count;
     148                 :   hb_user_data_array_t user_data;
     149                 : 
     150                 : #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID}
     151                 : 
     152               0 :   static inline void *create (unsigned int size) {
     153               0 :     hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
     154                 : 
     155               0 :     if (likely (obj))
     156               0 :       obj->init ();
     157                 : 
     158               0 :     return obj;
     159                 :   }
     160                 : 
     161               0 :   inline void init (void) {
     162               0 :     ref_count.init (1);
     163               0 :   }
     164                 : 
     165               0 :   inline bool is_inert (void) const {
     166               0 :     return unlikely (ref_count.is_invalid ());
     167                 :   }
     168                 : 
     169               0 :   inline void reference (void) {
     170               0 :     if (unlikely (!this || this->is_inert ()))
     171               0 :       return;
     172               0 :     ref_count.inc ();
     173                 :   }
     174                 : 
     175               0 :   inline bool destroy (void) {
     176               0 :     if (unlikely (!this || this->is_inert ()))
     177               0 :       return false;
     178               0 :     if (ref_count.dec () != 1)
     179               0 :       return false;
     180                 : 
     181               0 :     ref_count.init (HB_REFERENCE_COUNT_INVALID_VALUE);
     182                 : 
     183               0 :     user_data.finish ();
     184                 : 
     185               0 :     return true;
     186                 :   }
     187                 : 
     188               0 :   inline bool set_user_data (hb_user_data_key_t *key,
     189                 :                              void *              data,
     190                 :                              hb_destroy_func_t   destroy_func,
     191                 :                              hb_bool_t           replace) {
     192               0 :     if (unlikely (!this || this->is_inert ()))
     193               0 :       return false;
     194                 : 
     195               0 :     return user_data.set (key, data, destroy_func, replace);
     196                 :   }
     197                 : 
     198               0 :   inline void *get_user_data (hb_user_data_key_t *key) {
     199               0 :     return user_data.get (key);
     200                 :   }
     201                 : 
     202               0 :   inline void trace (const char *function) const {
     203                 :     DEBUG_MSG (OBJECT, (void *) this,
     204                 :                "refcount=%d %s",
     205                 :                this ? ref_count.get () : 0,
     206               0 :                function);
     207               0 :   }
     208                 : 
     209                 : };
     210                 : 
     211                 : 
     212                 : 
     213                 : 
     214                 : /* object */
     215                 : 
     216                 : template <typename Type>
     217               0 : static inline void hb_object_trace (const Type *obj, const char *function)
     218                 : {
     219               0 :   obj->header.trace (function);
     220               0 : }
     221                 : template <typename Type>
     222               0 : static inline Type *hb_object_create (void)
     223                 : {
     224               0 :   Type *obj = (Type *) hb_object_header_t::create (sizeof (Type));
     225               0 :   hb_object_trace (obj, HB_FUNC);
     226               0 :   return obj;
     227                 : }
     228                 : template <typename Type>
     229               0 : static inline bool hb_object_is_inert (const Type *obj)
     230                 : {
     231               0 :   return unlikely (obj->header.is_inert ());
     232                 : }
     233                 : template <typename Type>
     234               0 : static inline Type *hb_object_reference (Type *obj)
     235                 : {
     236               0 :   hb_object_trace (obj, HB_FUNC);
     237               0 :   obj->header.reference ();
     238               0 :   return obj;
     239                 : }
     240                 : template <typename Type>
     241               0 : static inline bool hb_object_destroy (Type *obj)
     242                 : {
     243               0 :   hb_object_trace (obj, HB_FUNC);
     244               0 :   return obj->header.destroy ();
     245                 : }
     246                 : template <typename Type>
     247               0 : static inline bool hb_object_set_user_data (Type               *obj,
     248                 :                                             hb_user_data_key_t *key,
     249                 :                                             void *              data,
     250                 :                                             hb_destroy_func_t   destroy,
     251                 :                                             hb_bool_t           replace)
     252                 : {
     253               0 :   return obj->header.set_user_data (key, data, destroy, replace);
     254                 : }
     255                 : 
     256                 : template <typename Type>
     257               0 : static inline void *hb_object_get_user_data (Type               *obj,
     258                 :                                              hb_user_data_key_t *key)
     259                 : {
     260               0 :   return obj->header.get_user_data (key);
     261                 : }
     262                 : 
     263                 : 
     264                 : 
     265                 : 
     266                 : 
     267                 : #endif /* HB_OBJECT_PRIVATE_HH */

Generated by: LCOV version 1.7