2 * Copyright © 2007 Chris Wilson
3 * Copyright © 2009,2010 Red Hat, Inc.
4 * Copyright © 2011 Google, Inc.
6 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
27 * Chris Wilson <chris@chris-wilson.co.uk>
28 * Red Hat Author(s): Behdad Esfahbod
29 * Google Author(s): Behdad Esfahbod
32 #ifndef HB_OBJECT_PRIVATE_HH
33 #define HB_OBJECT_PRIVATE_HH
35 #include "hb-private.hh"
41 hb_atomic_int_t ref_count;
43 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
44 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
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); }
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; }
54 } hb_reference_count_t;
60 #ifndef HB_DEBUG_OBJECT
61 #define HB_DEBUG_OBJECT (HB_DEBUG+0)
65 _hb_trace_object (const void *obj,
66 hb_reference_count_t *ref_count,
69 (void) (HB_DEBUG_OBJECT &&
70 fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
76 #define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
80 /* Object allocation and lifecycle manamgement macros */
82 #define HB_OBJECT_IS_INERT(obj) \
83 (unlikely ((obj)->ref_count.is_invalid ()))
85 #define HB_OBJECT_DO_INIT_EXPR(obj) \
86 obj->ref_count.init (1)
88 #define HB_OBJECT_DO_INIT(obj) \
90 HB_OBJECT_DO_INIT_EXPR (obj); \
93 #define HB_OBJECT_DO_CREATE(Type, obj) \
96 ((obj) = (Type *) calloc (1, sizeof (Type))) && \
98 HB_OBJECT_DO_INIT_EXPR (obj), \
106 #define HB_OBJECT_DO_REFERENCE(obj) \
109 if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
111 TRACE_OBJECT (obj); \
112 old_count = obj->ref_count.inc (); \
113 assert (old_count > 0); \
117 #define HB_OBJECT_DO_DESTROY(obj) \
120 if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
122 TRACE_OBJECT (obj); \
123 old_count = obj->ref_count.dec (); \
124 assert (old_count > 0); \
125 if (old_count != 1) \
132 #endif /* HB_OBJECT_PRIVATE_HH */