Update Copyright headers
[apps/home/video-player.git] / src / hb-object-private.hh
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 HB_BEGIN_DECLS
38
39
40 typedef struct {
41   hb_atomic_int_t ref_count;
42
43 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
44 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
45
46   inline void init (int v) { ref_count = v; /* non-atomic is fine */ }
47   inline int inc (void) { return hb_atomic_int_fetch_and_add (ref_count,  1); }
48   inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); }
49   inline void set (int v) { return hb_atomic_int_set (ref_count, v); }
50
51   inline int get (void) const { return hb_atomic_int_get (ref_count); }
52   inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
53
54 } hb_reference_count_t;
55
56
57
58 /* Debug */
59
60 #ifndef HB_DEBUG_OBJECT
61 #define HB_DEBUG_OBJECT (HB_DEBUG+0)
62 #endif
63
64 static inline void
65 _hb_trace_object (const void *obj,
66                   hb_reference_count_t *ref_count,
67                   const char *function)
68 {
69   (void) (HB_DEBUG_OBJECT &&
70           fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
71                    obj,
72                    ref_count->get (),
73                    function));
74 }
75
76 #define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
77
78
79
80 /* Object allocation and lifecycle manamgement macros */
81
82 #define HB_OBJECT_IS_INERT(obj) \
83     (unlikely ((obj)->ref_count.is_invalid ()))
84
85 #define HB_OBJECT_DO_INIT_EXPR(obj) \
86     obj->ref_count.init (1)
87
88 #define HB_OBJECT_DO_INIT(obj) \
89   HB_STMT_START { \
90     HB_OBJECT_DO_INIT_EXPR (obj); \
91   } HB_STMT_END
92
93 #define HB_OBJECT_DO_CREATE(Type, obj) \
94   likely (( \
95                (void) ( \
96                  ((obj) = (Type *) calloc (1, sizeof (Type))) && \
97                  ( \
98                   HB_OBJECT_DO_INIT_EXPR (obj), \
99                   TRACE_OBJECT (obj), \
100                   TRUE \
101                  ) \
102                ), \
103                (obj) \
104              ))
105
106 #define HB_OBJECT_DO_REFERENCE(obj) \
107   HB_STMT_START { \
108     int old_count; \
109     if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
110       return obj; \
111     TRACE_OBJECT (obj); \
112     old_count = obj->ref_count.inc (); \
113     assert (old_count > 0); \
114     return obj; \
115   } HB_STMT_END
116
117 #define HB_OBJECT_DO_DESTROY(obj) \
118   HB_STMT_START { \
119     int old_count; \
120     if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
121       return; \
122     TRACE_OBJECT (obj); \
123     old_count = obj->ref_count.dec (); \
124     assert (old_count > 0); \
125     if (old_count != 1) \
126       return; \
127   } HB_STMT_END
128
129
130 HB_END_DECLS
131
132 #endif /* HB_OBJECT_PRIVATE_HH */